簡體   English   中英

PDFBox 2.0 讀取單頁並寫入/保存到新文件

[英]PDFBox 2.0 Read single page and write/save to a new File

基於this SO question,我嘗試通讀pdf文件中的每一頁。 這樣做的背景是,我試圖替換不包含任何文本內容但包含完全空白頁面的圖像的頁面。 這樣做的背景是 pdf 可以包含可能包含圖像的空白頁面。 這些頁面確實需要在那里,因為它們即將用雙面打印。

但是對於 PDFBox 2.0,這似乎有點復雜,因為我每次嘗試保存新生成的PDDocument 這應該與新版本的PDFBox 2.0什么不同嗎? 我是否應該避免關閉PDDocument buffer ,因為通過將它排除在外,示例程序確實會毫無例外地運行,這可能會產生什么PDDocument buffer副作用?

可以在這里看到一個簡單的運行示例。 您可以使用任何 pdf 文件,因為結果將是具有相同頁數的 pdf 文件,這些文件應該是空的:

public static void main(String[] args) throws IOException {
    // Load a simple pdf file
    PDDocument d = PDDocument.load(new File("D:\\test.pdf"));
    // This should be our new output pdf
    PDDocument c = new PDDocument();
    for(int i = 0;i<d.getNumberOfPages();++i) {
        // From the SO question, create a new PDDocument and just add the single page
        PDDocument buffer = new PDDocument();
        PDPage page = d.getPage(i);
        buffer.addPage(page);

        // Here i´d check if it has content but gonna leave it out now

        // Reassign the page variable to generate a "blank" pdf
        page = new PDPage(); 

        // In order to let some printers not ignore the blank page I have to 
        // write white text on the white background.
        PDPageContentStream contentStream = new PDPageContentStream(buffer, page);

        PDFont font = PDType1Font.HELVETICA_BOLD;
        contentStream.beginText();
        contentStream.setNonStrokingColor(Color.white); // !!!!!!
        contentStream.setFont( font, 6 );
        contentStream.newLineAtOffset(100, 700);
        contentStream.showText("Empty page");
        contentStream.endText();
        contentStream.close();
        // Close the buffer document, if i comment it out the exception is gone
        buffer.close();
        // Add the blank page
        c.addPage(page);
    }
    d.close();
    // The exception occurs here and seems to be connected with the closing of the buffer document
    c.save("D:\\newtest.pdf");
    c.close();
}

堆棧跟蹤:

Exception in thread "main" java.io.IOException: Scratch file already closed
at org.apache.pdfbox.io.ScratchFile.checkClosed(ScratchFile.java:390)
at org.apache.pdfbox.io.ScratchFileBuffer.checkClosed(ScratchFileBuffer.java:99)
at org.apache.pdfbox.io.ScratchFileBuffer.seek(ScratchFileBuffer.java:295)
at org.apache.pdfbox.io.RandomAccessInputStream.restorePosition(RandomAccessInputStream.java:47)
at org.apache.pdfbox.io.RandomAccessInputStream.read(RandomAccessInputStream.java:78)
at java.io.InputStream.read(InputStream.java:101)
at org.apache.pdfbox.io.IOUtils.copy(IOUtils.java:66)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromStream(COSWriter.java:1134)
at org.apache.pdfbox.cos.COSStream.accept(COSStream.java:372)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteObject(COSWriter.java:533)
at org.apache.pdfbox.pdfwriter.COSWriter.doWriteBody(COSWriter.java:450)
at org.apache.pdfbox.pdfwriter.COSWriter.visitFromDocument(COSWriter.java:1034)
at org.apache.pdfbox.cos.COSDocument.accept(COSDocument.java:409)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1284)
at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1185)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1110)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1082)
at org.apache.pdfbox.pdmodel.PDDocument.save(PDDocument.java:1070)
at pdftools.Test.main(Test.java:41)

您的代碼有些混亂,但問題的核心是在 2.0 中,如果您在另一個文檔中使用它們的頁面,則不應關閉這些文檔。

所以這里有一些解決方案:

  • 不要關閉緩沖文檔,而是保留這些文檔直到完成
  • 創建頁面及其內容兩次
  • 僅為目的地創建新頁面(為什么要為“緩沖區”創建它,無論如何都要轉儲?)
  • 不要使用 addPage() 復制頁面,而是使用 importPage()。 這將進行深度復制。

我一直在尋找 2021 年的解決方案,這就是現在可以完成的方法(Java/Kotlin)。 示例從 PDF 文件中提取頁面並將其保存在額外文件中。

import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.PDPage
import java.io.File

val inputPdf = File("C:\\myInput.pdf")
val outputPdf = File("C:\\myOutput.pdf")

fun main(args: Array<String>) =
    PDDocument.load(inputPdf).use {
        savePageToExtraFile(it.pages.first(), outputPdf)
    }

fun savePageToExtraFile(page: PDPage, outputFile: File) =
    PDDocument().use {
        it.importPage(page)
        it.save(outputFile)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM