通過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了。。。。。。