gpt4 book ai didi

java - PDFBox 2.0 读取单页并写入/保存到新文件

转载 作者:行者123 更新时间:2023-11-30 07:26:46 79 4
gpt4 key购买 nike

基于this SO question我尝试阅读 pdf 文件中的每一页。其背景是,我试图用完全空白的页面替换不包含任何文本内容但包含图像的页面。其背景是 pdf 可以包含可能包含图像的空白页。这些页面确实需要存在,因为它们即将进行双面打印。

但是对于 PDFBox 2.0,这似乎有点复杂,因为每次我尝试保存新生成的 PDDocument 时都会遇到堆栈跟踪。新版本的 PDFBox 2.0 是否应该采取不同的做法?我是否应该避免关闭 PDDocument 缓冲区,因为将其排除在外,示例程序会毫无异常(exception)地运行,这可能会产生什么潜在副作用?

这里可以看到一个简单的运行示例。您可以使用任何 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()。这将制作一个深拷贝。

关于java - PDFBox 2.0 读取单页并写入/保存到新文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36718582/

79 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com