阅读文本 / Reading text
This paper uses synthetic samples to demonstrate the processing method. The code has been verified using examples in an isolated environment; this does not guarantee effectiveness for all real files or products. Before processing important files, please retain the original copies and verify them against the boundaries and acceptance criteria specified in the text.
Which problem does this paper address first?
When merging, first decide whether to import the original table of contents. If you wish to create the top-level entry yourself, explicitly set import_outline=False to avoid mixing the default import with manual reconstruction. Here, we only demonstrate page numbers and table-of-contents offsets; form-field isolation is not handled.
self-contained synthetic example
dependencies are listed in the import list. The code constructs inputs in memory; runtime logs are provided separately and do not constitute a guarantee for all real-world files.
from io import BytesIO
from pypdf import PdfReader, PdfWriter
def source(pages):
writer = PdfWriter()
for _ in range(pages):
writer.add_blank_page(width=200, height=200)
out = BytesIO()
writer.write(out)
return out.getvalue()
writer = PdfWriter()
for title, raw in [("Part A", source(2)), ("Part B", source(1))]:
start = len(writer.pages)
writer.append(PdfReader(BytesIO(raw)), import_outline=False)
writer.add_outline_item(title, start)
out = BytesIO()
writer.write(out)
reader = PdfReader(BytesIO(out.getvalue()))
assert len(reader.pages) == 3
assert len(reader.outline) == 2
assert reader.get_destination_page_number(reader.outline[0]) == 0
assert reader.get_destination_page_number(reader.outline[1]) == 2
The direct cause of the disappearance of the merged table of contents
uses
PdfWriter.append()
After concatenating multiple PDFs, opening the output file reveals an empty left-hand navigation pane, or clicking on a bookmark jumps to an incorrect page—this is the most common issue in PyPDF’s merging operation. The problem usually does not lie with the “merging” process itself, but rather with the source files’ bookmarks (Outlines), which reference the original document’s page numbers or internal object references. When several documents are merged into a new file, the physical page numbers shift, yet the old bookmark tree fails to automatically update these offsets. An even more subtle scenario occurs when the source files use Named Destinations instead of absolute page numbers, and identical named destinations exist across different source files: the subsequently appended file will overwrite the earlier definitions, causing the links to break.
synthesis example: Input boundary and expected output definition
To verify the robustness of the merging logic, we need to construct a set of controlled synthetic samples rather than relying on real-world files with diverse structures from the production environment. Suppose we have two source files for testing:
error/boundary input scenario
: If the two files are simply appended without any preprocessing, the most likely outcome is that only one “user_name” field will be editable (while the other is obscured or its data is lost), and all bookmarks may point to page ranges in source_a, or an error may occur when clicking the corresponding bookmark in source_b. This kind of silent failure is more dangerous than a program crash, because it compromises the document’s usability without throwing an exception.
Acceptance criteria for the merged results and the boundaries of manual review
code execution success does not guarantee that the deliverable is usable. The table below lists the actual acceptance criteria for merged PDFs, distinguishing between automated checks and scenarios requiring manual intervention. These standards apply to the validation of outputs from any PDF-merging tool.
Special Note:
reset_translation
method is crucial when repeatedly appending the same reader object. If you need to insert different pages of the same PDF into the output multiple times, you must call this method before each insertion; otherwise, the second insertion will use a reference copy of the first, and modifying one will affect the other. This is a detail at the code‑demo level, but during end‑to‑end validation it manifests as “modifying one piece of content unexpectedly changes another,” which can easily be mistaken for a software bug.
References and Next Steps
pypdf Merging PDFs Documentation
pypdf PdfWriter API Reference
The decision on handling the specific exception
observation
What should be done
should not infer
total merged pages
is added to each input and verified against
Failure to deliver in case of discrepancy
Second table of contents
checks the starting offset
cannot still point to the first page
source directory retention policy
explicitly imports
Avoid duplicate table of contents
uses this checklist for document translation
file splitting, encryption, or attachment processing are part of delivery preparation; translation cannot replace these checks. Retain the original documents and the processing checklist, then assess the translated manuscript’s page order, hyperlinks, and content integrity.
OmniDoc (Product Entry)
provides an entry point for translating multi-format documents, and the official website highlights its OCR, terminology database, and bilingual alignment features. For teams that wish to start processing directly from files, this is a path worth evaluating with real-world samples. Please use de-identified files that you are authorized to upload, and verify the results against the checklist provided in this document; we do not claim that OmniDoc utilizes the open-source libraries or internal algorithms referenced herein, nor do we substitute examples for product performance testing.
- 1 -
Updated 2026-10-08