我想将原始 PDF 文档的文本复制到新的 PDF 文档中,并保留源文本的格式。
我已经做了一些测试,但是复制文本的结果 进入新文件并不是我所希望的。下面我展示了代码 内容流。
for (PDPage page : newDoc.getPages()) {
PDPageContentStream contentStream = new PDPageContentStream(newDoc, page);
contentStream.beginText();
for(List<TextLine> row : rowList){
for(TextLine characters : line){
contentStream.setFont(characters.getFont(), characters.getFontSize());
contentStream.newLineAtOffset(characters.getxPos(), characters.getyPos());
contentStream.setLeading(10.5f);
contentStream.showText(characters.getText());
}
}
contentStream.endText();
contentStream.close();
}
我的代码似乎只复制源文档最后一页的最后一个单词,同时保留格式。 我该如何解决这个问题?
我们已经在对您的问题的评论中讨论了您的方法,您最终要求提供一个实际示例。
不幸的是,你的代码不可编译,更不用说可运行了,所以我不得不创建一些不同的代码:
void copyText(PDDocument source, int sourcePageNumber, PDDocument target, PDPage targetPage) throws IOException {
List<TextPosition> allTextPositions = new ArrayList<>();
PDFTextStripper pdfTextStripper = new PDFTextStripper() {
@Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
allTextPositions.addAll(textPositions);
super.writeString(text, textPositions);
}
};
pdfTextStripper.setStartPage(sourcePageNumber + 1);
pdfTextStripper.setEndPage(sourcePageNumber + 1);
pdfTextStripper.getText(source);
PDRectangle targetPageCropBox = targetPage.getCropBox();
float yOffset = targetPageCropBox.getUpperRightY() + targetPageCropBox.getLowerLeftY();
try (PDPageContentStream contentStream = new PDPageContentStream(target, targetPage, AppendMode.APPEND, true, true)) {
contentStream.beginText();
float x = 0;
float y = yOffset;
for (TextPosition position: allTextPositions) {
contentStream.setFont(position.getFont(), position.getFontSizeInPt());
contentStream.newLineAtOffset(position.getX() - x, - (position.getY() - y));
contentStream.showText(position.getUnicode());
x = position.getX();
y = position.getY();
}
contentStream.endText();
}
}
您可以将其应用到完整文档,如下所示:
void copyText(PDDocument source, PDDocument target) throws IOException {
for (int i = 0; i < source.getNumberOfPages(); i++) {
PDPage sourcePage = source.getPage(i);
PDPage targetPage = null;
if (i < target.getNumberOfPages())
targetPage = target.getPage(i);
else
target.addPage(targetPage = new PDPage(sourcePage.getMediaBox()));
copyText(source, i, target, targetPage);
}
}
应用于一些示例文档:
正如预期的那样,实际绘制为位图图像的“文本”不会被复制。
还要注意,这只是一个概念证明,而不是完整的实现。特别是,通常不支持页面旋转和非直立文本。此外,唯一支持的样式属性是文本字体和文本大小,其他细节(例如文本颜色)将被忽略。源和目标中不同的页面几何形状也会导致奇怪的外观。
由于您没有提到具体的 PDFBox 版本,所以我使用当前的 3.0.1。