FPDF viết Python

ReportLab là bộ công cụ chính mà tôi sử dụng để tạo tệp PDF từ đầu. Tuy nhiên, tôi đã phát hiện ra rằng có một cái khác gọi là fpdf2. Gói fpdf2 thực sự là một cổng của gói "Miễn phí" -PDF được viết bằng PHP

Ghi chú. PyFPDF hiện đã chết. Bài báo này ban đầu được viết với ý nghĩ về gói đó. Nó đã được thay thế bằng fpdf2

Bài viết này sẽ không đầy đủ trong phạm vi bảo hiểm của gói fpdf2. Tuy nhiên nó sẽ bao gồm quá đủ để bạn bắt đầu sử dụng nó một cách hiệu quả. Lưu ý rằng có một cuốn sách ngắn về PyFPDF có tên "Python thực hiện PDF. pyFPDF" của Edwood Ocasio trên Leanpub nếu bạn muốn tìm hiểu thêm về thư viện ngoài những gì được đề cập trong chương này hoặc tài liệu của gói


Cài đặt

Cài đặt fpdf2 rất dễ dàng vì nó được thiết kế để hoạt động với pip. Đây là cách

pdf = FPDF(orientation='P', unit='mm', format='A4')
8

Bạn sẽ nhận thấy khi bạn cài đặt gói này, gói này không có phần phụ thuộc nào, điều này thật tuyệt

FPDF viết Python
Bạn muốn tìm hiểu thêm về cách làm việc với các tệp PDF trong Python?

Báo cáoPhòng thí nghiệm. Xử lý PDF bằng Python

Mua ngay trên Leanpub


Sử dụng cơ bản

Bây giờ bạn đã cài đặt fpdf2, hãy thử sử dụng nó để tạo một tệp PDF đơn giản. Mở trình soạn thảo Python của bạn và tạo một tệp mới có tên là simple_demo. py. Sau đó nhập đoạn mã sau vào đó

# simple_demo.py

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt="Welcome to Python!", ln=1, align="C")
pdf.output("simple_demo.pdf")

Mục đầu tiên mà chúng ta cần nói đến đó là nhập khẩu. Ở đây chúng tôi nhập lớp FPDF từ gói fpdf. Các giá trị mặc định cho lớp này là tạo PDF ở chế độ Chân dung, sử dụng milimét cho đơn vị đo lường của nó và sử dụng kích thước trang A4. Nếu bạn muốn rõ ràng, bạn có thể viết dòng khởi tạo như thế này

pdf = FPDF(orientation='P', unit='mm', format='A4')

Tôi không phải là người thích sử dụng chữ 'P' để nói cho cả lớp biết hướng của nó. Bạn cũng có thể sử dụng 'L' nếu bạn thích phong cảnh hơn dọc

Gói fpdf2 hỗ trợ 'pt', 'cm' và 'in' làm đơn vị đo lường thay thế

Nếu bạn đi sâu vào nguồn, bạn sẽ thấy rằng gói fpdf2 chỉ hỗ trợ các kích thước trang sau

Đây là một chút hạn chế so với ReportLab, nơi bạn có một số kích thước bổ sung được hỗ trợ ngoài hộp và bạn cũng có thể đặt kích thước trang thành thứ gì đó tùy chỉnh

Dù sao đi nữa, bước tiếp theo là tạo một trang bằng phương thức add_page. Sau đó, chúng tôi đặt phông chữ của trang thông qua phương thức set_font. Bạn sẽ lưu ý rằng chúng tôi chuyển vào họ của phông chữ và kích thước mà chúng tôi muốn. Bạn cũng có thể đặt kiểu phông chữ bằng đối số kiểu. Nếu bạn muốn làm điều này, hãy lưu ý rằng nó cần một chuỗi chẳng hạn như 'B' cho in đậm hoặc 'BI' cho in đậm-nghiêng

