当前位置: 首页 > 知识库问答 >
问题:

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

金阳曜
2023-03-14

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

但在PDFBox 2.0中,这似乎有点复杂,因为每次我试图保存新生成的PDDocument时,都会遇到堆栈跟踪。新版本的PDFBox 2.0是否应该与之有所不同?我是否应该避免关闭PDDocument缓冲区,因为如果不关闭它,示例程序会毫无例外地运行,这可能会有什么潜在的副作用?

可以在这里看到一个简单的运行示例。您可以使用任何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个答案

席俊
2023-03-14

我一直在寻找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)
    }
夏季萌
2023-03-14

您的代码有点令人困惑,但问题的核心是,在2.0中,如果在另一个文档中使用文档的页面,则不应关闭文档。

所以这里有一些解决方案:

  • 不要关闭缓冲区文档,而是保留这些文档直到完成
  • 创建页面及其内容两次
  • 仅为目标创建新页面(为什么要为“缓冲区”创建它,无论如何您都要转储它?)
  • 不要使用addPage()复制页面,而是使用import Page()。这将制作一个深度副本。
 类似资料:
  • 本文向大家介绍python读文件保存到字典,修改字典并写入新文件的实例,包括了python读文件保存到字典,修改字典并写入新文件的实例的使用技巧和注意事项,需要的朋友参考一下 实例如下所示: 以上这篇python读文件保存到字典,修改字典并写入新文件的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 问题内容: 我在从文件读取,处理其字符串并将其保存到UTF-8文件时遇到问题。 这是代码: 然后,我对可变文本进行一些处理。 接着 这样可以完美地输出文件,但是根据我的编辑器,它在iso 8859-15中可以输出。由于相同的编辑器将输入文件(在变量文件名中)识别为UTF-8,所以我不知道为什么会这样。据我的研究表明,注释行应该可以解决问题。但是,当我使用这些行时,产生的文件主要具有特殊字符的乱码,

  • 问题内容: 是否可以将JSON数据保存到本地文本文件中?因此,稍后我可以通过加载该文件再次使用它,并取回存储的JSON数据。其实我真正想做的是在文本文件中导出JSON数据,以便以后可以用作import.Any的建议或解决方案? 这是我要用于导出到文本的一些示例。 http://jsfiddle.net/k56eezxp/ 问题答案: 是否可以将JSON数据保存到本地文本文件中? 是。当前,链接的j

  • 问题内容: 我正在为Android设计一个手写应用程序。 每当用户按下Enter键时,我都希望将信息()写入日志文件。 之后,我想读取存储的信息。 这是我的类的一部分,带有自定义的write方法: 这是读取方法: 当我在文件中仅保存一个对象时,它会很好地工作。当我尝试节省更多时,阅读不起作用(抛出)。 它在while循环中仅读取一个对象! 在主类中,我仅使用两种简单的方法: 定义为: 请求的更新:

  • 下面是我的文本文件: 这是我的代码片段: 我得到以下异常: 我该怎么办?

  • 我正在编写一个文件编写器,它将ID和名称(这两个字符串)写入文本文件。这需要用户输入,然后将数据存储在txt文件中。但是,当我再次运行它时,任何新数据都会覆盖以前的数据,因此数据永远不会保存到txt文件中。 谁能告诉我如何保存这些数据,以便添加的任何新数据都存储在下一行,而不覆盖上一行? 谢啦