【发布时间】:2015-02-10 08:27:25
【问题描述】:
到目前为止,所有示例似乎都涉及在创建新文档时添加元数据。我想获取现有的 PDF 并使用压模将 GUID 添加到每个页面的 XMP
【问题讨论】:
标签: pdf itextsharp
到目前为止,所有示例似乎都涉及在创建新文档时添加元数据。我想获取现有的 PDF 并使用压模将 GUID 添加到每个页面的 XMP
【问题讨论】:
标签: pdf itextsharp
XMP 在 PDF 上下文中最常见的用途是为整个文档添加 XMP 流,该文档从 PDF 的根字典(也称为目录)中引用。
但是,如果您查阅 PDF 规范,您会注意到 XMP 可以在 PDF 内的许多其他对象的上下文中使用,页面级别就是其中之一。如果您查看规范,您会发现 /Metadata 是页面字典中的可选键。它需要对 XMP 流的引用。
如果您要使用 iText 从头开始创建 PDF 文档,您将找不到添加此元数据的特定方法,但您可以使用 PdfWriter 中提供的通用 addPageDictEntry()。您可以将 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
}
这个 sn-p 取自 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();
【讨论】: