使用 iText 获取 pdf 文件中元素的坐标

发布于 2024-08-08 11:39:35 字数 394 浏览 13 评论 0原文

我正在使用 BIRT 报告库创建 pdf 文件。稍后我需要对这些文件进行数字签名。我正在使用 iText 对文档进行数字签名。

我面临的问题是,我需要将签名放在不同报告的不同位置。我已经有了对文档进行数字签名的代码,现在我总是将签名放在每个报告的最后一页的底部。

最终我需要每份报告都说明我需要在哪里签名。然后我必须使用 iText 读取该位置,然后将签名放在该位置。

这可以使用 BIRT 和 iText 实现吗?

谢谢

I'm creating a pdf file using BIRT reporting library. Later I need to digitally sign these files. I'm using iText to digitally sign the document.

The issue I'm facing is, I need to place the signature in different places in different reports. I already have the code to digitally sign the document, now I'm always placing the signature at the bottom of last page in every report.

Eventually I need each report to say where I need to place the signature. Then I've to read the location using iText and then place the signature at that location.

Is this possible to achieve using BIRT and iText

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白色秋天 2024-08-15 11:39:35

如果您愿意稍微作弊,您可以使用一个链接...根据我刚才对他们的文档的深入了解,BIRT 支持该链接。

链接是一个注释。遗憾的是,iText 不支持在高层检查注释,只支持生成注释,因此您必须使用低层对象调用。

提取它的代码可能如下所示:

// getPageN is looking for a page number, not a page index
PdfDictionary lastPageDict = myReader.getPageN(myReader.getNumberOfPages());

PdfArray annotations = lastPageDict.getAsArray( PdfName.ANNOTS );
PdfArray linkRect = null;
if (annotations != null) {
  int numAnnots = annotations.size();
  for (int i = 0; i < numAnnots; ++i) {
    PdfDictionary annotDict = annotations.getAsDict( i );
    if (annotDict == null) 
      continue; // it'll never happen, unless you're dealing with a Really Messed Up PDF.

    if (PdfName.LINK.equals( annotDict.getAsName( PdfName.SUBTYPE ) )) {
      // if this isn't the only link on the last page, you'll have to check the URL, which
      // is a tad more work.
      linkRect = annotDict.getAsArray( PdfName.RECT );

      // a little sanity check here wouldn't hurt, but I have yet to come across a PDF
      // that was THAT screwed up, and I've seen some Really Messed Up PDFs over the years.

      // and kill the link, it's just there for a placeholder anyway.
      // iText doesn't maintain any extra info on links, so no need for other calls.
      annotations.remove( i ); 
      break;
    }
  }
}

if (linkRect != null) {
  // linkRect is an array, thusly: [ llx, lly, urx, ury ].
  // you could use floats instead, but I wouldn't go with integers.  
  double llx = linkRect.getAsNumber( 0 ).getDoubleValue(); 
  double lly = linkRect.getAsNumber( 1 ).getDoubleValue();
  double urx = linkRect.getAsNumber( 2 ).getDoubleValue();
  double ury = linkRect.getAsNumber( 3 ).getDoubleValue();

  // make your signature
  magic();
}

如果 BIRT 在链接下的页面内容中生成一些文本以用于其视觉表示,那么这只是一个小问题。您的签名应完全覆盖它。

如果您一开始就可以直接从 BIRT 生成签名,那么您肯定会更好,但是我对他们的文档的一点检查并没有让我对他们的 PDF 定制能力充满信心......尽管坐在 iText 之上。它是一个能够生成 PDF 的报告生成器...我不应该期望太多。
`

编辑:如果您需要查找特定的 URL,您需要查看 PDF 参考的“12.5.6.5 链接注释”部分,可以在此处找到:
http://www.adobe.com/content /dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf

If you're willing to cheat a bit, you can use a link... which BIRT supports according to my little dive into their docs just now.

A link is an annotation. Sadly, iText doesn't support examining annotations at a high level, only generating them, so you'll have to use the low-level object calls.

The code to extract it might look something like this:

// getPageN is looking for a page number, not a page index
PdfDictionary lastPageDict = myReader.getPageN(myReader.getNumberOfPages());

PdfArray annotations = lastPageDict.getAsArray( PdfName.ANNOTS );
PdfArray linkRect = null;
if (annotations != null) {
  int numAnnots = annotations.size();
  for (int i = 0; i < numAnnots; ++i) {
    PdfDictionary annotDict = annotations.getAsDict( i );
    if (annotDict == null) 
      continue; // it'll never happen, unless you're dealing with a Really Messed Up PDF.

    if (PdfName.LINK.equals( annotDict.getAsName( PdfName.SUBTYPE ) )) {
      // if this isn't the only link on the last page, you'll have to check the URL, which
      // is a tad more work.
      linkRect = annotDict.getAsArray( PdfName.RECT );

      // a little sanity check here wouldn't hurt, but I have yet to come across a PDF
      // that was THAT screwed up, and I've seen some Really Messed Up PDFs over the years.

      // and kill the link, it's just there for a placeholder anyway.
      // iText doesn't maintain any extra info on links, so no need for other calls.
      annotations.remove( i ); 
      break;
    }
  }
}

if (linkRect != null) {
  // linkRect is an array, thusly: [ llx, lly, urx, ury ].
  // you could use floats instead, but I wouldn't go with integers.  
  double llx = linkRect.getAsNumber( 0 ).getDoubleValue(); 
  double lly = linkRect.getAsNumber( 1 ).getDoubleValue();
  double urx = linkRect.getAsNumber( 2 ).getDoubleValue();
  double ury = linkRect.getAsNumber( 3 ).getDoubleValue();

  // make your signature
  magic();
}

If BIRT generates some text in the page contents under the link for its visual representation, that's only a minor issue. Your signature should cover it completely.

You're definitely better of if you can generate the signature directly from BIRT in the first place, but my little inspection of their docs didn't exactly fill me with confidence in their PDF customization abilities... despite sitting on top of iText themselves. It's a report generator that happens to be able to produce PDFs... I shouldn't expect too much.
`

Edit: If you need to look for the specific URL, you'll want to look at section "12.5.6.5 Link Annotations" of the PDF Reference, which can be found here:
http://www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf

白馒头 2024-08-15 11:39:35

我对BIRT一无所知,对iText也只有一点了解。但也许这可行...

BIRT 可以将签名框的轮廓生成为具有给定字段名称的常规表单字段吗?如果是这样,那么您应该能够:

  1. 使用 getField 在 iText 的 AcroFields 哈希图中按名称查找该字段;
  2. 使用 pdf stamper 创建新签名,并根据旧字段对象的值设置其几何形状;并
  3. 使用removeField删除旧字段。

I don't know anything about BIRT, and have only a little familiarity with iText. But maybe this works...

Can BIRT generate the signature box's outline as a regular form field with a given field name? If so, then you should be able to:

  1. Lookup that field by name in iText's AcroFields hashmap, using getField;
  2. Create a new signature using the pdf stamper, and set its geometry based on the values of the old field object; and
  3. Delete the old field using removeField.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文