使用iText 7.1从PDF中删除链接

时间:2018-05-22 22:53:02

标签: java pdf hyperlink itext7

我们的供应商不接受包含链接的PDF。我们试图通过使用iText 7.1(Java)从PDF的每个页面删除所有链接注释来删除链接。我们尝试了多种基于研究的技术。以下是尝试检测和删除链接的三个示例。这些都不会导致删除链接的目标PDF(test-no-links.pdf)。任何见解将不胜感激。

示例1:基于注释的类类型删除

  String src  = "test-with-links.pdf";
  String dest = "test-no-links.pdf";

  PdfReader   reader  = new PdfReader(src);
  PdfWriter   writer  = new PdfWriter(dest);
  PdfDocument pdfDoc  = new PdfDocument(reader,writer);

  for( int page = 1; page <= pdfDoc.getNumberOfPages(); ++page ) {
    PdfPage               pdfPage     = pdfDoc.getPage(page);
    List<PdfAnnotation>   annots      = pdfPage.getAnnotations();

    if ((annots == null) || (annots.size() == 0)) {
      System.out.println("no annotations on page " + page);
    }
    else {
      for( PdfAnnotation annot : annots ) {
        if( annot instanceof PdfLinkAnnotation ) {
          pdfPage.removeAnnotation(annot);
        }
      }
    }
  }
  pdfDoc.close();

示例2:根据注释子类型值

删除
  String src  = "test-with-links.pdf";
  String dest = "test-no-links.pdf";

  PdfReader   reader  = new PdfReader(src);
  PdfWriter   writer  = new PdfWriter(dest);
  PdfDocument pdfDoc  = new PdfDocument(reader,writer);

  for( int page = 1; page <= pdfDoc.getNumberOfPages(); ++page ) {
    PdfPage               pdfPage     = pdfDoc.getPage(page);
    List<PdfAnnotation>   annots      = pdfPage.getAnnotations();

    if ((annots == null) || (annots.size() == 0)) {
      System.out.println("no annotations on page " + page);
    }
    else {
      for( PdfAnnotation annot : annots ) {
        // if this annotation has a link, delete it
        if ( annot.getSubtype().equals(PdfName.Link) ) {
          PdfDictionary annotAction = ((PdfLinkAnnotation)annot).getAction();

          if( annotAction.get(PdfName.S).equals(PdfName.URI) ||
              annotAction.get(PdfName.S).equals(PdfName.GoToR) ) {
            PdfString uri = annotAction.getAsString(PdfName.URI);
            System.out.println("Removing " + uri.toString());
            pdfPage.removeAnnotation(annot);
          }
        }
      }
    }
  }
  pdfDoc.close();

示例3:删除所有注释(忽略注释类型)

  String src  = "test-with-links.pdf";
  String dest = "test-no-links.pdf";

  PdfReader   reader  = new PdfReader(src);
  PdfWriter   writer  = new PdfWriter(dest);
  PdfDocument pdfDoc  = new PdfDocument(reader,writer);

  for( int page = 1; page <= pdfDoc.getNumberOfPages(); ++page ) {
    PdfPage               pdfPage     = pdfDoc.getPage(page);

    // remove all annotations from the page regardless of type
    pdfPage.getPdfObject().remove(PdfName.Annots);
  }
  pdfDoc.close();

1 个答案:

答案 0 :(得分:0)

每个测试都会生成一个没有链接注释的PDF。

但是,您的PDF查看器可能会将“www.qualpay.com”识别为(部分)网址并将其显示为链接。

详细

你的惯例

您的所有测试都成功删除了样本PDF中的所有链接注释,参见这些屏幕截图来源和所有三个结果文件,特别是查找页面1 Annots 条目:

测试与 - links.pdf

test-with-links.pdf

测试无links.pdf

test-no-links.pdf

测试无链接-次数1.pdf

test-no-links-1.pdf

测试无链接-2.pdf

test-no-links-2.pdf

观众

事实上,在Adobe Acrobat Reader(以及其他一些观看者,例如Chrome和Edge的内置PDF查看器)中查看PDF时,您会看到“www.qualpay.com”被视为一个链接。

原因是这是PDF查看器的功能 !它会扫描它显示的PDF文本,以查找它识别为某些URL(的一部分)的字符串,并将它们显示为链接!

在Adobe Acrobat Reader中,您可以禁用此功能:

Preferences / General

如果您禁用“从网址创建链接”,您会突然发现结果文件中的网址处于非活动状态,而源文件中的网址(包含链接注释)仍处于活动状态。

怎么做

  

我们的供应商不接受包含链接的PDF。

首先与您的供应商讨论“含有链接的PDF”的含义。他的意思是

  • PDF 链接注释
  • 包含常见PDF查看器的网址的PDF,如链接注释

在前一种情况下,您已完成,您的代码(任一变体)会删除链接注释。但是,您可能必须向供应商演示如何在Adobe Acrobat Reader中禁用URL识别。

在后一种情况下,您必须从PDF文本内容中删除常见PDF查看器识别为URL的所有内容。您可以使用URL文本的位图图像替换每个URL,或者像通用矢量图形(定义直线和曲线的路径并填充它)或某些类似的代理项一样绘制URL文本。