HomeChuyển FilePython-pdfkit Chuyển Đổi Mọi Nội Dung Sang PDF

Python-pdfkit Chuyển Đổi Mọi Nội Dung Sang PDF

Bạn đang có nhu cầu muốn chuyển hóa file text, html, hay một website sang định dạng pdf ? Bạn muốn tìm một thư viện để thực hiện nó với đầy đủ các tính năng trợ giúp như giữ nguyên font chữ, định dạng văn bản, trợ giúp Unicode ? Nội dung dưới đây là sự phối hợp thư viện pdfkit & “enginee” wkhtmltopdf nổi tiếng sẽ khắc phục được hết các yêu cầu của chúng ta.

PDF là gì ?

PDF (Portable Document Format) là định dạng tài liệu di động, tập tin văn bản khá thông dụng của hãng Adobe. PDF trợ giúp các loại font chữ, định dạng, màu sắc,…PDF có một ưu thế vượt trội so với Office Word là một văn bản PDF sẽ được hiển thị giống nhau trên những môi trường làm việc khác nhau, có nghĩa là bạn sẽ không phải lo việc thiếu font chữ khi mở một file pdf trên một máy khác hoặc in ấn mà không bị “vỡ” định dạng.

Cũng chính vì vậy mà càng lúc PDF càng được sử dụng nhiều trong việc trao đổi thông tin trên môi trường mạng internet. Càng lúc càng nhiều nhiều loại giải trình được yêu cầu xuất sang định dạng PDF (thay vì word như trước khi).

Lựa chọn thư viện chuyển hóa dữ liệu sang PDF.

Trong quá trình tìm hiểu việc convert dữ liệu sang pdf, tôi đã tìm hiểu các thư viện html2pdf, xhtml2pdf,…Các thư viện này được cái là để vận dụng vào bài toán convert dữ liệu thì rất nhanh và nhiều ví dụ. Nhưng khi mang vào xử lý dữ liệu tiếng Việt có dấu thì …. kết quả thu được là ô vuông và dấu ?
Loay hoay với bài toán convert dữ liệu unicode/UTF-8 mãi không được, đến lúc chán chán muốn “buông” thì tôi nhớ đến một thư viện mã nguồn mở đã từng dùng hồi còn code .NET là wkhtmltopdf. Đây là một software mã nguồn mở (theo chuẩn LGPLv3), phân phối giao diện command-line để thực hiện convert HTML (hoặc text) sang định dạng PDF, nó trợ giúp được các vấn đề liên quan quan font chữ Unicode và các loại định dạng khác nhau.
Thật tuyệt là có thư viện pdfkit của Python trợ giúp đến “tận răng” cho việc kết phù hợp với wkhtmltopdf.

Các bạn có thể tìm hiểu thêm về thư viện wkhtmltopdf này tại trang chủ: https://wkhtmltopdf.org/ và pypi của pdfkit: https://pypi.org/project/pdfkit.

Thiết lập wkhtmltopdf

Để khởi đầu setup, tất cả chúng ta sẽ đến trang chủ của software để thực hiện download: https://wkhtmltopdf.org/downloads.html, tùy vào hệ điều hành mà tất cả chúng ta sẽ download đúng phiên bản tương ứng. Open-Source này trợ giúp các hệ điều hành: Windows, macOS và hầu như các distro của Linux (Debian, Ubuntu, CentOS,…).

XEM THÊM  TOP 15+ phần mềm Convert to MP3 miễn phí, tốt nhất hiện nay
XEM THÊM  TOP 15+ phần mềm Convert to MP3 miễn phí, tốt nhất hiện nay

Sau khoảng thời gian setup, tất cả chúng ta cần thực hiện thiết lập $PATH (CLASS_PATH nếu là Windows) cho hệ điều hành trỏ đến đúng vị trí file executable của software. Cách thực hiện thiết lập $PATH, các bạn có thể tìm kiếm trên google.
Ví dụ: Tôi đang sử dụng hệ điều hành Windows, tôi setup wkhtmltopdf vào đường dẫn C:Program Fileswkhtmltopdf, tôi sẽ thực hiện set CLASS_PATH cho wkhtmltopdf với đường dẫn: C:Program Fileswkhtmltopdfbin
Sau khoảng thời gian setup & thực hiện thiếp lập $PATH xong, các bạn thực hiện gõ lệnh xác minh xem việc làm của tất cả chúng ta đã thành công hay chưa bằng cách mở màn hình terminal và gõ: wkhtmltopdf –version
Kết quả xuất hiện: wkhtmltopdf 0.12.5 (with patched qt) như vậy là đã thiếp lập thành công.

