通过FreeMarker生成word文档及到处PDF文件
1.导出流程
本次PDF简历信息导出的处理流程可以简化为如下操作,下面会详细说明每一步的具体操作。
- 创建好导出用Word模板并转存为xml文件
- 用FreeMarker语法替换内容生成ftl模板
- 将生成的word上传到文件服务器,并返回地址Url给前端
- 前端通过url进行网页预览或导出PDF操作
2.创建Word模板、将word转存为xml文件
导出PDF文件自己总结以下两种方式:
第一种 Doc文件转换成PDF文件
第二种 Html转换成PDF文件
在考虑将所需要信息填充入过程中Doc或Html中时,发现可以通过FreeMarker将所需信息填充入Word模板中,考虑到后期有打印简历的需要,用word文档打印的效果会更好,所以本次考虑用word创建模板再转换成PDF文件。
FreeMarker是一款模板引擎:基于模板和要改变的数据,生成输出文本(Word、Html)的通用工具。它是一款简单的、专用语言,在模板中,我们只需专注如何显示数据,而在模板外专注于展示的数据。
3.生成ftl文件模板
3.1 格式化xml文档
通过网站https://www.bejson.com/otherformat/xml/对另存为生成的xml文件进行格式化,格式化能够是我们方便的看清楚文档的结构,以及做内容的替换。
3.2 进行模板内容的替换
maven包导入:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
对模板进行编辑,将我们需要替换的内容给替换上去,例如图片中姓名那块对应如下代码。
<w:tblPrEx>
<w:tblBorders>
<w:top w:val="none" w:color="auto" w:sz="0" w:space="0"/>
<w:left w:val="none" w:color="auto" w:sz="0" w:space="0"/>
<w:bottom w:val="none" w:color="auto" w:sz="0" w:space="0"/>
<w:right w:val="none" w:color="auto" w:sz="0" w:space="0"/>
<w:insideH w:val="none" w:color="auto" w:sz="0" w:space="0"/>
<w:insideV w:val="none" w:color="auto" w:sz="0" w:space="0"/>
</w:tblBorders>
<w:tblLayout w:type="fixed"/>
<w:tblCellMar>
<w:top w:w="0" w:type="dxa"/>
<w:left w:w="108" w:type="dxa"/>
<w:bottom w:w="0" w:type="dxa"/>
<w:right w:w="108" w:type="dxa"/>
</w:tblCellMar>
</w:tblPrEx>
<w:trPr>
<w:trHeight w:val="522" w:hRule="atLeast"/>
</w:trPr>
<w:tc>
<w:tcPr>
<w:tcW w:w="2590" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="left"/>
<w:rPr>
<w:rFonts w:ascii="Heiti SC Light" w:eastAsia="Heiti SC Light"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:ascii="Heiti SC Light" w:eastAsia="Heiti SC Light"/>
<w:color w:val="7F7F7F" w:themeColor="background1" w:themeShade="80"/>
</w:rPr>
<w:t>姓名:</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:ascii="Heiti SC Light" w:eastAsia="Heiti SC Light"/>
</w:rPr>
<w:t>xxxxxxxx</w:t>
</w:r>
</w:p>
</w:tc>
而我们需要做的是把xxxxxxxx替换成${name}的FreeMarker语法,这样在生成时,就会用name的值去替换xxxxxx这块内容了。在完成模板的修改后,将xml文件另存为ftl文件。
3.3 导入模板用到的FreeMarker语法:
3.3.1 文字内容替换: ${name} ,xml模板中图片会以base64储存,若需要替换图片只需${base64Pic}传入对应图片base64码即可。
3.3.2 if else 判断:
<#if isRelativesInCompany == "0" >
aaa
<#else>
bbb
</#if>
3.3.3 list集合遍历: <#list workList as work> 即会遍历集合,通过work.就可以将每次遍历出来的数据取出来。
<#list workInfo as work>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:ascii="Heiti SC Light" w:eastAsia="Heiti SC Light"/>
<w:color w:val="7F7F7F" w:themeColor="background1" w:themeShade="80"/>
</w:rPr>
<w:t>起止日期:</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:hint="eastAsia" w:ascii="Heiti SC Light" w:eastAsia="Heiti SC Light"/>
</w:rPr>
<w:t>${work.time}</w:t>
</w:r>
</#list>
3.3.4 判断list集合长度:<#if (workList?size == 0 )></#if>
3.3.5 判断list集合是否到达最后一条:<#if work_has_next></#if>
4.生成doc文件并上传到文件服务器
//1、生成template模板,一共有三种方式,我通过的是获取web项目上下文去获取
try {
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
configuration.setServletContextForTemplateLoading(session.getServletContext(),"/temp");
Template template = configuration.getTemplate("applicant.ftl"); //文件名
//本地创建空文件
String fileName = "outFile"+sdf.format(new Date())+(int)(Math.random()*100)+".doc";
File outFile = new File(fileName);
outFile.createNewFile();
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
//将内容写进创建的outFile文件中
template.process(hashMap, out);
//将生成的doc上传到文件服务器,并返回访问地址
filePath = UploadUtils.getDfsProductPath(outFile);
out.close();
//删除本地创建的文件
outFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
5.实现文档在线预览与PDF文件下载
在拿到生成后的doc文档后,接下来要做的便是将文件转换成PDF的问题了,于是百度、Google了一通发现大致的解决方法分为:
1.使用Jacob,但是使用jacob中要依赖Office,部分博文中还会依赖插件,如SaveAsPDFandXPS.exe。但是也发现不需要依赖Office,可以使用wps、pdfcreator,在使用wps的时候还不需要安装插件(注意:wps有linux版,office到现在为止还没有linux版)
2.OpenOffice,可以结合Jodconverter开源框架和OpenOffice.org办公软件,具有跨平台的优点,转化速度快,但是部分office的格式似乎不支持。
3.Adobe Acrobat + jacob,这个用到什么虚拟打印机,和微软的一起使用效果比较好。(这个我不太懂)
4.Jcom + Adobe Acrobat ,会用到IDispatch。 (这4段是拷贝的)
原本以为doc转pdf会很简单,没想到看似简单的功能却有大学问,在转换时要么会兼容性不好样式出现错乱,要么是跨平台兼容性问题,总之转换起来很麻烦。在纠结了许久后,偶然想到公司知识库有文档预览功能。发现预览功能是直接购买的外部服务,既然是RMB玩家,那就去该公司的官网去看,还真发现了有帮你将doc文件转成PDF的功能,美滋滋的我就直接拿来用了。(有的文件预览也有免费的体验版)可以实现的功能是
文件浏览器预览: http://xxxx/?i=您的网站ID&fname=简历预览&furl=要预览的Office文件下载地址
PDF下载:http://xxxx/?i=您的网站ID&fname=简历&furl=要预览的Office文件下载地址
6.最后总结:
看似很复杂的生成PDF文档功能,没想到在实际操作实现过程中并没有想象中那么复杂(除了word转PDF那块),通过FreeMarker的应用,能够轻松的实现word模板数据的填充,拿到我们需要的DOC的word文件。当然这个实现方法也有一个最大的弊端:每一次模板的改动,就需要重新FreeMarker去重新填充,这样操作起来会非常的机械,如果下次还有机会的话就去尝试用HTML生成PDF了。。。。。。