Python给PDF添加文档附件与附件注释的详细教程

 更新时间:2026年09月05日 08:28:57   作者:用户372157426135  
在处理 PDF 文档时,我们经常需要附带一些补充文件,本文将演示如何使用 Python 实现在PDF中添加文档附件与附件注释,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下

在处理 PDF 文档时,我们经常需要附带一些补充文件。例如,项目报告中需要包含生成图表的原始 Excel 表格,发票中需要附带行程凭证,或者技术文档中需要提供 JSON 配置文件和日志。如果将这些文件单独分发,不仅管理起来比较繁琐,接收方也容易遗漏。

将补充文件直接嵌入 PDF,是解决这一问题的一种常用方式。

在 PDF 中,添加附件主要有两种形式:

  • 文档级附件
  • 附件注释

本文将演示如何使用 Python 实现这两种附件嵌入方式。

两种附件形式的区别与适用场景

在开始编写代码之前,可以先根据附件与正文之间的关系判断应该使用哪一种方式:

1.文档级附件(Document-Level Attachment)

属于整个 PDF 文档,不会改变页面原有的版面。用户使用 PDF 阅读器打开文档时,可以通过“附件”面板查看和导出这些文件。这种方式适用于与整份文档相关的补充材料,如数据表、附录、环境配置文件等。

2.附件注释(Attachment Annotation)

与页面上的特定位置关联,并以可视、可点击的附件图标显示。这种方式适用于与具体正文内容直接相关的材料。例如,在分析图表旁放置对应的数据源,或者在某段内容旁提供相关的原始文件。

选择原则:不需要在页面中体现位置关系的补充文件,可以使用文档级附件;需要与特定段落、图片或图表建立上下文对应关系时,则更适合使用附件注释。

环境设置

要运行下面的代码示例,需要先安装 PDF 处理所需的 Python 模块:

pip install Spire.PDF

然后导入示例中需要使用的类:

from spire.pdf import *
from spire.pdf.common import *

方法一:添加文档级附件

将文件添加为文档级附件时,文件会被加入 PDF 的文档附件集合中,不会修改任何页面内容。

1. 添加单个附件

下例演示如何将 Excel 数据文件嵌入一份 PDF 报告中:

from spire.pdf import *
from spire.pdf.common import *

# 创建 PdfDocument 对象并加载源文档
pdf = PdfDocument()
pdf.LoadFromFile("report.pdf")

# 创建附件对象
attachment = PdfAttachment("source-data.xlsx")

# 将附件添加到文档附件集合中
pdf.Attachments.Add(attachment)

# 保存更新后的 PDF 文档
pdf.SaveToFile("report-with-attachment.pdf")

​PdfAttachment​​ 用于根据外部文件创建附件对象,然后通过 ​​Attachments.Add()​​ 将其加入 PDF 的附件集合。

保存后的 PDF 页面不会发生变化。使用支持 PDF 附件的阅读器打开文件后,可以从附件面板中查看并打开 ​​source-data.xlsx​​。

2. 添加多个附件

如果需要将多个相关文件随 PDF 一起发布,可以分别创建 ​​PdfAttachment​​ 对象并添加到文档中:

# 创建多个附件
attachment1 = PdfAttachment("source-data.xlsx")
attachment2 = PdfAttachment("meeting-notes.docx")
attachment3 = PdfAttachment("architecture.png")

# 添加到文档附件集合
pdf.Attachments.Add(attachment1)
pdf.Attachments.Add(attachment2)
pdf.Attachments.Add(attachment3)

如果附件数量较多,也可以通过列表和循环处理:

attachment_files = [    "source-data.xlsx",    "meeting-notes.docx",    "architecture.png"]

for file in attachment_files:
    pdf.Attachments.Add(PdfAttachment(file))

这样可以把 PDF 和相关资料统一保存在同一个文件中,同时不会改变正文页面原有的布局。

需要注意的是,附件文件会实际写入 PDF,因此附件越大、数量越多,最终生成的 PDF 文件体积也会相应增加。

方法二:在指定页面添加附件注释

当附件需要与页面中的某个具体元素,例如表格、图片、图表或段落对应时,可以使用附件注释。

1. 基本实现代码

创建附件注释时,需要指定它在页面中的位置区域(​​RectangleF​​),并传入需要嵌入的文件数据流(​​Stream​​):

