向PDF添加元数据
无论是《Django Crash Course》还是即将推出的《Two Scoops of Django 3.x》,我们都采用了新的PDF渲染流程。遗憾的是,直到几天前,该流程还不包含封面。封面需要使用Adobe Acrobat手动插入。
虽然这种手动操作方法有效,但其后果也是可以预见的。
合并PDF文件
这部分很简单,在很多博客文章和 Stack Overflow 的回答中都能找到答案。
- 步骤 1:安装pypdf2
- 步骤二:编写如下所示的脚本
from PyPDF2 import PdfFileMerger
now = datetime.now()
pdfs = [
'images/Django_Crash_Course_5.5x8in.pdf',
'_output/dcc.pdf',
]
merger = PdfFileMerger()
for pdf in pdfs:
merger.append(pdf)
merger.write("releases/beta-20200226.pdf")
merger.close()
这时我们才发现,我们的新文件releases/beta-20200226.pdf缺少大部分元数据。糟糕!
添加元数据
根据 PyPDF2 文档,添加元数据非常简单。只需将一个参数传递dict给addMetadata()函数即可。我在调用函数之前插入了这段代码merger.write():
merger.addMetadata({
"Title": "Django Crash Course",
"Authors": 'Daniel Roy Greenfeld, Audrey Roy Greenfeld',
"Description": "Covers Python 3.8 and Django 3.x",
"ContentCreator": "Two Scoops Press",
"CreateDate": "2020-02-26",
"ModifyDate": "2020-02-26",
})
PDF文件生成成功!太棒了!是时候打开看看结果了!
遗憾的是,没有显示任何元数据。
然后我花了很长时间反复尝试,才让元数据正确显示出来。虽然有很多关于使用 PyPDF2提取元数据的 Python 相关文章,但我很难找到任何关于如何添加元数据的说明。
做作业
经过一番研究(谷歌搜索、Stack Overflow 查询和访问论坛),我在 O'Reilly 出版社找到了一本很棒的书,叫做《PDF Explained》,作者是 John Whitington。John Whitington 文笔很好,而且对 PDF 领域非常精通,值得称赞。
就我的目的而言,两个关键部分位于《PDF Explained》的第四章:
- https://www.oreilly.com/library/view/pdf-explained/9781449321581/ch04.html#didentries
- https://www.oreilly.com/library/view/pdf-explained/9781449321581/ch04.html#dates
根据我阅读的资料,我制定了以下规则:
- 每个元数据字段名称都必须以“.”为前缀。
/ - 请使用第 4 章中列出的元数据名称。
- 请遵循第 4 章中提供的日期格式。
编写代码!
现在我掌握了规则,回到代码中去。以下是我的成果:
from datetime import datetime
from PyPDF2 import PdfFileMerger
pdfs = [
'images/Django_Crash_Course_5.5x8in.pdf',
'_output/dcc.pdf',
]
merger = PdfFileMerger()
for pdf in pdfs:
merger.append(pdf)
# Make PDF datestamp
now = datetime.now()
pdf_datestamp = now.strftime("D:%Y%m%d%H%M%S-8'00'")
# https://www.oreilly.com/library/view/pdf-explained/9781449321581/ch04.html#didentries
# Fields are **precisely** named
merger.addMetadata({
"/Author": 'Daniel Roy Greenfeld, Audrey Roy Greenfeld',
"/Title": "Django Crash Course",
"/Subject": "Covers Python 3.8 and Django 3.x",
"/Creator": "Two Scoops Press",
"/CreationDate": pdf_datestamp,
"/ModDate": pdf_datestamp,
})
# Write the release
version = f"beta-{now.strftime('%Y%m%d')}"
merger.write(f"releases/{version}.pdf")
merger.close()
结论
编写这个小工具让我明白,尽管谷歌和 Stack Overflow 非常有用,但有时你仍然需要查阅参考手册。在我看来,这很有趣。:-)
说到参考手册,虽然我工作时参考了PDF Explained的在线版本,但我还是订购了一本Kindle版的纸质书。这是我至少应该做的。
文章来源:https://dev.to/feldroy/adding-metadata-to-pdfs-3adl