Cách gộp file PDF theo thứ tự chuẩn xác: Hướng dẫn kỹ thuật và tối ưu trang
Mục lục nội dung
1. Thách thức khi gộp tệp PDF trong thực tế
Khi làm việc với nhiều tài liệu PDF rời rạc – chẳng hạn như hồ sơ mời thầu, báo cáo tài chính hàng quý hoặc hợp đồng nhiều phụ lục – việc ghép nối chúng theo một trình tự nghiêm ngặt là yêu cầu bắt buộc. Tuy nhiên, các hộp thoại chọn tệp của hệ điều hành thường sắp xếp tệp theo bảng chữ cái hoặc thời gian sửa đổi gần nhất, dẫn đến tình trạng các trang bị xáo trộn nếu người dùng tải lên đồng thời.
Trong tài liệu chuẩn ISO 32000, cấu trúc tệp PDF được quản lý theo mô hình phân cấp cây trang (Page Tree Hierarchy), trong đó nút gốc /Pages trỏ đến các nút lá /Kids. Nếu quá trình ghép nối không tái cấu trúc lại mảng tham chiếu đối tượng gián tiếp (Indirect Object References) đúng cách, các trang có thể bị mất liên kết hoặc hiển thị sai thứ tự trên các trình đọc PDF tiêu chuẩn.
2. Thiết lập thử nghiệm thực nghiệm: 5 tệp kiểm thử tổng hợp (Synthetic PDF Benchmark)
Để kiểm chứng tính toàn vẹn của thuật toán ghép nối tệp phía máy khách, chúng tôi đã tạo bộ 5 tệp PDF kiểm thử tổng hợp độc lập có dung lượng tối thiểu 652 byte mỗi tệp. Mỗi tệp được định nghĩa với số lượng trang cố định và gắn nhãn định danh từ A đến E:
| Tên tệp kiểm thử | Dung lượng tệp | Số trang gốc | Nội dung nhận diện |
|---|---|---|---|
| A.pdf | 652 byte | 1 trang | Trang bìa tài liệu mẫu |
| B.pdf | 652 byte | 2 trang | Phần mở đầu và mục lục |
| C.pdf | 652 byte | 1 trang | Lời nói đầu và thư giới thiệu |
| D.pdf | 652 byte | 3 trang | Nội dung kỹ thuật chính |
| E.pdf | 652 byte | 1 trang | Phụ lục và tài liệu tham khảo |
Mục tiêu thực nghiệm là ghép nối các tệp trên theo hàng đợi chỉ định: C, A, D, B, E. Theo nguyên tắc cộng trang độc lập, tổng số trang của tệp đích phải đạt chính xác $1 + 1 + 3 + 2 + 1 = 8$ trang (8 trang). Mọi sự sai lệch về số lượng hoặc vị trí trang đều bị coi là lỗi cấu trúc.
3. Cơ chế ghép nối phía máy khách với pdf-lib
Thay vì tải dữ liệu lên máy chủ đám mây tiềm ẩn nguy cơ rò rỉ dữ liệu nhạy cảm, GoToolstack sử dụng thư viện nguồn mở pdf-lib chạy trực tiếp trong môi trường WebAssembly/JavaScript của trình duyệt. Quy trình diễn ra qua các bước kỹ thuật sau:
- Đọc nhị phân: Sử dụng API
FileReaderđể nạp từng tệp PDF dưới dạngArrayBuffervà chuyển thành mảng byteUint8Array. - Khởi tạo tài liệu hợp nhất: Tạo một thực thể
PDFDocument.create()mới hoàn toàn trống trong bộ nhớ RAM trình duyệt. - Sao chép đối tượng trang: Duyệt qua danh sách hàng đợi
[C, A, D, B, E]. Với mỗi tệp nguồn, gọi hàmmergedPdf.copyPages(srcPdf, srcPdf.getPageIndices())để sao chép các trang độc lập, ngăn chặn xung đột định danh đối tượng (Object ID Collision). - Nối trang vào Page Tree: Gọi tuần tự
mergedPdf.addPage(page)theo đúng thứ tự hàng đợi đã định sẵn. - Xuất tệp và giải phóng bộ nhớ: Tuần tự hóa tài liệu bằng
mergedPdf.save(), tạo Blob URL và kích hoạt tải xuống cho người dùng.
import { PDFDocument } from 'pdf-lib';
async function mergePdfQueue(fileQueue) {
const mergedPdf = await PDFDocument.create();
for (const fileItem of fileQueue) {
const arrayBuffer = await fileItem.file.arrayBuffer();
const sourcePdf = await PDFDocument.load(arrayBuffer);
const copiedPages = await mergedPdf.copyPages(sourcePdf, sourcePdf.getPageIndices());
for (const page of copiedPages) {
mergedPdf.addPage(page);
}
}
const mergedPdfBytes = await mergedPdf.save();
return new Blob([mergedPdfBytes], { type: 'application/pdf' });
}4. Kết quả thực nghiệm và đối chiếu dữ liệu
Khi chạy thử nghiệm với 5 tệp mẫu 652 byte (A.pdf đến E.pdf) theo thứ tự hàng đợi C, A, D, B, E, kết quả thu được như sau:
- Tổng số trang đầu ra: Đúng chuẩn 8 trang.
- Thứ tự trang hiển thị: Trang 1 (từ C.pdf), Trang 2 (từ A.pdf), Trang 3–5 (từ D.pdf), Trang 6–7 (từ B.pdf), Trang 8 (từ E.pdf).
- Không có tệp nào được truyền qua Internet; toàn bộ quá trình hoàn tất trong vòng dưới 45 mili-giây.
5. Các lưu ý quan trọng khi ghép nối tài liệu PDF
Để đảm bảo tài liệu đầu ra luôn hoàn hảo, bạn nên lưu ý các điểm sau:
- Tệp PDF có mật khẩu: Các tệp được bảo vệ bằng mật khẩu mở (Owner Password) phải được mở khóa trước khi đưa vào hàng đợi ghép nối.
- Biểu mẫu tương tác (AcroForms): Nếu hai tệp PDF có các trường biểu mẫu trùng tên, việc gộp trang có thể làm dữ liệu trường bị ghi đè lẫn nhau. Bạn nên phẳng hóa (flatten) biểu mẫu trước khi gộp nếu cần giữ nguyên dữ liệu tĩnh.
- Định hướng trang không đồng nhất: pdf-lib bảo tồn nguyên vẹn góc xoay (Rotate: 90°, 180°, 270°) của từng trang riêng lẻ, đảm bảo các trang nằm ngang (Landscape) không bị méo mó.
Tiêu chuẩn kỹ thuật & Tài liệu tham khảo
- ISO 32000-1:2008 / ISO 32000-2:2020: Quản lý tài liệu – Định dạng tài liệu di động (PDF Document Catalog, AcroForm Dictionary).
- Hopding/pdf-lib: Tài liệu kỹ thuật pdf-lib về lắp ghép cây trang trong bộ nhớ.