当前位置: 首页 > 知识库问答 >
问题:

使用iText将命名目标添加到现有PDF文档

穆睿才
2023-03-14

我不需要添加书签或其他动态内容,只需要添加一些具有名称的目的地,从而注入一个/Dests集合,该集合具有在生成的PDF中定义的名称。

我使用了iText 5.3.0并且阅读了iText Inaction(第2版)的第7章,但是我仍然不知道如何添加目的地,所以在浏览器中使用#namedest。

我正在用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,但仍然,我只是设法获得了注释,但没有定义命名目的地,它就无法工作。

有什么解决办法吗?我是否需要添加一些“幽灵”内容超过现有的一个块或其他东西?

不幸的是,如果我使用一个没有在其中定义目的地的pdf来测试它,那么提供的示例对我来说就不起作用了,源码primes.pdf就是这种情况,它已经包含了/dests数组。这种行为似乎与iText代码一致,因为writer将目的地加载到PdfDocument的map属性中,而该属性在关闭时不是由stamper“继承”的。

这就是说,我使用5.5.7版中添加的PdfStamper的addNamedDestination()方法使其工作;此方法在类的本地映射属性中加载一个命名目标,该目标稍后在关闭压模时被处理并合并到文档中。

这种方法带来了一个新的问题:带有Pdf打开参数(#,#nameddest=)的导航在IE中运行良好,但在Chrome v47(可能还有Firefox)中就不行了。我将问题追踪到dests名称在文档中定义和引用的顺序;stamper使用一个HashMap作为目的地的容器,这当然不能保证其对象的顺序,而且无论出于什么原因,Chrome拒绝识别未按“自然”顺序列出的目的地。所以,我让它工作的唯一方法是用自然顺序的树映射替换namedDestinations HashMap。

希望这能帮助其他有同样问题的人。

共有1个答案

司徒骞尧
2023-03-14

我以前也有过同样的需求。必须用Acrobat.jar查看器显示和导航pdf文档。为了导航,我需要在PDF中指定目的地。我已经在网上寻找一个可能的解决方案,但对我来说并不幸运。然后我想到了这个想法。

我尝试用itext重新创建现有的pdf,浏览每一个页面并将localdestinations添加到每一个页面,我得到了我想要的。下面是我的代码片段

OutputStream outputStream = new FileOutputStream(new File(filename));
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfOutline pol = cb.getRootOutline();
PdfOutline oline1 = null;
InputStream in1 = new FileInputStream(new File(inf1));
PdfReader reader = new PdfReader(in1);
for (int i = 1; i <= reader.getNumberOfPages(); i++)
{
    document.newPage();
    document.setMargins(0.0F, 18.0F, 18.0F, 18.0F);
    PdfImportedPage page = writer.getImportedPage(reader, i);
    document.add(new Chunk(new Integer(i).toString()).setLocalDestination(new Integer(i).toString()));
    System.out.println(i);
    cb.addTemplate(page, 0.0F, 0.0F);
}
outputStream.flush();
document.close();
outputStream.close();

以为这会对你有帮助。

 类似资料:
  • 我正在使用iText生成Pdf。但当我试图在pdf中添加图像时, 我mage.get实例(新的URL(timetableResource.getImageUrl()));document.add(学校标志); 但我得到的错误是 HTTP状态500-服务器为URL返回了HTTP响应代码400:http://139.59.72.150:8080/sms/attachments/23/42/school

  • 问题内容: 我想对iText执行以下操作: (1)解析现有的PDF文件 (2)在文档的现有单页上添加一些数据(例如时间戳) (3)写出文件 我似乎无法弄清楚如何使用iText做到这一点。用伪代码可以做到这一点: Document document = reader.read(input); document.add(new Paragraph(“my timestamp”)); writer.wr

  • 我是新来的iText 7,我已经尝试添加ltv信息到现有的签名通过使用addolv()方法(下面提供的代码)...如果我理解正确的话,这个方法将crl或ocsp参数添加到现有的签名或时间戳中,然后对文档进行时间戳,但是生成的pdf文档没有启用ltv。然而,如果我首先用ocsp或crl列表签署文档,我就能够生成支持LTV的签名,这让我相信这个问题与某些证书丢失或未正确添加无关。因此,由于某种原因,a

  • 问题内容: 我正在尝试使用itext java api将anchor(命名为destinations)添加到pdf。但是它不起作用。当我单击文本时,什么也没有发生。这就是我在做什么。 我究竟做错了什么?。任何帮助 问题答案: 试试这个。它为我工作。并会做魔术。

  • 我在实现中适用于简单情况,但不适用于复杂情况。原始 pdf 将显示在中央窗格中。我有一个侧窗格,其中有一些矩形,如“名称”,“签名”,“时间戳”,可以在pdf上拖动。使用 j 查询可拖动 我知道图像以像素为单位,而PDF尺寸以点为单位。因此,我将以像素为单位的图像坐标转换为点(0.75)。还考虑到,对于图像,原点是在左上 角,而在pdf中,原点是左下角,对于图像,y轴是南区,但对于pdf y轴是北

  • 问题内容: 我的java项目分为两部分。 我需要填充pdf的字段 我需要在页面空白区域的填充部分下方添加一个表(并且该表需要能够移到下一页)。 我能够分别执行这些操作(填充pdf并创建表)。但是我无法有效地合并它们。我尝试做一个doc.add(table),这将导致该表在pdf的下一页上,这是我不想要的。 我基本上只需要能够指定表格在页面上的起始位置(这样它就不会与现有内容重叠),然后将表格标记到