Tiếp theo, chúng tôi tạo một ô rộng 200 mm và cao 10 mm. Một ô về cơ bản là một ô có thể lưu chuyển chứa văn bản và có thể kích hoạt đường viền. Nó sẽ tự động phân tách nếu ngắt trang tự động được bật và ô vượt quá giới hạn kích thước của trang. Tham số txt là văn bản mà bạn muốn in trong PDF. Tham số ln yêu cầu PyFPDF thêm dấu ngắt dòng nếu được đặt thành một, đó là những gì chúng tôi làm ở đây. Cuối cùng, chúng ta có thể đặt căn chỉnh của văn bản thành căn lề (mặc định) hoặc căn giữa ('C'). Chúng tôi đã chọn cái sau ở đây

Cuối cùng, chúng tôi lưu tài liệu vào đĩa bằng cách gọi phương thức xuất với đường dẫn đến tệp mà chúng tôi muốn lưu

Khi tôi chạy mã này, tôi đã nhận được một tệp PDF trông như thế này

FPDF viết Python

Bây giờ chúng ta hãy tìm hiểu một chút về cách fpdf2 hoạt động với các phông chữ


Làm việc với phông chữ

fpdf2 có một bộ phông chữ cốt lõi được mã hóa cứng vào lớp FPDF của nó

self.core_fonts={'courier': 'Courier',
    'courierB': 'Courier-Bold',
    'courierBI': 'Courier-BoldOblique',
    'courierI': 'Courier-Oblique',
    'helvetica': 'Helvetica',
    'helveticaB': 'Helvetica-Bold', 
    'helveticaBI': 'Helvetica-BoldOblique',
    'helveticaI': 'Helvetica-Oblique',
    'symbol': 'Symbol',
    'times': 'Times-Roman',
    'timesB': 'Times-Bold',
    'timesBI': 'Times-BoldItalic',
    'timesI': 'Times-Italic',
    'zapfdingbats': 'ZapfDingbats'}

Bạn sẽ lưu ý rằng Arial không được liệt kê ở đây mặc dù chúng tôi đã sử dụng nó trong ví dụ trước. Arial đang được ánh xạ lại vào Helvetica trong mã nguồn thực tế, vì vậy bạn hoàn toàn không sử dụng Arial. Dù sao đi nữa, hãy tìm hiểu cách bạn có thể thay đổi phông chữ bằng fpdf2

# change_fonts.py

from fpdf import FPDF

def change_fonts():
    pdf = FPDF()
    pdf.add_page()
    font_size = 8
    for font in pdf.core_fonts:
        if any([letter for letter in font if letter.isupper()]):
            # skip this font
            continue
        pdf.set_font(font, size=font_size)
        txt = "Font name: {} - {} pts".format(font, font_size)
        pdf.cell(0, 10, txt=txt, ln=1, align="C")
        font_size += 2
    
    pdf.output("change_fonts.pdf")
    
if __name__ == '__main__':
    change_fonts()

Ở đây chúng ta tạo một hàm đơn giản có tên là change_fonts và sau đó chúng ta tạo một thể hiện của lớp FPDF. Bước tiếp theo là tạo một trang và sau đó lặp lại các phông chữ cốt lõi. Khi tôi thử điều đó, tôi phát hiện ra rằng fpdf2 không coi tên biến thể của các phông chữ cốt lõi của nó là phông chữ hợp lệ (tôi. e. helveticaB, helveticaBI, v.v.). Vì vậy, để bỏ qua các biến thể đó, chúng tôi tạo một cách hiểu danh sách và kiểm tra xem có bất kỳ ký tự viết hoa nào trong tên phông chữ không. Nếu có, chúng tôi bỏ qua phông chữ đó. Nếu không, chúng tôi đặt phông chữ và kích thước phông chữ và viết nó ra. Chúng tôi cũng tăng kích thước phông chữ lên hai điểm mỗi lần thông qua vòng lặp. Nếu bạn muốn thay đổi màu của phông chữ, thì bạn có thể gọi set_text_color và chuyển vào giá trị RGB mà bạn yêu cầu

