我有一个以前使用 FOP 创建的 PDF,我需要向其中添加一些命名的目标,以便稍后另一个程序可以使用 Adobe PDF 打开参数打开和导航文档,即#namedest=destination_name参数。
我不需要添加书签或其他动态内容,只需添加一些带有名称的目的地,从而注入一个 /Dests 集合,其名称在生成的 PDF 中定义。
我使用 iText 5.3.0 并阅读了 iText in Action(第 2 版)的第 7 章,但我仍然无法弄清楚如何添加目的地,因此在浏览器中将它们与#nameddest一起使用。
我正在使用 PdfReader 和 PdfStamper 阅读和操作文档。在使用自定义侦听器和 PdfContentStreamProcessor 解析文档并在每个页面上搜索特定文本标记后,我已经提前知道将每个目的地放在哪里。
这是我的代码的缩短版本:
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new BufferedOutputStream(dest));
// search text markers for destinations, page by page
for (int i=1; i<reader.getNumberOfPages(); i++) {
// get a list of markers for this page, as obtained with a custom Listener and a PdfContentStreamProcessor
List<MyDestMarker> markers = ((MyListener)listener).getMarkersForThisPage();
// add a destination for every text marker in the current page
Iterator<MyDestMarker> it = markers.iterator();
while(it.hasNext()) {
MyDestMarker marker = it.next();
String name = marker.getName();
String x = marker.getX();
String y = marker.getY();
// create a new destination
PdfDestination dest = new PdfDestination(PdfDestination.FITH, y); // or XYZ
// add as a named destination -> does not work, only for new documents?
stamper.getWriter().addNamedDestination(name, i /* current page */, dest);
// alternatives
PdfContentByte content = stamper.getOverContent(i);
content.localDestination(name, dest); // doesn't work either -> no named dest found
// add dest name to a list for later use with Pdf Open Parameters
destinations.add(name);
}
}
stamper.close();
reader.close();
我还尝试使用 PdfFormField.createLink() 创建 PdfAnnotation,但我仍然设法获取注释,但没有定义命名目的地,它不起作用。
有什么解决办法吗?我是否需要使用 Chunks 或其他东西在现有内容上添加一些“幽灵”内容?
提前致谢。
编辑 01-27-2016:我最近在 iText 网站的示例部分找到了我的问题的答案,这里。
不幸的是,如果我使用没有预先定义目标的 pdf 对其进行测试,则提供的示例对我不起作用,就像源primes.pdf已经包含/Dests数组一样。这种行为似乎与 iText 代码一致,因为作者将目的地加载到 PdfDocument 的地图属性中,该属性在关闭时不是由压模“继承”的。
也就是说,我使用 5.5.7 版添加的 PdfStamper 的addNamedDestination()方法让它工作;此方法在类的本地地图属性中加载命名目的地,稍后在关闭压模时处理并合并到文档中。
但是,这种方法引发了一个新问题:使用 Pdf Open Parameters ( #, #nameddest= ) 的导航在 IE 上运行良好,但在 Chrome v47(也可能是 Firefox)上运行良好。我将问题追溯到文档中定义和引用 dest 名称的顺序;压模使用 HashMap 作为目的地的容器,这当然不能保证其对象的顺序,并且无论出于何种原因,Chrome 都拒绝识别未按“自然”顺序列出的目的地。所以,我让它工作的唯一方法是用自然排序的 TreeMap 替换namedDestinations HashMap。
希望这可以帮助其他人解决同样的问题。