Thiết lập pdfkit

Pdfkit là một thư viện của Python nên tất cả chúng ta sẽ install nó từ “kho” pypi. Để đảm bảo không tạo “rác” trong PC, các chúng ta nên tạo riêng một virtual environment (tham khảo hướng dẫn Làm Chủ Python Virtual Environment – Môi Trường Lập Trình Ảo ?).

Thực hiện install thư viện bằng dòng lệnh:

pip install pdfkit

Kết quả:
Collecting pdfkit
Downloading https://files.pythonhosted.org/packages/57/da/48fdd627794cde49f4ee7854d219f3a65714069b722b8d0e3599cd066185/pdfkit-0.6.1-py3-none-any.whl
Installing collected packages: pdfkit
Successfully installed pdfkit-0.6.1

Sử dụng pdfkit trong chuyển hóa nội dung

1. Thực hiện convert một đoạn text thuần sang file pdf.

Bài toán: Yêu cầu thực hiện convert các message thu được từ hệ thống thông báo sang file định dạng PDF để thực hiện gửi vào thư điện tử tự động cho lực lượng vận hành.

Để khắc phục yêu cầu bài toán này, tất cả chúng ta sẽ dùng thư viện pdfkit với câu lệnh sau:

import pdfkit

def text2pdf(message, file_name):
    pdfkit.from_string(message, file_name)


if __name__ == "__main__":
    message = "This is a message from codelearn blogger"
    text2pdf(message, "message_en.pdf")

    message = "Đây là thông điệp từ tác giả bài viết trên codelearn"
    text2pdf(message, "message_vi.pdf")

Lưu đoạn code trên vào file 00_text2pdf.py, sau đó thực hiện chạy từ terminal

>python 00_text2pdf.py
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

Ta thu được kết quả:

Chữ tiếng Anh thì hiển thị bình thường nhưng tiếng Việt thì bị lỗi font chữ unicode. Để khắc phục được vấn đề này thì pdfkit cho phép các bạn thực hiện khai báo thêm một số “cấu hình” trước khi thực hiện convert.

def text2pdf(message, file_name):
    options = {'encoding': "UTF-8"}
    pdfkit.from_string(message, file_name, options=options)

Và đây là kết quả:

2. Thực hiện convert một website sang pdf.

Ví dụ: Tất cả chúng ta cùng nhau convert dữ liệu của url https://www.google.com/search?q=codelearn.io
Lưu đoạn source code dưới đây vào file 01_url2pdf.py

import pdfkit
pdfkit.from_url("https://www.google.com/search?q=codelearn.io", "code_learn_google.pdf")

Đứng từ terminal, thực hiện convert dữ liệu:

>python 01_url2pdf.py
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

Tất cả chúng ta thu được file kết quả:

Khá đơn giản đúng không. Nhưng thỉnh thoảng tất cả chúng ta sẽ gặp lỗi liên quan tới việc load dữ liệu trực tiếp từ iframe hoặc responsive của website.

Ví dụ: các bạn thử thay đường dẫn ở trên bằng đường dẫn: https://codelearn.io/sharing/post/quangvinh1986 – danh sách các nội dung của tôi trên codelearn

XEM THÊM  Cách ghép file PDF, gộp và nối nhiều file PDF thành một file duy nhất

pdfkit.from_url("https://codelearn.io/sharing/post/quangvinh1986", "my_codelearn.pdf")

Khi thực hiện convert, tất cả chúng ta sẽ thu được Warning thông báo:

>>> import pdfkit
>>> pdfkit.from_url("https://codelearn.io/sharing/post/quangvinh1986", "my_codelearn.pdf")
Loading pages (1/6)
libpng warning: iCCP: extra compressed data==> ] 74%
Warning: A finished ResourceObject received a loading finished signal. This might be an indication of an iframe taking too long to load.
Warning: A finished ResourceObject received a loading progress signal. This might be an indication of an iframe taking too long to load.
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
True

