𝗦𝘁𝗼𝗽 𝗣𝗮𝗿𝘀𝗶𝗻𝗴 𝗣𝗗𝗙𝘀 𝗮𝘁 𝗥𝗲𝗻𝗱𝗲𝗿 𝗧𝗶𝗺𝗲

Most developers build PDF extraction tools the wrong way.

They try to guess document structure from the visual output. They render a page to a canvas and look at pixel positions. They use computer vision to find columns or tables.

This approach is backwards.

A PDF already contains the structure you need in the operator stream.

A table is not just a set of pixels. It is a set of path operators like moveTo, lineTo, and rectangle. Zone boundaries are encoded in the CTM stack. You do not need to reconstruct what is already there.

Stop using visual heuristics. Use the source data.

I previously tried using De Casteljau subdivision for bounding boxes. I rejected it during testing.

De Casteljau is a subdivision algorithm. You split curves until the segments are small enough. This works for rendering, but it is bad for bounding boxes.

You have to choose a tolerance. If the tolerance is too loose, the box is wrong. If it is too tight, you waste resources on recursion. There is a better way. An analytical solution using the quadratic formula is exact. It does not recurse. It does not allocate segments.

The same logic applies to zone detection.

Many tools calculate zone boundaries by finding the midpoint between two text groups. This is a visual guess. It is not structural.

If you use midpoints, sub-pixel rounding will place regions in the wrong zones.

The fix is simple. Use the top edge of the bounding box. A region belongs to a zone based on where it starts. Use the actual Y-coordinate of the top edge.

Building a real PDF extractor is harder. You must:

This is more work than pixel-based guessing. But it produces deterministic results.

A pixel-based tool gives different results at 100% zoom than it does at 150% zoom. It is pattern-matching visual artifacts, not extracting structure.

If you do not parse the operator stream, you are building a demo. It might work on your test files, but it will fail on real user uploads.

The path through the operator stream is difficult. You must understand the fill and stroke state machines and the PDF specification. But you only have to learn it once. Then it works for every PDF.

Ngừng phân tích PDF tại thời điểm render: Một kiến trúc tốt hơn để trích xuất dữ liệu có cấu trúc

Nếu bạn từng xây dựng một ứng dụng xử lý các tệp PDF, bạn có lẽ đã gặp phải các vấn đề về hiệu suất. Một sai lầm phổ biến là thực hiện việc phân tích (parsing) PDF ngay tại thời điểm render (render-time).

Vấn đề: Cạm bẫy tại thời điểm render

Khi bạn phân tích một tệp PDF tại thời điểm render, quy trình thường diễn ra như sau:

  1. Người dùng yêu cầu dữ liệu.
  2. Ứng dụng tải tệp PDF từ bộ lưu trữ.
  3. Ứng dụng phân tích PDF (có thể sử dụng OCR hoặc LLM).
  4. Ứng dụng trả về dữ liệu có cấu trúc cho người dùng.

Vấn đề là việc phân tích PDF cực kỳ tốn tài nguyên tính toán (compute-intensive). Nó chậm và không thể dự đoán được. Điều này dẫn đến độ trễ (latency) cao, làm hỏng trải nghiệm người dùng. Nếu nhiều người dùng cùng yêu cầu phân tích một lúc, hệ thống của bạn có thể dễ dàng bị quá tải.

Giải pháp: Tách biệt các thành phần (Decoupling)

Thay vì phân tích PDF khi bạn cần hiển thị chúng, hãy chuyển sang một kiến trúc bất đồng bộ (asynchronous) và hướng sự kiện (event-driven).

Một kiến trúc tốt hơn

Quy trình nên được chia thành hai giai đoạn riêng biệt:

1. Xử lý nền (Background Processing)

Khi một tệp PDF mới được tải lên, một sự kiện (event) sẽ được kích hoạt. Một worker chạy ngầm sẽ nhận sự kiện này và bắt đầu quá trình phân tích. Sau khi hoàn tất, dữ liệu có cấu trúc sẽ được lưu vào cơ sở dữ liệu.

2. Truy vấn (Querying)

Khi người dùng yêu cầu dữ liệu, ứng dụng chỉ đơn giản là truy vấn cơ sở dữ liệu để lấy dữ liệu đã được cấu trúc hóa. Việc này diễn ra cực kỳ nhanh chóng vì không có quá trình phân tích nặng nề nào diễn ra trong lúc thực hiện yêu cầu.

Lợi ích