1. 程式人生 > >word模板動態填充並下載

word模板動態填充並下載

需求:java生成word
通常首先會想到iText和POI,這是因為我們習慣了使用這兩種方法操作Excel,自然而然的也想使用這種生成word文件。但是當我們需要動態生成word時,通常不僅要能夠顯示word中的內容,還要能夠很好的保持word中的複雜樣式。這時如果再使用IText和POI去操作,就好比程式設計師去搬磚一樣痛苦。
實現思路_
  這時候,我們應該考慮使用FreeMarker的模板技術快速實現這個複雜的功能,讓程式設計師在喝咖啡的過程中就把問題解決。實現思路是這樣的:先建立一個word文件,按照需求在word中填好一個模板,然後把對應的資料換成變數${},然後將文件儲存為xml文件格式,使用文件編輯器開啟這個xml格式的文件,去掉多餘的xml符號,使用Freemarker讀取這個文件然後替換掉變數,輸出word文件即可。
1.1 需要的jar包
在這裡插入圖片描述


1.2 xml模板轉為doc檔案的工具類

	備註:此工具類使用了單利模式
	這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
	意圖:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

    主要解決:一個全域性使用的類頻繁地建立與銷燬。
    
    何時使用:當您想控制例項數目,節省系統資源的時候。
    
    如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則建立。
        
    優點: 
    1、在記憶體裡只有一個例項,減少了記憶體的開銷,尤其是頻繁的建立和銷燬例項(比如管理學院首頁頁面快取)。
    2、避免對資源的多重佔用(比如寫檔案操作)。
    缺點:沒有介面,不能繼承,與單一職責原則衝突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來例項化。
  
         * 根據word模板列印檔案工具類__
         * 雙檢鎖/雙重校驗鎖__這種方式採用雙鎖機制,安全且在多執行緒情況下能保持高效能。
         */

  public class DocUtil {
    private volatile static DocUtil docUtil;
    private Configuration configure = null;
    
    private DocUtil() {
        configure = new Configuration();
        configure.setDefaultEncoding("utf-8");
    }
    
    public static DocUtil getSingleton() {
        if (docUtil == null) {
            synchronized (DocUtil.class) {
                if (docUtil == null) {
                    docUtil = new DocUtil();
                }
            }
        }
        return docUtil;
    }
    /**
     * 根據Doc模板生成word檔案
     *
     * @param dataMap      需要替換的資料 key__value
     * @param downloadType 模板名稱
     * @param savePath     儲存路徑
     */
    public void createDoc(Map<String, Object> dataMap, String downloadType, String savePath) {
        try {
            //載入需要裝填的模板
            Template template = null;
            //載入模板檔案
            configure.setClassForTemplateLoading(this.getClass(), "/com/sgcc/fsp/manage/web/templates");
            //設定物件包裝器
            configure.setObjectWrapper(new DefaultObjectWrapper());
            //設定異常處理器
            configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
            //定義Template物件,注意模板型別名字與downloadType要一致
            template = configure.getTemplate(downloadType + ".xml");
            //輸出文件
            File outFile = new File(savePath);
            Writer out = null;
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
            template.process(dataMap, out);
            outFile.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 獲取付款列印的doc文件__
     */
    public static void getPaymentDoc(Map<String, Object> dataMap, String savePath) {
        DocUtil docUtil = DocUtil.getSingleton();
        //找到對應模板、替換變數值__
        docUtil.createDoc(dataMap, "paymentApproval", savePath);
    }
    
    public static void main(String[] args) {
        DocUtil docUtil = DocUtil.getSingleton();
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("year", "2018");
        dataMap.put("month", "11");
        dataMap.put("day", "22");
        dataMap.put("businessName", "遠東國際");
        dataMap.put("businessGroupLeader", "薛勝東");
        dataMap.put("applicant", "趙遠東");
        docUtil.createDoc(dataMap, "paymentApproval", "H:/outFile.doc");
    }
    }

單例模式文件___
http://www.runoob.com/design-pattern/singleton-pattern.html