定制软件开发Java实现Word转PDF【完整版】

前言:

定制软件开发最近也是在非常紧急的定制软件开发准备暑期实习的面试,定制软件开发一边学习一边修补简历,定制软件开发因为之前看到某位大佬定制软件开发的帖子说建议投递的简历形式为PDF,定制软件开发这一下可是把我难死了,定制软件开发索性就可以在网上找寻各种方法,定制软件开发逛了一圈回来发现,定制软件开发网上特别多的这种帮助定制软件开发制作简历的平台,定制软件开发但是都没有把word文档转为PDF的,定制软件开发所以我必须重新在平台上重新输入一遍自己的信息然后再由平台进行制作,但是问题又出现了,部分信息我并不想填,但是不填平台不允许进行下一项的填写,很是令人头疼。经过这么一倒腾,就想着能不能利用自己学的技术做一个简历制作并且还是最终还可以PDF的形式输出呢?

🏡  博客首页:派 大 星

⛳️  欢迎关注  ❤️ 点赞  🎒 收藏  ✏️ 留言

🎢  本文由派大星原创编撰

🚧  系列专栏:项目从0搭建

🎈  本系列项目从设计到实现源码全部开源免费学习使用,一起追向理想,欢迎各位大佬监督打卡开发!



文章目录

🍇  难度分析

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
② 编写配置文件

由于只是一个小案例,不需要配置特别多的东西,只需要设置启动的端口即可!

server:  port: 8080
  • 1
  • 2
③ 对上述介绍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();        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

注:如想了解小操作请移步Gitee仓库

④ 配置Swagger配置类
@Configuration@EnableSwagger2public 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();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

注:需要注意的是@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") ;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
⑥ 具体实现格式转换业务
    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");    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

🌶  前提

需要在启动项目前准备一个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
  • 1

No.2:

Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.ser.std.ToStringSerializerBaseat 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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解决方案:

首先将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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

🥦  生成PDF最终结果:

由最终结果来看,效果还是可以的。

⭐️  案例总结

使用Aspose类库进行实现格式的转换,由最终结果来看还是可以的,达到了初期预想的效果。但是Aspose类库的作用不仅仅如此,还有很多很强大的功能还未探索。根据这个小案例我又想着是不是可以做一个简历生成的平台来供需要的同学来学习(哈哈哈,现在很成熟的网站很多比如:超级简历、智联招聘等等很多),那么他们的后端是否和我做的小案例逻辑差不多呢?

新鲜出炉的代码将会及时更新到Gitee仓库

以上代码属于部分实现,想要了解完整版请移步

❗️❗️❗️让好奇心促使技术的成长❗️❗️❗️

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发