在項目中使用它完成的功能是按照固定的模板將數據導出到Word。比如台賬。在完成后將處理過程按照台賬的要求導出,有時程序中需要實現生成標准Word文檔,要求能夠打印,並且保持頁面樣式不變。
這個功能就是由XML+Freemarder來實現的,Word從2003開始支持XML格式,大致的步驟:用office2003或者以上的版本編輯 好 word的樣式,然后另存為xml,將xml翻譯為FreeMarker模板,最后用java來解析FreeMarker模板並輸出Doc。
一、模板的制作
先用Word做一個模板,如下圖:
然后另存為XML文件,可以利用高亮顯示的notepad++打開xml,主要是有高亮顯示,和元素自動配對
也可以用foxe_CHS打開xml,是一個簡潔、快速的 XML 編輯器,還提供F8對齊排版功能。
保存后,修改后綴名為ftl,至此模板制作完畢。
二、編程實現
首先引入freemarker的開源包
1 import freemarker.template.Configuration; 2 import freemarker.template.Template; 3 import freemarker.template.TemplateException;
編寫java類,主要實現對模板的賦值以及生成流,用於導出。
1 package com.test.freemarker.report; 2 import java.io.BufferedWriter; 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.OutputStreamWriter; 7 import java.io.Writer; 8 import java.util.HashMap; 9 import java.util.Map; 10 import freemarker.template.Configuration; 11 import freemarker.template.Template; 12 import freemarker.template.TemplateException; 13 14 public class DocumentHandler { 15 private Configuration configuration = null; 16 17 public DocumentHandler() { 18 configuration = new Configuration(); 19 configuration.setDefaultEncoding("utf-8"); 20 } 21 22 public void createDoc() { 23 // 要填入模本的數據文件 24 Map dataMap = new HashMap(); 25 getData(dataMap); 26 // 設置模本裝置方法和路徑,FreeMarker支持多種模板裝載方法。可以重servlet,classpath,數據庫裝載, 27 // 這里我們的模板是放在com.havenliu.document.template包下面 28 configuration.setClassForTemplateLoading(this.getClass(), "/com/test/freemarker/report"); 29 Template t = null; 30 try { 31 // test.ftl為要裝載的模板 32 t = configuration.getTemplate("test.ftl"); 33 t.setEncoding("utf-8"); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 // 輸出文檔路徑及名稱 38 File outFile = new File("D:/test.doc"); 39 Writer out = null; 40 try { 41 FileOutputStream fos = new FileOutputStream(outFile); 42 OutputStreamWriter oWriter = new OutputStreamWriter( 43 fos,"UTF-8");//這個地方對流的編碼不可或缺,使用main()單獨調用時,應該可以,但是如果是web請求導出時導出后word文檔就會打不開,並且包XML文件錯誤。主要是編碼格式不正確,無法解析。 44 out = new BufferedWriter(oWriter); 45 /** out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8")); **/ 46 } catch (Exception e1) { 47 e1.printStackTrace(); 48 } 49 try { 50 t.process(dataMap, out); 51 out.close(); 52 } catch (TemplateException e) { 53 e.printStackTrace(); 54 } catch (IOException e) { 55 e.printStackTrace(); 56 } 57 } 58 59 /** 60 * 注意dataMap里存放的數據Key值要與模板中的參數相對應 61 * @param dataMap 62 */ 63 private void getData(Map dataMap) { 64 dataMap.put("title_name", "用戶信息"); 65 dataMap.put("user_name", "張三"); 66 dataMap.put("org_name", "微軟公司"); 67 dataMap.put("dept_name", "事業部"); 68 } 69 }
三、生成的Word結果如下:
對於復雜的報表樣式可以在Word中編輯后保存,如果需要輸出列表類型數據可以參考Freemarker的循環或邏輯控制。
四、總結
這個工具生成word確實很方便,但是還是有些不足的地方,FreeMarker三宗罪->http://www.iteye.com/topic/17468
轉載自:http://blog.csdn.net/xiexl/article/details/6747767