通过 pdfbox 删除 pdf 中的一个句子
Remove a sentence in pdf by pdfbox
我做去除水印的工作。我遇到了如何删除 pdf 文件中的句子的问题。我有一个想法,在处理运算符(TJ Tj ')时,我记录了这样的运算符(TJ Tj ' ... showIdx)的顺序。当找到需要删除的句子时,我找到了运算符的顺序索引,并重新处理内容流,将其删除。
[op] 介绍 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"
根据Google翻译那一行说“本报告仅供-中庚基金管理有限公司-中庚报告信箱”。这很可能意味着,这份报告的确是只给钟庚看的。但让我们假设他们决定更广泛地发布这些报告,而您的任务是取消该软限制。
您提到了 中的 PdfContentStreamEditor
。
实际上,您可以像在 中使用它一样使用它,其中字符串“[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
。
我做去除水印的工作。我遇到了如何删除 pdf 文件中的句子的问题。我有一个想法,在处理运算符(TJ Tj ')时,我记录了这样的运算符(TJ Tj ' ... showIdx)的顺序。当找到需要删除的句子时,我找到了运算符的顺序索引,并重新处理内容流,将其删除。
[op]
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"
根据Google翻译那一行说“本报告仅供-中庚基金管理有限公司-中庚报告信箱”。这很可能意味着,这份报告的确是只给钟庚看的。但让我们假设他们决定更广泛地发布这些报告,而您的任务是取消该软限制。
您提到了 PdfContentStreamEditor
。
实际上,您可以像在
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
。