Và khi mở ra, tất cả chúng ta sẽ thu được giao diện bị khuất một phần dữ liệu:

XEM THÊM  Hướng dẫn chuyển file ảnh sang Word năm 2021

Funny question: Các bạn có thấy vì sao khi thực hiện convert dữ liệu text thì tất cả chúng ta cần thêm đoạn khai báo unicode mà convert cả website thì không cần không?
Câu trả lời sẽ có ở phần bên dưới.

3. Thực hiện convert file dữ liệu html sang file pdf

Yêu cầu: Thực hiện chuyển hóa nội dung file html sang pdf, yêu cầu giữ nguyên được format trên file html như khi hiển thị trên web-browser.

Để thực hiện được phần này, tất cả chúng ta sẽ tạo ra một file html có nội dung như bên dưới và lưu nó lại với tên gọi dùng thử.html

<htmlvàgt;
    <headvàgt;
        <titlevàgt;
            Chuyển đổi mọi nội dung sang pdf bằng pdfkit và wkhtmltopdf 
        </titlevàgt;
        
    </headvàgt;

    <bodyvàgt;
        <pvàgt;This is a message from codelearn bloggervàlt;/pvàgt;
        <pvàgt;Đây là thông điệp từ tác giả nội dung trên codelearnvàlt;/pvàgt;
        <p style="color: red;">Red textvàlt;/pvàgt;
        <p style="color: blue;">Blue textvàlt;/pvàgt;
        <p style="color: green;">Green textvàlt;/pvàgt;
    </bodyvàgt;
</htmlvàgt;

Để đơn giản thì tất cả chúng ta sẽ tạo ra file 03_html2pdf.py chứa code thực hiện convert sẽ đặt “tạm” ở cùng thư mục với dùng thử.html,

import pdfkit

def html2pdf(html_file_name, pdf_file_name):
    pdfkit.from_file(html_file_name, pdf_file_name)


if __name__ == "__main__":
    html2pdf("demo.html", "demo.pdf")

Sau đó, thực hiện khởi chạy file trên từ màn hình terminal

>python 03_html2pdf.py
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

Thu được file kết quả:

Lại một lần nữa font chữ tiếng Việt lại làm phiền tất cả chúng ta. Quay lại thắc mắc phía trên của tôi, vì sao các website mà tất cả chúng ta thực hiện convert lại không bị lỗi font chữ mà cái file html bé tẹo phía trên lại bị lỗi font chữ ?
Câu trả lời nằm ở dữ liệu html tạo ra file html và response content tất cả chúng ta thu được từ các website. Một cái có thẻ <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ /> đặt trong thẻ <headvàgt; và một cái thì không có.

Hiện tại tất cả chúng ta tất cả chúng ta thực hiện thêm đoạn thẻ <metavàgt; trên vào file html và thực hiện chạy lại file convert. Kết quả thu được:

Kết quả thì đã có dữ liệu unicode được hiển thị thành công nhưng tốt nhất là tất cả chúng ta vẫn nên thêm vào các khai báo cấu hình liên quan đến unicode khi thực hiện convert file.

def html2pdf(html_file_name, pdf_file_name):
    options = {'encoding': "UTF-8"}
    pdfkit.from_file(html_file_name, pdf_file_name, options=options)

Ngoài việc trợ giúp UTF-8 encoding, pdfkit còn trợ giúp nhiều loại tham số cấu hình khác nhau. Tất cả chúng ta sẽ tìm hiểu nó trong phần tiếp theo.

Một số lưu ý khi sử dụng pdfkit và wkhtmltopdf

1. Các loại tham số cấu hình mà pdfkit trợ giúp.

Trước tiên là cấu hình giống như khi tất cả chúng ta thực hiện in ấn một văn bản ra máy in văn phòng:

options = {
        'page-size': 'A4',
        'orientation': 'Portrait',
        'quiet': '',
        'dpi': 96,
        'margin-top': '0.2in',
        'margin-bottom': '0.2in',
        'margin-right': '0.72in',
        'margin-left': '0.72in',
        'encoding': "UTF-8"
    }

