使用pyobjc向pdf写入元数据

6 投票
2 回答
1534 浏览
提问于 2025-04-16 06:34

我正在尝试用以下的Python代码给一个PDF文件写入元数据:

from Foundation import *
from Quartz import *

url = NSURL.fileURLWithPath_("test.pdf")
pdfdoc = PDFDocument.alloc().initWithURL_(url)
assert pdfdoc, "failed to create document"

print "reading pdf file"

attrs = {}
attrs[PDFDocumentTitleAttribute] = "THIS IS THE TITLE"
attrs[PDFDocumentAuthorAttribute] = "A. Author and B. Author"

PDFDocumentTitleAttribute = "test"

pdfdoc.setDocumentAttributes_(attrs)
pdfdoc.writeToFile_("mynewfile.pdf")   

print "pdf made"

这看起来运行得不错(控制台没有报错),但是当我检查文件的元数据时,结果是这样的:

PdfID0:
242b7e252f1d3fdd89b35751b3f72d3
PdfID1:
242b7e252f1d3fdd89b35751b3f72d3
NumberOfPages: 4

而原始文件的元数据是这样的:

InfoKey: Creator
InfoValue: PScript5.dll Version 5.2.2
InfoKey: Title
InfoValue: Microsoft Word - PROGRESS  ON  THE  GABION  HOUSE Compressed.doc
InfoKey: Producer
InfoValue: GPL Ghostscript 8.15
InfoKey: Author
InfoValue: PWK
InfoKey: ModDate
InfoValue: D:20101021193627-05'00'
InfoKey: CreationDate
InfoValue: D:20101008152350Z
PdfID0: d5fd6d3960122ba72117db6c4d46cefa
PdfID1: 24bade63285c641b11a8248ada9f19
NumberOfPages: 4

所以问题是,它没有把新的元数据添加上去,而且还清除了之前的元数据结构。我需要做些什么才能让这个工作正常?我的目标是添加可以被管理系统导入的元数据。

2 个回答

2

免责声明:我对Python完全是新手,但对PDF很熟悉。

为了避免覆盖掉已有的属性,你需要用pdfDoc.documentAttributes来初始化attrs,而不是用{}。因为setDocumentAttributes很可能是一个覆盖操作,而不是合并操作(根据你这里的输出来看)。

其次,所有的PDFDocument*Attribute常量都是PDFDocument的一部分。我对Python的了解肯定不够,但难道你不应该把它们当作属性来引用,而不是单纯的变量吗?应该像这样:

attrs[PDFDocument.PDFDocumentTitleAttribute] = "THIS IS THE TITLE"

你能把值赋给PDFDocumentTitleAttribute,让我觉得它可能不是一个常量。

如果我没猜错的话,你的attrs可能试图把多个值赋给一个空的键。我对Python的了解有限,所以不太清楚你该怎么检查这一点。在调用pdfDoc.setDocumentAttributes_()之前检查一下attrs应该会有帮助。

6

马克的思路是对的,但有一些特别的地方需要注意。

首先,他说得没错,pdfdoc.documentAttributes 是一个 NSDictionary,里面包含了文档的元数据。你想要修改这些内容,但要注意,documentAttributes 返回的是一个不可变的 NSDictionary。所以你需要把它转换成一个可以修改的 NSMutableDictionary,方法如下:

attrs = NSMutableDictionary.alloc().initWithDictionary_(pdfDoc.documentAttributes())

现在你可以像之前那样修改 attrs 了。没有必要像马克建议的那样写 PDFDocument.PDFDocumentTitleAttribute,那样是行不通的,因为 PDFDocumentTitleAttribute 是一个模块级常量,所以只需按照你自己代码中的方式来做就可以了。

下面是我能用的完整代码:

from Foundation import *
from Quartz import *

url = NSURL.fileURLWithPath_("test.pdf")
pdfdoc = PDFDocument.alloc().initWithURL_(url)

attrs = NSMutableDictionary.alloc().initWithDictionary_(pdfdoc.documentAttributes())
attrs[PDFDocumentTitleAttribute] = "THIS IS THE TITLE"
attrs[PDFDocumentAuthorAttribute] = "A. Author and B. Author"

pdfdoc.setDocumentAttributes_(attrs)
pdfdoc.writeToFile_("mynewfile.pdf")

撰写回答