Kết quả của việc chạy mã này trông như thế này

FPDF viết Python

Tôi thích việc thay đổi phông chữ trong fpdf2 dễ dàng như thế nào. Tuy nhiên, số lượng phông chữ cốt lõi khá ít. Bạn có thể thêm phông chữ TrueType, OpenType hoặc Type1 bằng cách sử dụng fpdf2 thông qua phương thức add_font. Phương thức này nhận các đối số sau

  • gia đình (họ phông chữ)
  • phong cách (kiểu phông chữ)
  • fname (tên tệp phông chữ hoặc đường dẫn đầy đủ đến tệp phông chữ)
  • uni (cờ TTF Unicode)

Ví dụ mà tài liệu của fpdf2 sử dụng như sau

pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)

Bạn sẽ gọi add_font trước khi thử sử dụng nó thông qua phương thức set_font. Tôi đã thử điều này trên Windows và gặp lỗi vì Windows không thể tìm thấy phông chữ này, đó là điều tôi mong đợi. Đây là một cách thực sự đơn giản để thêm phông chữ và có thể sẽ hoạt động. Lưu ý rằng nó sử dụng các đường dẫn tìm kiếm sau

  • FPDF_FONTPATH
  • HỆ THỐNG_TTFONTS

Đây dường như là các hằng số được xác định trong môi trường của bạn hoặc trong chính gói PyFPDF. Tài liệu này không giải thích cách chúng được thiết lập hoặc sửa đổi. Thay vào đó, bạn nên sử dụng set_global() với đường dẫn đến phông chữ mà bạn muốn sử dụng

import fpdf

fpdf_mod.set_global("SYSTEM_TTFONTS", os.path.join(os.path.dirname(__file__),'fonts'))

SYSTEM_TTFONTS được đặt thành Không có theo mặc định


Đang vẽ

Gói fpdf2 có hỗ trợ vẽ hạn chế. Bạn có thể vẽ các đường thẳng, hình elip và hình chữ nhật. Trước tiên chúng ta hãy xem cách vẽ các đường thẳng

# draw_lines.py

from fpdf import FPDF

def draw_lines():
    pdf = FPDF()
    pdf.add_page()
    pdf.line(10, 10, 10, 100)
    pdf.set_line_width(1)
    pdf.set_draw_color(255, 0, 0)
    pdf.line(20, 20, 100, 20)
    pdf.output('draw_lines.pdf')
    
if __name__ == '__main__':
    draw_lines()

Ở đây chúng ta gọi phương thức line và truyền cho nó hai cặp tọa độ x/y. Độ rộng của dòng mặc định là 0. 2 mm vì vậy chúng tôi tăng nó lên 1 mm cho dòng thứ hai bằng cách gọi phương thức set_line_width. Chúng tôi cũng đặt màu của dòng thứ hai bằng cách gọi set_draw_color thành giá trị RGB tương đương với màu đỏ. Đầu ra trông như thế này

FPDF viết Python

Bây giờ chúng ta có thể tiếp tục và vẽ một vài hình dạng

________số 8

Khi bạn vẽ một hình dạng như hình elip hoặc hình chữ nhật, bạn sẽ cần nhập tọa độ x và y đại diện cho góc trên bên trái của bản vẽ. Sau đó, bạn sẽ muốn vượt qua chiều rộng và chiều cao của hình dạng. Đối số cuối cùng bạn có thể chuyển vào là kiểu có thể là "D" hoặc một chuỗi trống (mặc định), "F" để điền hoặc "DF" để vẽ và điền. Trong ví dụ này, chúng tôi tô màu cho hình elip và sử dụng giá trị mặc định cho hình chữ nhật. Kết quả cuối cùng trông như thế này

FPDF viết Python

