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

如何从.jar文件读取PDF

方博
2023-03-14

在我的maven项目中,我有一个PDF文件,它位于resources文件夹中。我的函数从资源文件夹读取PDF文件,并根据用户的数据在文档中添加一些值。

此项目使用mvn清洁安装打包为. jar文件,并在我的其他Spring Boot应用程序中用作依赖项。

在我的Spring启动项目中,我创建了将在PDF上执行一些工作的类的instace。一旦PDF文件上的所有工作都完成,并且当PDF文件保存在文件系统上时,它始终是空的(所有页面都是空白的)。我的印象是mvn干净安装对PDF文件做了一些事情。以下是我到目前为止尝试过的方法:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
File file= new ClassPathResource("/pdfs/testpdf.pdf").getFile();//Try to get PDF file

PDDocument pdf = PDDocument.load(file);//Load PDF document from the file
List<PDField> fields = forms.getFields();//Get input fields that I want to update in the PDF    
fieldsMap.forEach(throwingConsumerWrapper((field,value) -> changeField(fields,field,value)));//Set input field values

pdf.save(byteArrayOutputStream);//Save value to the byte array

这很好,但只要项目被打包到<code>中。jar文件,然后我得到了一个异常,即<code>新的类路径资源(“/pdfs/testpdf.pdf”)。getFile() 找不到指定的文件。

这是正常的,因为File类不能访问. jar文件中的任何内容(它只能访问. jar文件本身),这很清楚。

因此,该问题的解决方案是使用< code>InputStream而不是< code>File。我是这样做的:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
InputStream inputStream = new ClassPathResource("/pdfs/testpdf.pdf").getInputStream();//Try to get input stream

PDDocument pdf = PDDocument.load(inputStream );//Load PDF document from the input stream
List<PDField> fields = forms.getFields();//Get input fields that I want to update in the PDF    
fieldsMap.forEach(throwingConsumerWrapper((field,value) -> changeField(fields,field,value)));//Set input field values

pdf.save(byteArrayOutputStream);//Save value to the byte array

这次getInputStream()不会抛出错误,并且inputStream对象不是null。但是曾经保存在我的文件系统上的PDF文件是空的,这意味着所有页面都是空的。

我甚至尝试复制完整的 inputStream 并将其逐个字节保存到文件中,但我注意到每个字节都等于 0。以下是我所做的:

InputStream inputStream = new ClassPathResource("/pdfs/test.pdf").getInputStream();
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);

File targetFile = new File(OUTPUT_FOLDER);
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);

复制的< code>test.pdf会被保存,但当使用Adobe Reader打开时会被报告为损坏。

有人知道怎么修吗?

共有2个答案

太叔高义
2023-03-14

经过几个小时的调查和@Simon Martinelli和@Tilman Hausherr的良好投入,我有两个问题要解决:

为了从< code>resources文件夹中读取文件,您必须使用适当的类。如上所述,您不能使用< code>File类从< code >中读取文件。jar和我在我的例子中使用了下面的结构:

InputStream inputStream = CreatePDF.class.getResourceAsStream("/pdfs/test.pdf");
PDDocument pdf = PDDocument.load(inputStream);

在我的情况下CreatePDF类是静态的。如果您的类不是静态的,请使用以下内容:

InputStream inputStream = this.getClass().getResourceAsStream("/pdfs/test.pdf");
PDDocument pdf = PDDocument.load(inputStream);

我在问题的第三个示例中注意到的一件事是,当我将文件从资源逐个字节复制到我的本地文件夹时,所有字节都等于0。我知道这不可能是正确的,所以我尝试对简单的. txt文件做同样的事情,在这种情况下一切都正常工作。这意味着mvn清洁安装在PDF文件上引起了一些问题。经过一些调查,我意识到mvn过滤器导致了问题。如果启用了资源过滤器:

<resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
</resource>

然后您的二进制数据将被损坏,这是我最初的问题。当我将其设置为false时,它像预期的那样工作。

这是来自 maven 页面的警告:

警告:不要过滤包含图像等二进制内容的文件!这很可能导致输出损坏。

如果同时具有文本文件和二进制文件作为资源,则建议使用两个单独的文件夹。一个文件夹 src/main/resources(默认)用于未过滤的资源,另一个文件夹 src/main/resources-filter 用于过滤的资源。

以下是一个如何做到这一点的示例:

<resource>
    <directory>src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
        <include>**/*.txt</include>
        <include>**/*.html</include>
    </includes>
</resource>
<resource>
    <directory>src/main/resources</directory>
    <filtering>false</filtering>
    <includes>
        <include>**/*.pdf</include>
    </includes>
</resource>
卓云
2023-03-14

你必须像这样加载它:

InputStream inputStream = this.getClass().getClassloader().getResourceAsStream("/pdfs/testpdf.pdf");

如果您通过ClassLoader加载它,则路径从类路径的根开始。

 类似资料:
  • 问题内容: 我在JAR文件中有一个文件。这,例如。 我该如何访问?我的源代码是: 问题答案: 您不能使用File,因为此文件在文件系统上并不独立存在。相反,您需要getResourceAsStream(),如下所示:

  • 问题内容: 我正在尝试从作为桌面应用程序运行的单独jar中访问jar文件中的XML文件。我可以获取所需文件的URL,但是当我将其传递给FileReader(作为字符串)时,我得到了FileNotFoundException,上面写着“文件名,目录名或卷标语法不正确”。 作为参考,我毫不费力地从同一个jar中读取图像资源,并将URL传递给ImageIcon构造函数。这似乎表明我用来获取URL的方法是

  • 问题内容: 我想读取一个文件,该文件位于类路径中所包含的 之一内。我如何读取其中包含的任何文件? 问题答案: 如果要从应用程序内部读取该文件,请使用: 路径以“ /”开头,但这不是文件系统中的路径,而是类路径中的路径。因此,如果你的文件位于类路径“ org.xml”中,并且名为myxml.xml,则路径类似于“ /org/xml/myxml.xml”。 InputStream读取文件的内容。如果需

  • 问题内容: 我需要从文件中读取内容(它们都是变量,当然不是常量)。最简单的方法是什么? 问题答案: 这个怎么样:

  • 问题内容: 我需要使用bash从“ some.jar”中读取MANIFEST.MF Maven清单文件 问题答案: 将取消解压缩程序的详细输出 将提取到标准输出 例: 或者,您可以使用代替-。 -p将文件提取到管道(stdout)。除了文件数据外,什么都没有发送到stdout,并且文件总是以二进制格式提取,就像存储文件一样(不进行转换)。

  • 问题内容: 我想像这样从我的jar中读取资源: //Read the file 并且在Eclipse中运行它时效果很好,但是如果我将其导出到jar中运行,则会出现: 我真的不知道为什么,但是经过一些测试,我发现我是否改变了 至 然后它的作用相反(它在jar中起作用,但在Eclipse中不起作用)。 我正在使用Eclipse,并且包含我的文件的文件夹位于类文件夹中。 问题答案: 而不是尝试将资源作为