Xử lý PDF “thần tốc” với Python và PyMuPDF: Từ Script đơn giản đến Production

Python tutorial - IT technology blog
Python tutorial - IT technology blog

Xử lý PDF bằng code: Tại sao lại là PyMuPDF?

Xử lý PDF bằng code thường là một cơn ác mộng nếu bạn chọn sai công cụ. Mình từng loay hoay với PyPDF2 và PDFMiner. Kết quả? Khi dự án cần xử lý 5.000 hóa đơn mỗi ngày, hệ thống bắt đầu “hụt hơi” và crash liên tục do ngốn RAM.

Sau 6 tháng vận hành thực tế cho một hệ thống kho bãi, mình khẳng định: PyMuPDF (thư viện fitz) là lựa chọn “out trình” nhất hiện nay. Nhờ viết trên nền C engine của MuPDF, nó nhanh hơn các thư viện thuần Python từ 5 đến 10 lần. Từ đọc, sửa, xóa trang đến vẽ đồ họa, nó cân được hết.

Script của mình ban đầu chỉ 200 dòng, giờ đã lên hơn 2.000 dòng để xử lý đủ loại case oái oăm. Dưới đây là những kinh nghiệm thực chiến nhất mình chắt lọc lại cho bạn.

Cài đặt và đọc nội dung: Xong ngay trong 5 phút

Cài đặt cực kỳ đơn giản qua pip. Có một điểm kỳ lạ: tên package là pymupdf nhưng khi code bạn phải import fitz. Đây là một chút “di sản” lịch sử của thư viện này, cứ dùng thôi đừng thắc mắc nhé.

pip install pymupdf

Thử đoạn code đọc nội dung cơ bản nhất:

import fitz  # Import PyMuPDF

# Mở file chỉ với một dòng lệnh
doc = fitz.open("document.pdf")

# Truy cập trang đầu tiên (index bắt đầu từ 0)
page = doc[0]
text = page.get_text()

print(f"Nội dung trang 1:\n{text}")
doc.close()

Trông mượt đấy chứ? Nhưng thực tế dự án sẽ không bao giờ màu hồng như vậy.

Kỹ thuật thực chiến: Trích xuất và Ghép nối PDF

1. Trích xuất văn bản theo cấu trúc (Blocks)

Sử dụng get_text() thông thường đôi khi khiến chữ nghĩa nhảy loạn xạ do cấu trúc PDF vốn rất phức tạp. Giải pháp của mình là dùng tham số "blocks". Nó giúp bạn lấy dữ liệu theo từng khối văn bản, giữ đúng logic đọc từ trên xuống dưới.

doc = fitz.open("report.pdf")
for page in doc:
    # Trả về list các tuple chứa tọa độ và nội dung
    blocks = page.get_text("blocks")
    for b in blocks:
        print(f"Vị trí: {b[:4]} | Nội dung: {b[4]}")

2. Ghép nhiều file PDF (Merge)

Lúc làm tool gom hóa đơn cuối tháng, mình cực kỳ ưng tính năng insert_pdf. Nó cho phép bạn bốc chính xác từng trang từ file A bỏ vào file B mà không làm mất định dạng hay link đính kèm.

def merge_pdfs(file_list, output_name):
    result = fitz.open()
    for file in file_list:
        with fitz.open(file) as m_file:
            result.insert_pdf(m_file)
    result.save(output_name)
    result.close()

merge_pdfs(["part1.pdf", "part2.pdf"], "final_report.pdf")

Thêm Watermark và Bảo mật chuyên nghiệp

“Em chèn chữ CONFIDENTIAL mờ mờ vào tất cả các trang cho anh”. Nếu sếp yêu cầu thế, đừng lo. Với PyMuPDF, việc này chỉ tốn vài dòng code thay vì ngồi sửa tay hàng tiếng đồng hồ.

def add_watermark(input_pdf, output_pdf, text):
    doc = fitz.open(input_pdf)
    for page in doc:
        # Chèn chữ nghiêng 45 độ tại tọa độ (100, 100)
        page.insert_text((100, 100), text, 
                         fontsize=60, 
                         rotate=45, 
                         color=(0.8, 0.8, 0.8), 
                         fill_opacity=0.3)
    doc.save(output_pdf)
    doc.close()

Muốn chèn logo công ty? Bạn chỉ cần đổi insert_text thành insert_image và xác định vùng tọa độ (Rect) mong muốn.

Bài học xương máu khi chạy Production

Sau nhiều lần “ăn hành” với các file PDF lỗi, đây là những lưu ý bạn cần thuộc lòng:

  • Giải phóng bộ nhớ: Đừng bao giờ quên doc.close(). Khi xử lý hàng nghìn file lớn, không đóng file sẽ khiến RAM server cạn kiệt chỉ trong vài phút. Tốt nhất hãy dùng with fitz.open(...) as doc:.
  • Nén file đầu ra: File PDF sau khi chỉnh sửa thường bị phình to. Hãy dùng doc.save(filename, garbage=4, deflate=True) để loại bỏ rác và nén dữ liệu. Dung lượng có thể giảm tới 30-50%.
  • Xử lý Font lỗi: Nếu trích xuất ra toàn ký tự lạ (ô vuông), đó là do font không được nhúng đúng cách. Lúc này, bạn cần kết hợp OCR (như Tesseract) để quét ảnh thay vì đọc text thuần túy.
  • Hệ tọa độ: Luôn nhớ điểm (0,0) nằm ở góc trên bên trái trang giấy. Muốn chèn gì vào góc dưới bên phải, bạn phải lấy chiều rộng và chiều cao trang trừ đi lề.

Tóm lại, PyMuPDF là một con “quái vật” thực thụ: nhanh, mạnh và cực kỳ ổn định. Nếu bạn đang xây dựng hệ thống tự động hóa tài liệu, hãy bắt đầu với nó ngay hôm nay. Chúc bạn thành công với dự án của mình!

Share: