Java实现Word转PDF【完整版】

举报
派 大 星 发表于 2022/07/26 11:33:47 2022/07/26
【摘要】 最近也是在非常紧急的准备暑期实习的面试,一边学习一边修补简历,因为之前看到某位大佬的帖子说建议投递的简历形式为`PDF`,这一下可是把我难死了,索性就可以在网上找寻各种方法,逛了一圈回来发现,网上特别多的这种帮助制作简历的平台,但是都没有把`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官网

Aspose的Word转PDF文档地址

在官网中向开发者提供了友好功能介绍,包括代码示例以及类库中的所有的方法解释,并且官方提供了不同标准的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仓库

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

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。