如何使用 PDFBox 将文档中逐页提取的文本复制到新的 PDF 文档中?

问题描述 投票:0回答:1

我想将原始 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();
} 
下面我向您展示源文档和目标文档的示例: source document destination document

我的代码似乎只复制源文档最后一页的最后一个单词,同时保留格式。 我该如何解决这个问题?

java pdfbox
1个回答
0
投票

我们已经在对您的问题的评论中讨论了您的方法,您最终要求提供一个实际示例

不幸的是,你的代码不可编译,更不用说可运行了,所以我不得不创建一些不同的代码:

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();
    }
}

CopyFormattedPageText方法)

您可以将其应用到完整文档,如下所示:

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);
    }
}

CopyFormattedPageText方法)

应用于一些示例文档:

原创 复制

正如预期的那样,实际绘制为位图图像的“文本”不会被复制。

还要注意,这只是一个概念证明,而不是完整的实现。特别是,通常不支持页面旋转和非直立文本。此外,唯一支持的样式属性是文本字体和文本大小,其他细节(例如文本颜色)将被忽略。源和目标中不同的页面几何形状也会导致奇怪的外观。


由于您没有提到具体的 PDFBox 版本,所以我使用当前的 3.0.1。

© www.soinside.com 2019 - 2024. All rights reserved.