from spire.pdf import *
from spire.pdf.common import *

pdf = PdfDocument()
pdf.LoadFromFile("report.pdf")

# 获取目标页面(这里为第 1 页,索引从 0 开始)
page = pdf.Pages.get_Item(0)

# 读取附件文件
data_stream = Stream("source-data.xlsx")

# 设置图标在页面上的位置和尺寸
# 参数依次为:X 坐标、Y 坐标、宽度、高度
bounds = RectangleF(50.0, 100.0, 16.0, 16.0)

# 创建附件注释
annotation = PdfAttachmentAnnotation(
    bounds,
    "source-data.xlsx",
    data_stream
)

# 设置外观和提示文字
annotation.Color = PdfRGBColor(Color.get_Blue())
annotation.Flags = PdfAnnotationFlags.Default
annotation.Icon = PdfAttachmentIcon.Graph
annotation.Text = "双击打开原始数据表格"

# 将附件注释添加到页面
page.AnnotationsWidget.Add(annotation)

pdf.SaveToFile("report-with-page-attachment.pdf")

这里最关键的是:

bounds = RectangleF(50.0, 100.0, 16.0, 16.0)

四个参数分别表示附件图标的 X 坐标、Y 坐标、宽度和高度。

另外:

page = pdf.Pages.get_Item(0)

获取的是 PDF 的第一页,因为页面索引从 ​​0​​ 开始。如果要把附件添加到其他页面,需要根据实际页码调整索引值。

2. 常见的附件图标样式

​PdfAttachmentIcon​​ 提供了多种附件注释的内置图标样式。

这些枚举值只影响附件图标的显示形式,并不会限制附件实际可以使用的文件类型。

枚举值图标样式
​PdfAttachmentIcon.Graph​图表样式
​PdfAttachmentIcon.Paperclip​回形针样式
​PdfAttachmentIcon.PushPin​图钉样式
​PdfAttachmentIcon.Tag​标签样式

可以根据页面内容和附件用途选择合适的图标。例如:

annotation.Icon = PdfAttachmentIcon.Paperclip

进阶运用:为附件图标配上文字说明

孤零零放一个 16x16 像素的附件小图标,读者可能不知道干嘛用的。我们可以在画布上直接画一行引导文字,再根据文字宽度将附件图标放置在文字后面:

# 1. 在页面 Canvas 上绘制提示文字
label_text = "附件:生成该图表对应的原始数据"
font = PdfTrueTypeFont("Arial", 10.0, PdfFontStyle.Regular, True)

x_pos = 50.0
y_pos = 150.0

page.Canvas.DrawString(
    label_text,
    font,
    PdfBrushes.get_Black(),
    x_pos,
    y_pos
)

# 2. 获取文字实际宽度
text_width = font.MeasureString(label_text).Width

# 3. 将附件图标放在文字右侧 5 点的位置
icon_bounds = RectangleF(
    x_pos + text_width + 5.0,
    y_pos,
    16.0,
    16.0
)

# 4. 创建并添加附件注释
annotation = PdfAttachmentAnnotation(
    icon_bounds,
    "source-data.xlsx",
    data_stream
)

annotation.Icon = PdfAttachmentIcon.Paperclip
page.AnnotationsWidget.Add(annotation)

最终页面上的效果可以理解为:

附件:生成该图表对应的原始数据 📎

这里没有直接写死附件图标的 X 坐标,而是先通过:

font.MeasureString(label_text).Width

获取文字实际占用的宽度,再计算图标的位置。如果提示文字发生变化,图标仍然可以自动保持在文字后方。这种方式比固定坐标更适合动态生成的 PDF 文档。

补充操作:提取 PDF 中的文档级附件

在自动化处理流程中,除了向 PDF 中写入附件,有时还需要读取已经存在的文档级附件,并将它们保存到本地。

from spire.pdf import *
from spire.pdf.common import *

pdf = PdfDocument()
pdf.LoadFromFile("report-with-attachment.pdf")

# 遍历文档级附件
for i in range(pdf.Attachments.Count):
    attachment = pdf.Attachments.get_Item(i)

    # 将附件保存到本地
    with open(attachment.FileName, "wb") as f:
        f.write(attachment.Data)

pdf.Close()

这里访问的 ​​pdf.Attachments​​ 是 PDF 的文档级附件集合

