使用 Python 管理 PDF 属性和元数据

PDF 文档属性(也称为元数据)包含作者、标题、主题、关键词等信息,这些信息在文档管理系统中起着关键作用------它们使文档可被搜索、分类和追踪。除了标准属性外,PDF 还支持自定义属性,用于存储业务相关的扩展信息。在实际应用中,批量处理大量 PDF 文档的属性时,手动逐一编辑效率极低且容易出错。通过 Python 编程方式管理这些属性,可以实现属性的批量读取、设置和验证,将文档管理流程自动化。本文将介绍如何使用 Python 设置标准文档属性、读取属性信息、添加自定义属性,以及设置文档过期时间。

为什么以编程方式管理文档属性

与手动操作相比,编程方式具有以下优势:

  • 批量处理:一次性更新数百个 PDF 文档的作者、关键词等属性
  • 数据一致性:通过代码统一定义属性值,避免人工输入的拼写错误和格式不一致
  • 流程集成:将属性管理嵌入到文档生成流水线中,在创建文档时自动写入元数据
  • 自定义扩展:通过自定义属性存储业务信息(如部门、项目编号、密级),实现文档的业务分类管理

环境搭建

本文使用 Spire.PDF for Python,它提供了管理 PDF 文档属性的 API。

bash 复制代码
pip install Spire.PDF

安装完成后,即可在 Python 脚本中导入相关模块开始工作。

设置标准文档属性

PDF 标准属性包括作者(Author)、创建者(Creator)、关键词(Keywords)、生产者(Producer)、主题(Subject)和标题(Title)。以下代码演示了如何加载一个 PDF 文件并设置这些属性:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

inputFile = "Input.pdf"
outputFile = "Properties.pdf"

# 加载 PDF 文档
doc = PdfDocument()
doc.LoadFromFile(inputFile)

# 设置标准文档属性
doc.DocumentInformation.Author = "E-iceblue"
doc.DocumentInformation.Creator = "E-iceblue"
doc.DocumentInformation.Keywords = "pdf, demo, document information"
doc.DocumentInformation.Producer = "Spire.Pdf"
doc.DocumentInformation.Subject = "Demo of Spire.Pdf"
doc.DocumentInformation.Title = "Document Information"

# 设置文件信息
doc.FileInfo.CrossReferenceType = PdfCrossReferenceType.CrossReferenceStream
doc.FileInfo.IncrementalUpdate = False

# 保存文档
doc.SaveToFile(outputFile)
doc.Close()

代码中的关键步骤:

  1. 加载文档LoadFromFile() 方法从文件路径加载 PDF 文档。
  2. DocumentInformation 属性 :通过 doc.DocumentInformation 对象访问和设置各项标准属性,每个属性直接赋值即可。
  3. FileInfo 设置CrossReferenceType 控制交叉引用表的存储格式(Stream 或 Table),IncrementalUpdate 设为 False 表示保存时重写整个文件而非增量更新。

读取文档属性

设置属性后,通常需要读取并验证。以下代码从 PDF 文档中提取所有标准属性并输出:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

inputFile = "Properties.pdf"

doc = PdfDocument()
# 读取 PDF 文件
doc.LoadFromFile(inputFile)

# 获取文档信息对象
docInfo = doc.DocumentInformation

# 逐项读取属性
print("Author: " + docInfo.Author)
print("Creation Date: " + docInfo.CreationDate.strftime("%Y/%m/%d %H:%M:%S"))
print("Keywords: " + docInfo.Keywords)
print("Modify Date: " + docInfo.ModificationDate.strftime("%Y/%m/%d %H:%M:%S"))
print("Subject: " + docInfo.Subject)
print("Title: " + docInfo.Title)

doc.Close()

除了手动设置的属性外,PDF 文档还自动维护两个时间戳:

  • CreationDate:文档创建时间,可通过 strftime() 格式化输出
  • ModificationDate:文档最后修改时间,由 PDF 写入器自动更新

设置自定义文档属性

标准属性覆盖的是 PDF 规范定义的字段。当需要存储业务相关的扩展信息时,可以使用自定义属性。自定义属性以键值对形式存在,键名和值均可自由定义:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

inputFile = "Input.pdf"
outputFile = "CustomDocumentProperties.pdf"

doc = PdfDocument()
# 加载 PDF 文件
doc.LoadFromFile(inputFile)

