Java实现Word转PDF【完整版】
前言:
最近也是在非常紧急的准备暑期实习的面试,一边学习一边修补简历,因为之前看到某位大佬的帖子说建议投递的简历形式为PDF
,这一下可是把我难死了,索性就可以在网上找寻各种方法,逛了一圈回来发现,网上特别多的这种帮助制作简历的平台,但是都没有把word
文档转为PDF
的,所以我必须重新在平台上重新输入一遍自己的信息然后再由平台进行制作,但是问题又出现了,部分信息我并不想填,但是不填平台不允许进行下一项的填写,很是令人头疼。经过这么一倒腾,就想着能不能利用自己学的技术做一个简历制作并且还是最终还可以PDF
的形式输出呢?
🏡 博客首页:派 大 星
⛳️ 欢迎关注 🐳 点赞 🎒 收藏 ✏️ 留言
🎢 本文由派大星原创编撰
🚧 系列专栏:项目从0搭建
🎈 本系列项目从设计到实现源码全部开源免费学习使用,一起追向理想,欢迎各位大佬监督打卡开发!
@TOC
🍇 难度分析
Aspose
提供了详细的官方文档,并且库中提供了Document
对象将现有的文档加载到任何格式,将文件名或流传递到该对象的构造函数(构造函数详情具体见下表)
中,但是在生成之前自己需要先创建一个Doc
的空白文档,类似于在SpringBoot
时操作的Thymeleaf
类似,使用模板来将数据在生成的PDF
中进行渲染,在官方的文档中也是很暖心的提供了代码的示例供使用者参考以及类库中的各种Api
方法可以说是非常贴心,通过研究文档,发现该类库不仅支持Word
格式,以及xml、HTML
等格式也是提供了特定的Api
供使用,而且对于编程语言也是支持多种比如:Java、C++等
。
Document构造函数详情 |
---|
Document() 创建一个空白 Word 文档。 |
Document(java.lang.StringfileName) 从文件中打开现有文档。自动检测文件格式。 |
Document(java.lang.StringfileName, LoadOptions loadOptions) 从文件中打开现有文档。允许指定其他选项,例如加密密码。 |
Document(java.io.InputStreamstream, LoadOptions loadOptions) 从流中打开现有文档。允许指定其他选项,例如加密密码。 |
🍓 项目回顾(Aspose)
🍒 最终效果演示
🥝 技术选型:
- 🥥 SpringBoot
- 🥭 Swagger
- 🌽 Aspose
🥕 项目需求分析
仿照超级简历模式进行简历制作,用户只需要填写自己想要填充的信息即可生成属于自己的PDF
版简历,不需要再先使用Word
填充随后再更改为PDF
格式,减少了冗余操作,而且并不会限制用户输入某一部分信息后才能输入下一项信息的需求。
🍣 项目搭建
1. 进入Aspose官网
在官网中向开发者提供了友好功能介绍,包括代码示例以及类库中的所有的方法解释,并且官方提供了不同标准的PDF
转换方式来支持将Doc或Docx
转换为PDF
格式。
总结下来,Aspose
类库还是很强大的,当然Aspose
类库包含的功能不止是word转PDF
,其他的方法更值得研究一番,这里就只简单介绍并演示一下word转PDF
。
2. 搭建项目
①创建Maven项目
引入Aspose
相关以及部分使用依赖,这里使用的是离线SDK
,因为使用Aspose
转换格式后在生成PDF
会有特别大的水印,观感并不是很好。下载离线SDK可以进行一些细微的小操作(🐶保命 )
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>aspose-words-19.5jdk.jar</version>
<scope>system</scope>
<systemPath>${pom.basedir}/libs/aspose-words-19.5jdk.jar</systemPath>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
② 编写配置文件
由于只是一个小案例,不需要配置特别多的东西,只需要设置启动的端口即可!
server:
port: 8080
③ 对上述介绍Aspose类库进行方法封装
/**
* Word转PDF操作
*
* @param doc 源文件
* @param targetFile 目标文件
*/
public static void doc2pdf(Document doc, String targetFile) {
try {
long old = System.currentTimeMillis();
//新建一个空白pdf文档
File file = new File(targetFile);
FileOutputStream os = new FileOutputStream(file);
//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, SaveFormat.PDF);
os.close();
long now = System.currentTimeMillis();
//转化用时
System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
} catch (Exception e) {
e.printStackTrace();
}
}
注:如想了解小操作请移步Gitee仓库
④ 配置Swagger配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.pdx.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("Java生成PDF")
.description("Java生成PDF")
.termsOfServiceUrl("")
.version("1.0")
.build();
}
}
注:需要注意的是@EnableSwagger2
注解不能省略以及忽视,否则Swagger文档
不可使用
⑤ 编写Controller前端控制器代码
首先创建一个GeneratorPDFContrller
@PostMapping("/generatorPdf")
@ApiOperation(value = "Java生成PDF")
public String generatorPdf(HttpServletRequest request, @RequestBody PDFVo vo) throws Exception {
pdfService.generatorPdf(request,vo);
return JSON.toJSONString("ok") ;
}
⑥ 具体实现格式转换业务
public void generatorPdf(HttpServletRequest request, PDFVo vo) throws Exception {
File directory = new File("");
String canonicalPath = directory.getCanonicalPath();
String path = canonicalPath+"/src/main/resources/templates/single.docx";
Document firstDocument = null;
String start = "2019-9-1";
String end = "2023-6-30";
Document document = new Document(path);
Range range = document.getRange();
//使用参数替换
range.replace("username",vo.getUsername(),new FindReplaceOptions());
range.replace("school",vo.getSchool(),new FindReplaceOptions());
range.replace("age",String.valueOf(vo.getAge()),new FindReplaceOptions());
range.replace("phone",vo.getPhone(),new FindReplaceOptions());
range.replace("email",vo.getEmail(),new FindReplaceOptions());
range.replace("sex",vo.getSex(),new FindReplaceOptions());
range.replace("nation",vo.getNation(),new FindReplaceOptions());
range.replace("education",vo.getEducation(),new FindReplaceOptions());
range.replace("major",vo.getMajor(),new FindReplaceOptions());
range.replace("start",start,new FindReplaceOptions());
range.replace("end",end,new FindReplaceOptions());
if (firstDocument == null){
firstDocument = document;
}else {
//添加文档
firstDocument.appendDocument(document, ImportFormatMode.KEEP_DIFFERENT_STYLES);
}
//生成路径
String url = System.getProperty("user.dir")+"/upload/";
isFolderExists(url);
String date = DateFormatUtils.dateRotation();
AsposeWordsUtils.doc2pdf(firstDocument,url+date+".pdf");
}
🌶 前提
需要在启动项目前准备一个Docx
格式的模板,程序读取模板并将数据渲染进去:如下图:
❗ ❗注意 ❗ ❗
在创建项目时需要注意版本控制,如果太高或太低就会出现一些恶心的报错信息,下面列举几个我遇到的 ❌
No.1:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpPutFormContentFilter' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter]: Factory method 'httpPutFormContentFilter' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.ObjectMapper
No.2:
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase
at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[?:1.8.0_202]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_202]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[?:1.8.0_202]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_202]
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_202]
at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_202]
解决方案:
首先将SpringBoot版本降或升
到2.3.2.RELEASE
然后直接将下面的依赖导入即可!
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
🥦 生成PDF最终结果:
由最终结果来看,效果还是可以的。
⭐️ 案例总结
使用Aspose
类库进行实现格式的转换,由最终结果来看还是可以的,达到了初期预想的效果。但是Aspose
类库的作用不仅仅如此,还有很多很强大的功能还未探索。根据这个小案例我又想着是不是可以做一个简历生成的平台来供需要的同学来学习(哈哈哈,现在很成熟的网站很多比如:超级简历、智联招聘等等很多)
,那么他们的后端是否和我做的小案例逻辑差不多呢?
新鲜出炉的代码将会及时更新到Gitee
仓库
以上代码属于部分实现,想要了解完整版请移步派大星的Gitee仓库
❗️❗️❗️让好奇心促使技术的成长❗️❗️❗️
- 点赞
- 收藏
- 关注作者
评论(0)