版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!html
這個方案只能在java中運行,沒法在Android項目中運行。因此此方案是:APP將表單數據發送給後臺,後臺經過freemarker將表單數據根據模板ftl文件生成Word文件,而後返回給APP,由APP進行展示。java
官網下載地址:https://freemarker.apache.org/freemarkerdownload.html數據庫
後續將freemarker.jar文件添加到項目中。apache
注意:服務器
例子:編輯器
對於Word2016,另存爲後會自動打開xml文件,因此須要先關閉xml文件,而後再使用FirstObject XML Editor軟件打開xml文件!ide
下載FirstObject XML Editor軟件(免安裝版):下載地址:http://www.firstobject.com/dn_editor.htm測試
官網下載的軟件打開文件的時候可能會出現崩潰的問題。建議使用foxe_CHS.exe軟件進行編輯。下載地址見項目Demo下載地址。this
首先進行「縮進排版」編碼
查找真實數據,替換成FreeMarker標記,其實就是Map<String, Object>中key,如${writeDate},對應Map的key值就是writeDate。
替換成:
對於文本按照上面的方式進行替換,而對於圖片須要這樣替換:
圖片是以base64編碼存在的,且這些編碼放在<w:binData>標籤之中。將這些base64編碼使用佔位符代替,而後java代碼中將圖片生成base64編碼,傳入值就能正常顯示了。
替換成
注意:必定不要用word打開ftl模板文件查看,不然xml內容會發生變化,致使前面的工做白作了;可使用EditPlus打開查看。
package com.why.main; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.HashMap; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import sun.misc.BASE64Encoder; /** * 生成Doc文檔 */ public class DocumentHandler { //測試 public static void main(String[] args) { DocumentHandler documentHandler = new DocumentHandler(); documentHandler.createDoc(); } // 配置實例:只須要一個實例(單例模式) private Configuration configuration = null; private String tempDirPath = "D:/temp"; public DocumentHandler() { // 經過Freemaker的Configuration讀取相應的ftl configuration = new Configuration(Configuration.VERSION_2_3_28); configuration.setDefaultEncoding("UTF-8");// 設置默認編碼方式 } /** * 生成DOC文檔 */ public void createDoc() { // 要填入模本的數據文件 Map<String,Object> dataMap = new HashMap<String,Object>(); getData(dataMap); // 設置模本裝置方法和路徑,FreeMarker支持多種模板裝載方法。能夠重servlet,classpath,數據庫裝載, // 若是模板是放在程序代碼的包下面 //configuration.setClassForTemplateLoading(this.getClass(),"../"); //若是放到服務器目錄中,則使用下面的代碼 try { configuration.setDirectoryForTemplateLoading(new File(tempDirPath)); } catch (IOException e2) { e2.printStackTrace(); } //這裏要設置取消使用Local語言環境 configuration.setLocalizedLookup(false); Template template = null; try { // leaveTemplet.ftl爲要裝載的模板 template = configuration.getTemplate("leaveTemplet.ftl","UTF-8"); } catch (IOException e) { e.printStackTrace(); } // 輸出文檔路徑及名稱 File dir = new File(tempDirPath); File outFile = new File(tempDirPath + "/請假條.doc"); if (!dir.isDirectory()) { dir.mkdir(); if (!outFile.exists()) { try { outFile.createNewFile(); } catch (IOException e) { System.out.println("建立文件失敗"); e.printStackTrace(); } } } Writer out = null; try { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } catch (FileNotFoundException e1) { System.out.println("輸出文件失敗"); e1.printStackTrace(); } try { template.process(dataMap, out); System.out.println("it's success!"); } catch (TemplateException e) { System.out.println("生成失敗"); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 注意dataMap裏存放的數據Key值要與模板中的參數相對應 */ private void getData(Map<String,Object> dataMap) { String imgBase64Str = getImageStr(tempDirPath + "/leaderopinion_img.png"); // 使用String的有參構造方法 dataMap.put("writeDate","2018年10月13日");//填寫日期 dataMap.put("name","HaiyuKing");//姓名 dataMap.put("dept","移動組");//部門 dataMap.put("leaveType","☑倒休 √年假 ✔事假 ☐病假 ☐婚假 ☐產假 ☐其餘");//請假類型 dataMap.put("leaveReason","倒休休息兩天");//請假理由 dataMap.put("leaveStartDate","2018年10月13日上午");//請假開始日期 dataMap.put("leaveEndDate","2018年10月14日下午");//請假結束日期 dataMap.put("leaveDay","2");//請假天數 dataMap.put("leaveLeader","贊成");//直屬領導意見 dataMap.put("leaveDeptLeaderImg",imgBase64Str);//部門領導意見 } /** * 獲取圖片的base64值*/ private String getImageStr(String imgFile) { InputStream in = null; byte[] data = null; try { in = new FileInputStream(imgFile); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data); } }
注意:Map數據中的key值,對應ftl文件中的${xxxx}這裏面的xxxx值。
一、不要使用英文;
二、若是想要保證一個總體,不要將中文、數字、標點符號一塊兒使用(這裏指佔位區域);
三、日期想要做爲一個總體,不要數字+中文輸入,而是經過Enter鍵輸入;
下面記錄的是不一樣輸入的效果(使用FirstObject XML Editor軟件打開xml文件)
使用英文:
使用數字:
使用中文:
日期採用數字+中文:
日期採用Enter鍵輸入:
中文+標點符號:
沫沫金:使用Java模版引擎FreeMarker生成複雜的Word文檔
FreeMaker解析Word模板(含圖片)生成Word文檔
連接:https://pan.baidu.com/s/19aPNIYWXt5GMN_KDQjFCRA 提取碼:eo0n