需要注意的是,通过附件注释嵌入的文件属于页面注释,并不包含在这个集合中。如果需要读取页面上的附件注释,则需要进一步遍历相应页面的注释集合。

阅读器兼容性说明

附件成功写入 PDF 后,实际的查看和交互体验还会受到 PDF 阅读器的影响。

  • 桌面端 PDF 阅读器,如 Adobe Acrobat Reader、Foxit PDF Reader 等:一般能够较完整地显示文档级附件面板,并支持页面上的附件注释。
  • 浏览器内置 PDF 查看器,如 Chrome、Edge、Firefox 等:主要用于显示 PDF 页面内容,对附件面板和附件注释等交互功能的支持可能有所不同。有些情况下,用户可能无法像在桌面阅读器中一样直接访问附件。

因此,如果附件属于业务流程中的关键文件,例如财务凭证、合同附件、审计资料或项目交付文件,最好在正式交付前使用接收方实际可能使用的 PDF 阅读器进行测试。

总结

使用 Python 给 PDF 添加附件时,主要需要根据附件与正文内容之间的关系选择合适的方式:

  • 如果文件与整份 PDF 相关,并且不需要在页面中体现具体位置,可以使用 文档级附件
  • 如果文件与正文中的某个图表、图片或段落直接相关,可以使用 附件注释,并将附件图标放在对应内容附近。

两种方式都可以将外部文件直接嵌入 PDF,但在文档结构和阅读方式上各有侧重。实际使用时,只需要判断附件属于整份文档,还是与某个具体页面内容相关,再选择相应的实现方式即可。

到此这篇关于Python给PDF添加文档附件与附件注释的详细教程的文章就介绍到这了,更多相关Python PDF添加附件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现的将文件每一列写入列表功能示例【测试可用】

    Python实现的将文件每一列写入列表功能示例【测试可用】

    这篇文章主要介绍了Python实现的将文件每一列写入列表功能,涉及Python文件读取、遍历、序列追加、赋值等相关操作技巧,需要的朋友可以参考下
    2018-03-03
  • Python如何生成requirements.txt

    Python如何生成requirements.txt

    在 Python 项目中,requirements.txt 文件通常用于列出项目依赖的库及其版本号,本文主要介绍了Python生成requirements.txt的几个常用方法,希望对大家有所帮助
    2025-02-02
  • python利用文件读写编写一个博客

    python利用文件读写编写一个博客

    这篇文章主要为大家详细介绍了python利用文件读写编写一个博客,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • Python实战之异步获取中国天气信息

    Python实战之异步获取中国天气信息

    这篇文章主要介绍了如何利用Python爬虫异步获取天气信息,用的API是中国天气网。文中的示例代码讲解详细,感兴趣的小伙伴可以动手试一试
    2022-03-03
  • Python按天实现生成时间范围序列的方法详解

    Python按天实现生成时间范围序列的方法详解

    有的时候我们希望生成一段时间返回,比如从 2022-01-01 00:00:00 后面的 10 天,这么 10 个 datetime 对象,但是我们又不想自己去计算哪些月有30天哪些月有31天。所以本文将用Python实现按天自动生成时间范围序列,需要的可以参考一下
    2022-11-11
  • python+OpenCV人脸识别考勤系统实现的详细代码

    python+OpenCV人脸识别考勤系统实现的详细代码

    作为一个基于人脸识别算法的考勤系统的设计与实现教程,以下内容将提供详细的步骤和代码示例。本教程将使用 Python 语言和 OpenCV 库进行实现,需要的朋友可以参考下
    2023-05-05
  • 解决python列表list中的截取问题

    解决python列表list中的截取问题

    这篇文章主要介绍了解决python列表list中的截取问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • Python中实现远程调用(RPC、RMI)简单例子

    Python中实现远程调用(RPC、RMI)简单例子

    说白了,远程调用就是将对象名、函数名、参数等传递给远程服务器,服务器将处理结果返回给客户端
    2014-04-04
  • Python 如何求矩阵的逆

    Python 如何求矩阵的逆

    这篇文章主要介绍了Python 如何求矩阵的逆案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Linux下使用python自动修改本机网关代码分享

    Linux下使用python自动修改本机网关代码分享

    这篇文章主要介绍了Linux下使用python自动修改本机网关代码分享,本文直接给出实现代码,需要的朋友可以参考下
    2015-05-05

最新评论