page-size: Khổ giấy của file pdf sau khoảng thời gian convert. Mặc định là A4, có thể thay đổi thành cách giá trị Letter, A5,…

XEM THÊM  [ePub] Cách làm ePub đơn giản, tối ưu và đúng chuẩn

orientation: Mặc định là khổ giấy xoay dọc (Portrait), có thể thay đổi sang xoay ngang (Landscape)

XEM THÊM  Cách ghép file PDF online, offline đơn giản trong nháy mắt

quiet: Hiển thị log trong quá trình convert sang pdf. Giá trị ưng với các level đặt log (INFO, WARNING,…). Thường đặt ” trên production để tránh lỗi hiển thị terminal.

dpi: Dots Per Inch – Độ đậm nét của ký tự trên file pdf. Mặc định là 96. Tham số này không nên thay đổi. Với Windows, UNIX thì wkhtmltopdf sẽ reset về 96pdi, nếu chuyển qua convert trên máy OSX thì mới có thể tăng số lượng dpi lên được.

margin: Giãn cách từ vị trí các mép tương ứng đến phần dữ liệu trước nhất của nội dung của file. Tùy vào nhu cầu mà tất cả chúng ta thay đổi hoặc giữ nguyên mặc định.

Do pdfkit thực hiện dựa trên thư viện gốc wkhtmltopdf nên các tham số cấu hình của wkhtmltopdf cũng có thể sử dụng với pdfkit (ví dụ: enable/disable css, javascript, …), Các tham số này, các bạn có thể tham khảo thêm từ help của wkhtmltopdf

wkhtmltopdf -H

2. Xử lý trường hợp không có quyền thiết lập $PATH.

Đôi lúc bạn không có quyền thực hiện set $PATH trên hệ thống hoặc hệ thống bị clear mất CLASS_PATH, khi thực hiện chạy các lệnh convert sẽ đẩy ra một trong số các thông báo:

IOError: 'No wkhtmltopdf executable found'
OSError: 'No wkhtmltopdf executable found'

Nếu mà vẫn muốn dùng pdfkit, pdfkit sẽ phân phối một tham số để bạn thực hiện trỏ đường dẫn theo vị trí setup wkhtmltopdf.

Trước tiên thì phải tìm xem đường dẫn theo file chạy wkhtmltopdf trên hệ điều hành (exe trên windows hoặc file class trên UNIX).

Trên Windows thì tất cả chúng ta chỉ cần thực hiện search wkhtmltopdf.exe là ra được file và vị trí file.
Trên UNIX thì tất cả chúng ta dùng command-line: which wkhtmltopdf

Thường thì đường dẫn sẽ lưu ở: /usr/local/bin/wkhtmltopdf

Thực hiện sao chép dữ liệu PATH trên và mang vào cấu hình tham số:

wkhtmltopdf_path = "/usr/local/bin/wkhtmltopdf"
path_config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_path)
pdfkit.from_file(html_file_path, pdf_file_path, options=options, configuration=config)

3. Thực hiện convert nhiều website nội dung vào một file pdf

Thư viện pdfkit cho phép tất cả chúng ta thực hiện “ghép” nội dung nhiều page vào một file pdf duy nhất như ví dụ dưới đây:

import pdfkit

urls = ["https://www.google.com/search?q=codelearn.io", "https://www.google.com/search?q=codelearn.io+%2B+quangvinh1986",
        "https://www.google.com/search?q=codelearn.io+python"]
pdfkit.from_url(urls, "multi_codelearn.pdf")

Khi thực hiện chạy, ta thu được 1 file dữ liệu có nội dung:

Nhìn các chỉ mục ta cũng có thể thấy file pdf phía trên là tổng hợp dữ liệu của 3 url đầu vào.

Các bạn có thể làm tương tự với các function .from_string(), .from_file()

Kết 

Trên đây, tôi đã thực hiện giới thiệu với các bạn về thư viện pdfkit, chúc các bạn có thể chủ động được việc khắc phục các vấn đề với file pdf. Toàn thể source code được lưu trữ tại python-pdfkit.
Cảm ơn các bạn đã đọc nội dung của tôi.

Xem thêm bài viết thuộc chuyên mục: Chuyển File
RELATED ARTICLES

Most Popular

Recent Comments