如何使用iTextSharp将XMP元数据添加到现有PDF的每个页面

时间:2015-02-10 08:27:25

标签: pdf itextsharp

到目前为止,所有示例似乎都涉及在创建新文档时添加元数据。我想使用现有的PDF并使用压模

为每个页面的XMP添加GUID

1 个答案:

答案 0 :(得分:1)

在PDF的上下文中最常见的XMP用法是为从PDF的根词典(也称为目录)引用的整个文档添加XMP流。

但是,如果您查阅PDF规范,您会注意到XMP可以在PDF中的许多其他对象的上下文中使用,页面级别就是其中之一。如果查看规范,您会发现/Metadata是页面词典中的可选键。它期望引用XMP流。

如果您要使用iText从头开始创建PDF文档,您将找不到添加此元数据的特定方法,但您可以使用addPageDictEntry()中提供的通用PdfWriter。您可以将PdfName.METADATA作为键和对已添加到PdfWriter的流的引用作为值传递。

您的问题不是从头开始创建PDF,而是关于修改现有PDF。在这种情况下,您还需要页面字典。获取这些词典非常容易:

PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfDictionary page;
for (int p = 1; p <= n; p++) {
    page = reader.getPageN(p);
    // do stuff with the page dictionary
}

此片段是从Rotate90Degrees示例中获取的。在该示例中,我们查看/Rotate条目,它是一个数字:

PdfNumber rotate = page.getAsNumber(PdfName.ROTATE);

您需要查找/Metadata条目,这是一个流:

PRStream stream = (PRStream) page.getAsStream(PdfName.METADATA);

也许此流是null,在这种情况下,您需要添加/Metadata条目,如AddXmpToPage示例中所示:

// We create some XMP bytes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XmpWriter xmp = new XmpWriter(baos, new PdfDictionary());
xmp.close();
// We add the XMP bytes to the writer
PdfIndirectObject ref = stamper.getWriter().addToBody(new PdfStream(baos.toByteArray()));
// We add a reference to the XMP bytes to the page dictionary
page.put(PdfName.METADATA, ref.getIndirectReference());

如果有XMP流,您希望保留它并向其添加内容。

这是获取XMP字节的方法:

byte[] xmpBytes = PdfReader.getStreamBytes(stream);

您在这些字节上执行XML魔术,从而产生一个名为newXmpBytes的新byte[]。用这些新字节替换原始字节,如下所示:

stream.setData(newXmpBytes);

所有这些操作都在驻留在PdfReader对象中的现有文件上完成。您现在必须坚持这样的更改:

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();