Bây giờ chúng ta hãy tìm hiểu về hỗ trợ hình ảnh


Thêm hình ảnh

Gói fpdf2 hỗ trợ thêm các định dạng JPEG, PNG và GIF vào tệp PDF của bạn. Nếu bạn tình cờ cố gắng sử dụng GIF động, thì chỉ khung hình đầu tiên được sử dụng. Cũng cần lưu ý rằng nếu bạn thêm cùng một hình ảnh nhiều lần vào tài liệu, fpdf2 đủ thông minh để chỉ nhúng một bản sao thực của hình ảnh. Đây là một ví dụ rất đơn giản về việc thêm hình ảnh vào PDF bằng fpdf2

# add_image.py

from fpdf import FPDF

def add_image(image_path):
    pdf = FPDF()
    pdf.add_page()
    pdf.image(image_path, x=10, y=8, w=100)
    pdf.set_font("Arial", size=12)
    pdf.ln(85)  # move 85 down
    pdf.cell(200, 10, txt="{}".format(image_path), ln=1)
    pdf.output("add_image.pdf")
    
if __name__ == '__main__':
    add_image('snakehead.jpg')

Đoạn mã mới ở đây là lệnh gọi phương thức hình ảnh. Chữ ký của nó trông như thế này

# simple_demo.py

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt="Welcome to Python!", ln=1, align="C")
pdf.output("simple_demo.pdf")
0

Bạn chỉ định đường dẫn tệp hình ảnh, tọa độ x và y cũng như chiều rộng và chiều cao. Nếu bạn chỉ chỉ định chiều rộng hoặc chiều cao, chiều rộng hoặc chiều cao khác sẽ được tính toán cho bạn và cố gắng duy trì tỷ lệ ban đầu của hình ảnh. Bạn cũng có thể chỉ định loại tệp một cách rõ ràng, nếu không thì nó được đoán từ tên tệp. Cuối cùng, bạn có thể thêm một liên kết / URL khi thêm hình ảnh

Khi bạn chạy mã này, bạn sẽ thấy một cái gì đó như sau

FPDF viết Python

Bây giờ hãy tìm hiểu cách fpdf2 hỗ trợ thực hiện các tài liệu nhiều trang


Tài liệu nhiều trang

fpdf2 đã bật hỗ trợ nhiều trang theo mặc định. Nếu bạn thêm đủ ô vào một trang, nó sẽ tự động tạo một trang mới và tiếp tục thêm văn bản mới của bạn vào trang tiếp theo. Đây là một ví dụ đơn giản

pdf = FPDF(orientation='P', unit='mm', format='A4')
0

Tất cả điều này làm là tạo ra 100 dòng văn bản. Khi tôi chạy mã này, tôi đã nhận được một tệp PDF chứa 4 trang văn bản


Đầu trang và chân trang

Gói fpdf2 có hỗ trợ tích hợp để thêm đầu trang, chân trang và số trang. Lớp FPDF chỉ cần được phân lớp con và các phương thức đầu trang và chân trang được ghi đè để làm cho chúng hoạt động. chúng ta hãy xem

pdf = FPDF(orientation='P', unit='mm', format='A4')
1

Vì đây là một đoạn mã khá dài, chúng ta hãy xem từng đoạn mã này. Phần đầu tiên mà chúng tôi muốn xem xét là phương thức tiêu đề

pdf = FPDF(orientation='P', unit='mm', format='A4')
2

