如何用 ITextPDF 库替换 pdf 文件中的文本?

How to replace a text in pdf file with ITextPDF library?

我需要用实际值替换像 ${placeholder} 这样的占位符,但我找不到任何可行的解决方案...我一直在关注 https://itextpdf.com/en/resources/examples/itext-7/replacing-pdf-objects 但它没有工作。有人知道怎么做吗?

一般来说,"replace" pdf 文件的内容并不是那么容易,因为它可以用不同的方式编写。例如,假设您要将块 "Hello" 替换为块 "World"。如果 "Hello" 已作为一个完整的单词写入 pdf,那么你会很幸运。它可能被写成 "He" 和 "llo",甚至 "o","l","l","e","H",这些字母可能会放在内容流的不同部分。

但是可以删除内容,然后将一些其他内容放在同一位置。

让我们看看如何实现。

1) 我建议你使用 iText 的 pdfSweep,因为这个工具能够检测放置内容的区域并删除内容(重要的是要提到 pdfSweep 不会隐藏内容,它将完全删除)

请看下一个示例:https://github.com/itext/i7j-pdfsweep/blob/develop/src/test/java/com/itextpdf/pdfcleanup/BigDocumentAutoCleanUpTest.java

让我们讨论一下 redactTonySoprano 测试。如您所见,可以提供一些正则表达式(例如,“"Tony( |_)Soprano"、"Soprano" 和 "Sopranoes"),iText 将编辑所有匹配的内容。

然后您可以使用 iText 通过低级 api (PdfCanvas) 或更复杂的高级 api (Canvas) 在这些区域上写一些文本等)。

让我们稍微修改一下我之前提到的女高音样本:

2) 让我们在编辑区域添加一些文本:

for (IPdfTextLocation location : strategy.getResultantLocations()) {
PdfPage page = pdf.getPage(location.getPageNumber()+1);
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), page.getDocument());
Canvas canvas = new Canvas(pdfCanvas, pdf, location.getRectangle());
canvas.add(new Paragraph("SECURED").setFontSize(8));

}

结果并不理想,但这只是概念验证。可以覆盖提取策略并定义编辑内容的字体,以便它可以用于要放置在编辑区域的新文本。

下面使用 iText 替换 PDF 内容的示例代码

    File dir = new File("./");
    File [] files = dir.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".pdf");
        }
    });

    for (File pdffile : files) {
        System.out.println(pdffile.getName());
        PdfReader reader = null;
        reader = new PdfReader(pdffile.toString()); 

      PdfDictionary dict = reader.getPageN(1);
      PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
      if (object instanceof PRStream) {
          PRStream stream = (PRStream)object;
          byte[] data = PdfReader.getStreamBytes(stream);
          String dd = new String(data);
          dd = dd.replace("0 0 0 rg\n()Tj", "0 0 0 rg\n(Plan Advanced Payment)Tj");
          System.out.print(dd);
          stream.setData(dd.getBytes());
      }
      PdfStamper stamper = new PdfStamper(reader,
      new FileOutputStream("./output/"+pdffile.getName())); // output PDF
      stamper.close();
      reader.close();
    }