You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyPDF2合并PDF时书签页码未正确偏移问题求助

解决PyPDF2合并PDF时书签页码未偏移的问题

使用PyPDF2的append()方法合并PDF文件时,书签会保留原文件的页码指向,不会自动计算合并后的偏移量,导致后续PDF的书签仍指向原文件页码而非合并后的正确位置。要实现书签页码基于总页数偏移,需手动处理每个PDF的书签并调整其目标页码。

修改后的实现代码

import os
import PyPDF2

root_directory = r'E:\ppp\ro'

def adjust_bookmark_pages(bookmarks, page_offset):
    """递归调整书签的页码偏移量(处理嵌套书签)"""
    adjusted_list = []
    for bm in bookmarks:
        # 复制书签属性,调整目标页码
        adjusted_bm = bm.copy()
        adjusted_bm.page = bm.page + page_offset
        # 递归处理子书签
        if bm.children:
            adjusted_bm.children = adjust_bookmark_pages(bm.children, page_offset)
        adjusted_list.append(adjusted_bm)
    return adjusted_list

def add_bookmarks_to_writer(writer, bookmarks):
    """将调整后的书签添加到PDF写入器,处理嵌套结构"""
    def add_child_items(parent_item, child_bookmarks):
        for child in child_bookmarks:
            child_item = writer.add_outline_item(
                child.title, child.page, parent=parent_item,
                bold=child.bold, italic=child.italic, color=child.color
            )
            if child.children:
                add_child_items(child_item, child.children)
    
    for bm in bookmarks:
        parent_item = writer.add_outline_item(
            bm.title, bm.page, parent=None,
            bold=bm.bold, italic=bm.italic, color=bm.color
        )
        if bm.children:
            add_child_items(parent_item, bm.children)

def combine_pdfs(max_pages):
    for dirpath, dirnames, filenames in os.walk(root_directory, topdown=True):
        if 'combined' in dirnames:
            combined_directory = os.path.join(dirpath, 'combined')
            pdf_files = [
                os.path.join(combined_directory, fn) 
                for fn in os.listdir(combined_directory) 
                if fn.endswith('.pdf')
            ]
            pdf_files.sort(reverse=True)

            pdf_index = 0
            while pdf_index < len(pdf_files):
                pdf_writer = PyPDF2.PdfWriter()
                total_pages_added = 0

                while pdf_index < len(pdf_files):
                    pdf_path = pdf_files[pdf_index]
                    print(pdf_path)
                    with open(pdf_path, 'rb') as input_file:
                        pdf_reader = PyPDF2.PdfReader(input_file)
                        current_pdf_pages = len(pdf_reader.pages)
                        
                        if total_pages_added + current_pdf_pages <= max_pages:
                            # 逐个添加当前PDF的所有页面
                            for page in pdf_reader.pages:
                                pdf_writer.add_page(page)
                            
                            # 调整并添加当前PDF的书签
                            if pdf_reader.outline:
                                adjusted_bookmarks = adjust_bookmark_pages(pdf_reader.outline, total_pages_added)
                                add_bookmarks_to_writer(pdf_writer, adjusted_bookmarks)
                            
                            total_pages_added += current_pdf_pages
                            pdf_index += 1
                        else:
                            break

                # 写入合并后的PDF文件
                output_path = os.path.join(combined_directory, 'combinedpdf.pdf')
                with open(output_path, 'wb') as output_file:
                    pdf_writer.write(output_file)
            break

combine_pdfs(max_pages=200)

核心改动说明

  1. 替换append()方法:不再直接调用append()批量添加文件,改为逐个添加页面,以便精准控制书签的页码调整。
  2. 递归调整书签页码:通过adjust_bookmark_pages函数处理所有层级的书签,将每个书签的目标页码加上之前已合并的总页数(偏移量),确保指向合并后的正确位置。
  3. 重新构建书签结构:使用add_bookmarks_to_writer函数将调整后的书签(包括嵌套子书签)重新添加到合并文档中,保留原书签的样式(加粗、斜体、颜色等)。

经过上述修改,合并后的PDF书签会自动计算页码偏移,例如第二个PDF的书签会加上第一个PDF的总页数,得到正确的目标页码。

内容的提问来源于stack exchange,提问作者vampirekabir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 10:13:18