Ở đây, chúng tôi chỉ mã cứng trong hình ảnh logo mà chúng tôi muốn sử dụng và sau đó chúng tôi đặt phông chữ mà chúng tôi sẽ sử dụng trong tiêu đề của mình. Tiếp theo, chúng tôi thêm một địa chỉ và chúng tôi đặt địa chỉ đó ở bên phải của hình ảnh. Bạn sẽ nhận thấy rằng khi bạn đang sử dụng fpdf2, điểm gốc nằm ở trên cùng bên trái của trang. Vì vậy, nếu chúng ta muốn di chuyển văn bản của mình sang bên phải, thì chúng ta cần tạo một ô có một số đơn vị đo lường. Trong trường hợp này, chúng tôi di chuyển ba dòng tiếp theo sang bên phải bằng cách thêm một ô 100 mm. Sau đó, chúng tôi thêm một dấu ngắt dòng ở cuối, sẽ thêm 20 mm khoảng cách theo chiều dọc

Tiếp theo, chúng tôi muốn ghi đè phương thức footer

pdf = FPDF(orientation='P', unit='mm', format='A4')
3

Điều đầu tiên chúng tôi làm ở đây là đặt vị trí y của gốc trên trang thành -10 mm hoặc -1 cm. Điều này đặt nguồn gốc của chân trang ngay phía trên cuối trang. Sau đó, chúng tôi đặt phông chữ cho chân trang. Cuối cùng, chúng ta tạo văn bản đánh số trang. Bạn sẽ lưu ý tham chiếu đến {nb}. Đây là một giá trị đặc biệt trong fpdf2 được chèn vào khi bạn gọi alias_nb_pages và biểu thị tổng số trang trong tài liệu. Bước cuối cùng trong phần chân trang là viết văn bản trang trên trang và căn giữa nó

Đoạn mã cuối cùng cần xem nằm trong hàm create_pdf

pdf = FPDF(orientation='P', unit='mm', format='A4')
4

Đây là nơi chúng tôi gọi phương thức alias_nb_pages hơi kỳ diệu sẽ giúp chúng tôi lấy tổng số trang. Chúng tôi cũng đặt phông chữ cho phần của trang mà đầu trang hoặc chân trang không hiển thị. Sau đó, chúng tôi viết 50 dòng văn bản vào tài liệu để tạo tài liệu PDF nhiều trang

Khi bạn chạy mã này, bạn sẽ thấy một trang giống như thế này

FPDF viết Python

Bây giờ, hãy tìm hiểu cách bạn có thể tạo bảng với PyFPDF


Những cái bàn

Gói fpdf2 không có điều khiển bảng. Thay vào đó, bạn phải xây dựng các bảng của mình bằng các ô hoặc HTML. Trước tiên, hãy xem cách bạn có thể tạo bảng bằng các ô

pdf = FPDF(orientation='P', unit='mm', format='A4')
5

Ở đây chúng tôi chỉ tạo một danh sách đơn giản gồm các danh sách và sau đó lặp lại nó. Đối với mỗi hàng trong danh sách và mỗi phần tử trong hàng lồng nhau, chúng tôi thêm một ô vào đối tượng PDF của mình. Lưu ý rằng chúng tôi bật đường viền cho các ô này. Khi chúng tôi hoàn thành việc lặp qua một hàng, chúng tôi thêm dấu ngắt dòng. Nếu bạn muốn các ô có nhiều khoảng trống hơn trong các ô, thì bạn có thể chuyển vào một giá trị khoảng cách. Khi tôi chạy tập lệnh này, tôi đã kết thúc với một bảng trông như thế này

FPDF viết Python

Đây là một cách khá thô sơ để tạo bảng mặc dù. Cá nhân tôi thích phương pháp của ReportLab ở đây hơn

Phương pháp thay thế là sử dụng HTML để tạo bảng của bạn

pdf = FPDF(orientation='P', unit='mm', format='A4')
6Tiêu đề 1tiêu đề 2 ô 1 ô 2 ô 2 ô 3

