添加自定义PDF元数据后加密致元数据丢失,如何解决?
如何同时为PDF添加自定义元数据和密码保护?
我尝试通过以下代码为任意PDF文件添加自定义元数据并设置密码保护:
import os, sys from PyPDF2 import PdfReader, PdfWriter if __name__ == '__main__': path = os.path.abspath(os.path.dirname(sys.argv[0])) fnTemplate = os.path.join(path, "template.pdf") propName = "Some Name" propValue = f"Some Value" wPW = "pw1" # Write custom metadata with open(fnTemplate, "rb") as file: pdf_reader = PdfReader(file) pdf_writer = PdfWriter() [pdf_writer.add_page(page) for page in pdf_reader.pages] pdf_writer.add_metadata( { f"/{propName}": propValue, **pdf_reader.metadata, } ) with open("workPDF1.pdf", "wb") as outFile: pdf_writer.write(outFile) # Password protect pdf reader = PdfReader("workPDF1.pdf") writer = PdfWriter() writer.append_pages_from_reader(reader) writer.encrypt(wPW) with open("finalPDF.pdf", "wb") as out_file: writer.write(out_file)
问题在于,生成的finalPDF.pdf仅实现了密码保护,但自定义元数据已丢失;而中间文件workPDF1.pdf中的自定义元数据是正常存在的。请问如何同时实现这两个功能?
解决方案
之所以finalPDF.pdf丢失自定义元数据,是因为第二步加密流程中,PdfWriter不会自动从PdfReader复制元数据,必须手动传递元数据信息。
优化方案一:合并流程(推荐)
将添加元数据和加密操作合并到同一个PdfWriter流程中,无需生成中间文件,既能减少磁盘IO,又能确保元数据和加密同时生效:
import os, sys from PyPDF2 import PdfReader, PdfWriter if __name__ == '__main__': path = os.path.abspath(os.path.dirname(sys.argv[0])) fnTemplate = os.path.join(path, "template.pdf") propName = "Some Name" propValue = f"Some Value" wPW = "pw1" with open(fnTemplate, "rb") as file: pdf_reader = PdfReader(file) pdf_writer = PdfWriter() # 添加所有页面到写入器 for page in pdf_reader.pages: pdf_writer.add_page(page) # 添加自定义元数据,同时保留原文件的元数据 pdf_writer.add_metadata( { f"/{propName}": propValue, **pdf_reader.metadata, } ) # 设置密码保护 pdf_writer.encrypt(wPW) # 直接写入最终加密且带元数据的PDF with open("finalPDF.pdf", "wb") as out_file: pdf_writer.write(out_file)
优化方案二:保留两步流程(手动复制元数据)
如果必须保留生成中间文件的流程,需要在加密步骤中手动将元数据从PdfReader复制到PdfWriter:
# 密码保护流程修改如下 reader = PdfReader("workPDF1.pdf") writer = PdfWriter() writer.append_pages_from_reader(reader) # 手动复制元数据 writer.add_metadata(reader.metadata) writer.encrypt(wPW) with open("finalPDF.pdf", "wb") as out_file: writer.write(out_file)
内容的提问来源于stack exchange,提问作者Rapid1898
相关产品推荐
相关产品推荐

