通过pdfbox删除pdf中的一个句子

问题描述

我做了删除水印的工作。我遇到了如何删除 pdf 文件中的句子的问题。我有一个想法,在处理运算符(TJ Tj ')时,我记录此类运算符的顺序(TJ Tj ' ... showIdx)。当发现需要删除的句子时,我找到操作符的顺序索引,并重新处理内容流,删除它们。 [op]https://stackoverflow.com/questions/58475104/filter-out-all-text-above-a-certain-font-size-from-pdf>[1] 介绍了 PdfContentStreamEditor,但我无法从中获得帮助。

BT    
Tj   showIdx2
TJ   showIdx2
、
ET

BT
Tj    showIdx3
TJ    showIdx4
、
ET
···
[the case pdf file]  <a https://github.com/zhongguogu/PDFBox/blob/master/pdf/watermark.pdf >
the content in page header "本报告仅供-中庚基金管理有限公司-中庚报告邮箱使用 p2"

解决方法

根据谷歌翻译那句话是“本报告仅供-中庚基金管理有限公司-中庚报告邮箱”。这很可能意味着,这份报告确实是给钟庚看的。但让我们假设他们决定更广泛地发布这些报告,而您的任务是取消该软限制。

您提到了 this answer 中的 PdfContentStreamEditor

确实,您可以像在 this answer 中使用它的方式一样使用它,其中要从某些 QR 代码下方删除字符串“[QR]”:

PDDocument document = ...
for (PDPage page : document.getDocumentCatalog().getPages()) {
    PdfContentStreamEditor editor = new PdfContentStreamEditor(document,page) {
        final StringBuilder recentChars = new StringBuilder();

        @Override
        protected void showGlyph(Matrix textRenderingMatrix,PDFont font,int code,Vector displacement)
                throws IOException {
            String string = font.toUnicode(code);
            if (string != null)
                recentChars.append(string);

            super.showGlyph(textRenderingMatrix,font,code,displacement);
        }

        @Override
        protected void write(ContentStreamWriter contentStreamWriter,Operator operator,List<COSBase> operands) throws IOException {
            String recentText = recentChars.toString();
            recentChars.setLength(0);
            String operatorString = operator.getName();

            if (TEXT_SHOWING_OPERATORS.contains(operatorString) && "本报告仅供-中庚基金管理有限公司-中庚报告邮箱使用 p2".equals(recentText))
            {
                return;
            }

            super.write(contentStreamWriter,operator,operands);
        }

        final List<String> TEXT_SHOWING_OPERATORS = Arrays.asList("Tj","'","\"","TJ");
    };
    editor.processPage(page);
}
document.save("watermark-RemoveByText.pdf");

(RemoveText 测试 testRemoveByText)

但是请注意,这仅适用于使用一个仅显示指令的文本绘制要删除的文本并且该指令仅绘制要删除的文本的情况。

如果要替换的文本是使用多个相互跟随的指令绘制的,那么只要您有潜在的匹配项,您就必须开始收集指令,而不是立即删除它们。一旦潜在匹配最终证明不是匹配,您就必须super.write收集到的说明。

如果替换的文本只是单个指令所绘制内容的一部分,则您将不得不修改该指令。取决于一个人的脚本,这可能非常困难,取决于它使用了多少连字和其他东西。

而且最复杂的情​​况可能需要您在收到指令时收集所有指令,分析整个指令,调整已识别的指令,然后将处理过的收集到的指令转发给 super.write