""" pdf. add_page() pdf. write_html(bảng) pdf. đầu ra ('simple_table_html. pdf') nếu __name__ == '__main__'. đơn giản_table_html()

Ở đây, chúng tôi sử dụng lớp HTMLMixin của fpdf2 để cho phép nó chấp nhận HTML làm đầu vào và chuyển đổi nó thành PDF. Khi bạn chạy ví dụ này, bạn sẽ nhận được như sau

FPDF viết Python

Có một số ví dụ trên trang web sử dụng khung Web2Py kết hợp với PyFPDF để tạo các bảng trông đẹp hơn, nhưng mã không đầy đủ nên tôi sẽ không trình bày điều đó ở đây


Chuyển đổi HTML sang PDF

Gói fpdf2 có một số hỗ trợ hạn chế cho các thẻ HTML. Bạn có thể tạo tiêu đề, đoạn văn và kiểu văn bản cơ bản bằng HTML. Bạn cũng có thể thêm siêu liên kết, hình ảnh, danh sách và bảng. Kiểm tra tài liệu để biết danh sách đầy đủ các thẻ và thuộc tính được hỗ trợ. Sau đó, bạn có thể lấy HTML cơ bản và biến nó thành PDF bằng cách sử dụng HTMLMixin mà chúng ta đã thấy trong phần trước khi tạo bảng của mình

pdf = FPDF(orientation='P', unit='mm', format='A4')
7

Đây là văn bản thông thường

Bạn cũng có thể in đậm, in nghiêng hoặc gạch chân ''' pdf = HTML2PDF() pdf. add_page() pdf. ghi_html(html) pdf. đầu ra ('html2pdf. pdf') nếu __name__ == '__main__'. html2pdf()

Ở đây chúng tôi chỉ sử dụng đánh dấu HTML khá chuẩn để thiết kế PDF. Nó thực sự trông khá đẹp khi bạn chạy mã này

FPDF viết Python


Web2Py

Khung Web2Py bao gồm gói fpdf2 để tạo báo cáo trong khung dễ dàng hơn. Điều này cho phép bạn tạo các mẫu PDF trong Web2Py. Tài liệu về chủ đề này hơi khan hiếm, vì vậy tôi sẽ không đề cập đến chủ đề này trong cuốn sách này. Tuy nhiên, có vẻ như bạn có thể thực hiện các báo cáo khá nửa vời bằng cách sử dụng Web2Py theo cách này


mẫu

Bạn cũng có thể tạo mẫu bằng fpdf2. Gói này thậm chí còn bao gồm một tập lệnh thiết kế sử dụng wxPython cho giao diện người dùng của nó. Các mẫu mà bạn có thể tạo sẽ là nơi bạn muốn chỉ định vị trí của từng thành phần trên trang, kiểu của nó (phông chữ, kích thước, v.v.) và văn bản mặc định sẽ sử dụng. Hệ thống tạo khuôn mẫu hỗ trợ sử dụng tệp CSV hoặc cơ sở dữ liệu. Tuy nhiên, chỉ có một ví dụ trong tài liệu về chủ đề này, điều này hơi thất vọng. Mặc dù tôi nghĩ rằng phần này của thư viện hứa hẹn, nhưng do thiếu tài liệu nên tôi không cảm thấy thoải mái khi viết rộng rãi về nó


kết thúc

Gói fpdf2 là một dự án khá hay cho phép bạn tạo tệp PDF cơ bản. Họ chỉ ra trong Câu hỏi thường gặp rằng họ không hỗ trợ biểu đồ hoặc tiện ích con hoặc "hệ thống bố cục trang linh hoạt" như ReportLab. Chúng cũng không hỗ trợ trích xuất hoặc chuyển đổi văn bản PDF như PDFMiner hoặc PyPDF2. Tuy nhiên, nếu tất cả những gì bạn cần là những điều cơ bản để tạo PDF, thì thư viện này có thể phù hợp với bạn. Tôi nghĩ đường cong học tập của nó đơn giản hơn của ReportLab. Tuy nhiên, fpdf2 không có nhiều tính năng như ReportLab và tôi không cảm thấy như bạn có mức độ kiểm soát chi tiết tương tự khi đặt các thành phần trên trang