最近碰到个问题,就是项目打包成jar包运行无法访问resources里的资源。jar包运行时引用的第三方jar包也无法加载。
就是我需要实现一个导出成pdf或者word文档的功能,导出这两种文档是根据模板来导出。先准备好了pdf和word的模板,导出时将数据内容填充到模板中,然后再将填写好内容的pdf或word文档下载下来。
这两种模板我是放在 resources 目录下 template 文件夹里
读取模板时,我是用 ClassLoader.getSystemResource(“template”).getPath() 来读取的,具体代码如下:
/**
* @param dataMap 导出数据
* @param templateName 模板名称
* @param path 导出word的路径以及文件名称
* 通过模板导出word格式文件
* */
public static void exportWord(Map<String,Object> dataMap,String templateName,String path) throws IOException, TemplateException {
//Configuration 用于读取ftl文件
Configuration configuration = new Configuration(new Version("2.3.0"));
configuration.setDefaultEncoding("utf-8");
/**
* 以下是两种指定ftl文件所在目录路径的方式,注意这两种方式都是
* 指定ftl文件所在目录的路径,而不是ftl文件的路径
*/
configuration.setDirectoryForTemplateLoading(new File(ClassLoader.getSystemResource("template").getPath()));
System.out.println("模板路径=====>>>>>>>>>>>"+new File(ClassLoader.getSystemResource("template").getPath()));
//输出文档路径及名称
File outFile = new File(path);
//以utf-8的编码读取ftl文件
Template template = configuration.getTemplate(templateName, "utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);
template.process(dataMap, out);
out.close();
}
以上代码读取模板,在本地运行的时候是没有问题,但是把这个项目打包成jar包后,部署到服务器运行,导出word或pdf文件的时候,就报错了,看错误信息,是 configuration.setDirectoryForTemplateLoading(new File(ClassLoader.getSystemResource(“template”).getPath())); 这一句报错了。
其实就是 ClassLoader.getSystemResource(“template”).getPath() 这里获取模板路径的时候没有获取到,为null,所以报错了,然后我换了种方法获取路径,根据某个类的相对路径来获取:
//这里要注意前面要加“/”,即"/template",如果直接用 "template" 也是获取不到的
configuration.setClassForTemplateLoading(this.getClass(),"/template");
改好之后果然可以了,然鹅并没结束,这里我导出word是没问题了,可是我导出pdf还是有问题。
因为我这里导出成pdf是先将数据填写到word模板中,然后再将这个模板转为pdf进行下载。
word转pdf就用到了一个第三方jar包,aspose-words-15.8.0.jar
用这个jar包,将word转为pdf,在pom.xml中需要配置:
<!--引入word转pdf jar包-->
<dependency>
<groupId>aspose</groupId>
<artifactId>words</artifactId>
<version>15.8.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/jar/aspose-words-15.8.0.jar</systemPath>
</dependency>
这样在本地运行是没有问题的,但是打包成jar运行就不行,后面找了半天终于找到解决办法,在pom.xml打包成jar的配置中,加上 < includeSystemScope>true</ includeSystemScope> 这句即可:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
这样就大功告成,打包jar,运行,导出word和pdf都没问题。
关于引用的第三方jar包,其实也可以将第三方jar包导入到本地的maven仓库,在pom里引入的时候,像引入其他依赖一样就可以了,在将项目打包成jar包的时候,pom里面也不用配置 < includeSystemScope>true</ includeSystemScope> 了
第三方外部jar包转成maven本地仓库的jar包
打开cmd,输入以下命令,就可以将外部jar包转到maven本地仓库,然后引入的时候,像其他依赖一样引入就行,打包也会像其他依赖一样一起打包。
mvn install:install-file -Dfile=C:\Users\Admin\Desktop\aspose-words-16.8.0.jar -DgroupId=aspose -DartifactId=words -Dversion=16.8.0 -Dpackaging=jar
-Dfile=C:\Users\Admin\Desktop\aspose-words-16.8.0.jar 这里是外部jar包存放的路径。
<!--引入word转pdf jar包-->
<dependency>
<groupId>aspose</groupId>
<artifactId>words</artifactId>
<version>16.8.0</version>
</dependency>
这里用到的 aspose-words-16.8.0.jar 包,我放在 这里 了,提取码是 3hwy,需要的自行下载。