使用Java生成word文檔(附源碼)


當我們使用Java生成word文檔時,通常首先會想到iTextPOI,這是因為我們習慣了使用這兩種方法操作Excel,自然而然的也想使用這種生成word文檔。但是當我們需要動態生成word時,通常不僅要能夠顯示word中的內容,還要能夠很好的保持word中的復雜樣式。這時如果再使用ITextPOI去操作,就好比程序員去搬磚一樣痛苦。

 

  這時候,我們應該考慮使用FreeMarker的模板技術快速實現這個復雜的功能,讓程序員在喝咖啡的過程中就把問題解決。實現思路是這樣的:先創建一個word文檔,按照需求在word中填好一個模板,然后把對應的數據換成變量${},然后將文檔保存為xml文檔格式,使用文檔編輯器打開這個xml格式的文檔,去掉多余的xml符號,使用Freemarker讀取這個文檔然后替換掉變量,輸出word文檔即可。

  具體過程如下:

  1.創建帶有格式的word文檔,將該需要動態展示的數據使用變量符替換。

 

140726908.png

2. 將剛剛創建的word文檔另存為xml格式。

140752129.png

 

3編輯這個XMl文檔去掉多余的xml標記,如圖中藍色部分

 

140826202.png

 

 

  4.從Freemarker官網【下載】最新的開發包,將freemarker.jar拷貝到自己的開發項目中。

  5.新建DocUtil類,實現根據Doc模板生成word文件的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.favccxx.secret.util;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
public class DocUtil {
        privateConfiguration configure = null ;
        publicDocUtil(){
               configure= new Configuration();
               configure.setDefaultEncoding( "utf-8" );
        }
        /**
         * 根據Doc模板生成word文件
         * @param dataMap Map 需要填入模板的數據
         * @param fileName 文件名稱
         * @param savePath 保存路徑
         */
        publicvoid createDoc(Map<String, Object> dataMap, String downloadType, StringsavePath){
               try {
                      //加載需要裝填的模板
                      Templatetemplate  = null ;
                      //加載模板文件
                      configure.setClassForTemplateLoading( this .getClass(), "/com/favccxx/secret/templates" );
                      //設置對象包裝器
                      configure.setObjectWrapper(newDefaultObjectWrapper());
                      //設置異常處理器
                      configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
                      //定義Template對象,注意模板類型名字與downloadType要一致
                      template= configure.getTemplate(downloadType + ".xml" );
                      //輸出文檔
                      FileoutFile = new File(savePath);
                      Writerout = null ;
                      out= new BufferedWriter( new OutputStreamWriter( new FileOutputStream(outFile), "utf-8" ));                                   
                      template.process(dataMap,out);
                      outFile.delete();
               } catch (Exception e) {
                      e.printStackTrace();
               }
        }
}

  6.用戶根據自己的需要,調用使用getDataMap獲取需要傳遞的變量,然后調用createDoc方法生成所需要的文檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
  * 根據下載類型獲取需要傳遞的Map參數
  * @param oid 對象Id
  * @param downloadType 下載類型
  */
private Map<String, Object> getDataMap(String oid,String downloadType){
     Map<String, Object> dataMap = new HashMap<String, Object>();
     if ( "Parameter1" .equals(downloadType)){
         ...
         ...
         dataMap = DataMapUtil.setObjToMap(Object1);
     } else {
         ...
         ...
         dataMap = DataMapUtil.setObjToMap(Object2);
     }
     return dataMap;
}

  

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class DataMapUtil {
       
     private static Map<String, Object> dataMap = new HashMap<String, Object>();
       
     /**
      * 將對象轉換成Map
      * @param obj 對象類
      * @return
      */
     public static Map<String,Object> setObjToMap(Object obj){
         Class c;
         try {
             c = Class.forName(obj.getClass().getName());
             Method[] methods = c.getMethods();
             for ( int i= 0 ,l=methods.length;i<l;i++){
                 String method = methods[i].getName();
                 System.out.println( "The method is:" + method);
                 if (method.startsWith( "get" )){
                     Object value = methods[i].invoke(obj);
                     if (value != null ){
                         if (value.getClass().getClassLoader() != null ){  //處理自定義的對象類型
                             setObjToMap(value);
                         }
                         String key = method.substring( 3 );
                         key = key.substring( 0 , 1 ).toLowerCase() + key.substring( 1 );
                         if ( "java.util.Date" .equals(value.getClass().getName())){
                             value = DateUtil.dateToString((Date)value);
                         }
                         dataMap.put(key, value);
                     }
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
         }
         return dataMap;
     }
}

 

  7.趕緊把這個方法,應用到自己的項目中吧。

本文出自 “這個人的IT世界” 博客,請務必保留此出處http://favccxx.blog.51cto.com/2890523/1331115

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM