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

如何用Python或替代方案给PDF添加可跳转URL的书签

实现PDF书签跳转外部URL的两种方案

方案1:修改现有PyPDF2代码,手动替换书签动作

你现用的PdfFileWriter.addBookmark默认生成内部页面跳转的/GoTo类型动作,只需在生成书签后手动修改动作属性为/URI类型即可,修改后的代码如下:

from PyPDF2 import PdfFileReader, PdfFileWriter
from PyPDF2.generic import NameObject, DictionaryObject, TextStringObject

def AddBookmarks(inputPdfPath: str, headers: list) -> str:
    """ 添加书签,支持跳转内部页面或外部URL """
    output = PdfFileWriter()
    outputPdfPath = inputPdfPath.replace(".pdf", "_with_bookmarks.pdf")
    input = PdfFileReader(open(inputPdfPath, 'rb'))

    # 先把所有页面添加到输出对象
    for i in range(input.getNumPages()):
        output.addPage(input.getPage(i))
    
    output.setPageMode("/UseOutlines")
    
    for header in headers:
        page_num = header["Page"] - 1
        # 先创建基础书签,URL类书签可随便填现有页码,实际跳转不会生效
        bookmark = output.addBookmark(header["Title"], page_num, parent=None)
        # 如果配置了Url参数,替换动作为URI跳转
        if "Url" in header and header["Url"]:
            # 构造URI动作对象
            uri_action = DictionaryObject()
            uri_action.update({
                NameObject('/S'): NameObject('/URI'),
                NameObject('/URI'): TextStringObject(header["Url"])
            })
            # 替换书签下的动作属性
            bookmark[NameObject('/A')] = uri_action

    outputStream = open(outputPdfPath,'wb')
    output.write(outputStream)
    outputStream.close()
    return outputPdfPath

# 调用示例
headers = [
    {"Title": "内部跳转章节1", "Page": 3},
    {"Title": "跳转到外部站点", "Page": 1, "Url": "http://www.example.com"}
]
AddBookmarks("test.pdf", headers)

方案2:用PyMuPDF(fitz)实现,语法更简洁

PyMuPDF是处理PDF的常用库,对大纲(书签)的操作支持更原生,不需要手动修改对象属性,兼容性更好:
首先安装依赖:pip install pymupdf

import fitz

def AddBookmarks(inputPdfPath: str, headers: list) -> str:
    outputPdfPath = inputPdfPath.replace(".pdf", "_with_bookmarks.pdf")
    doc = fitz.open(inputPdfPath)
    toc = []
    for header in headers:
        if "Url" in header and header["Url"]:
            # 第一个参数是书签层级,1代表一级书签;第三个参数填0即可不生效
            toc.append([1, header["Title"], 0, {"kind": 2, "uri": header["Url"]}])
        else:
            # 普通内部跳转,第三个参数是页码(从1开始计数)
            toc.append([1, header["Title"], header["Page"]])
    # 写入大纲
    doc.set_toc(toc)
    doc.save(outputPdfPath)
    doc.close()
    return outputPdfPath

注意:部分轻量化PDF阅读器可能不支持外部URL跳转的书签,使用Adobe Acrobat、Chrome/Edge内置PDF阅读器可正常触发跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:42:02