# 添加自定义文档属性
doc.DocumentInformation.SetCustomProperty("Company", "E-iceblue")
doc.DocumentInformation.SetCustomProperty("Component", "Spire.PDF for .NET")
doc.DocumentInformation.SetCustomProperty("Name", "Daisy")
doc.DocumentInformation.SetCustomProperty("Team", "SalesTeam")

# 保存文件
doc.SaveToFile(outputFile, FileFormat.PDF)
doc.Close()

SetCustomProperty(key, value) 方法接受两个字符串参数:属性名和属性值。自定义属性不会出现在 PDF 阅读器的"文档属性"标准标签页中,但可以通过编程方式读取,适合存储文档管理系统所需的业务元数据。

设置文档过期时间

在某些场景下,文档需要设置有效期,过期后自动提示用户。通过 JavaScript Action 可以实现这一功能:

python 复制代码
from spire.pdf.common import *
from spire.pdf import *

inputFile = "Input.pdf"
outputFile = "SetExpiryDate.pdf"

doc = PdfDocument()
doc.LoadFromFile(inputFile)

# 构建 JavaScript 脚本:检查当前时间是否超过截止时间
javaScript = (
    "var rightNow = new Date();"
    "var endDate = new Date('October 20, 2025 23:59:59');"
    "if(rightNow.getTime() > endDate)"
    "app.alert('This document has expired, please contact us for a new one.', 1);"
    "this.closeDoc();"
)

# 将 JavaScript 设置为文档打开后执行的动作
js = PdfJavaScriptAction(javaScript)
doc.AfterOpenAction = js

# 保存文档
doc.SaveToFile(outputFile)
doc.Close()

AfterOpenAction 属性指定文档打开时自动执行的 JavaScript 动作。上述脚本在打开文档时检查当前时间,若超过截止日期则弹出提示并关闭文档。这种方式适用于发布有时效性限制的文档。

实战技巧

批量更新文档属性

在处理大量文档时,可以将属性设置封装为函数,遍历目录批量处理:

python 复制代码
import os

def update_pdf_properties(file_path, author, title, subject, keywords):
    doc = PdfDocument()
    doc.LoadFromFile(file_path)
    doc.DocumentInformation.Author = author
    doc.DocumentInformation.Title = title
    doc.DocumentInformation.Subject = subject
    doc.DocumentInformation.Keywords = keywords
    doc.FileInfo.IncrementalUpdate = False
    doc.SaveToFile(file_path)
    doc.Close()

# 遍历目录批量更新
directory = "./pdf_files"
for filename in os.listdir(directory):
    if filename.endswith(".pdf"):
        update_pdf_properties(
            os.path.join(directory, filename),
            author="Company Team",
            title="Quarterly Report",
            subject="Finance",
            keywords="report, 2025, quarterly"
        )

属性验证与审计

在文档管理系统中,属性完整性检查是常见需求:

python 复制代码
def validate_pdf_properties(file_path):
    doc = PdfDocument()
    doc.LoadFromFile(file_path)
    info = doc.DocumentInformation
    missing = []
    if not info.Author:
        missing.append("Author")
    if not info.Title:
        missing.append("Title")
    if not info.Keywords:
        missing.append("Keywords")
    doc.Close()
    return missing if missing else "All required properties are set."

通过检查属性是否为空,可以快速筛选出元数据不完整的文档,确保归档前所有必要信息已填写。

总结

本文介绍了使用 Python 管理 PDF 文档属性和元数据的完整流程,涵盖标准属性设置、属性读取、自定义属性添加和文档过期时间设置四个核心操作。

关键要点回顾:

  1. 通过 doc.DocumentInformation 对象设置和读取标准属性(Author、Title、Subject、Keywords 等)
  2. 使用 SetCustomProperty(key, value) 方法添加业务相关的自定义属性
  3. CreationDateModificationDate 由系统自动维护,可通过 strftime() 格式化输出
  4. 通过 PdfJavaScriptActionAfterOpenAction 实现文档过期时间控制

掌握这些技能后,你可以将属性管理集成到文档处理流水线中,实现 PDF 文档元数据的批量设置、验证和审计,提升文档管理的规范性和效率。

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
默_笙1 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
qq_426003961 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
胡写代码1 天前
别再前后端各写一套表单校验了
java·后端
长沙三为智能科技1 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
大勇前进1 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端