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

當咱們使用Java生成word文檔時,一般首先會想到iTextPOI,這是由於咱們習慣了使用這兩種方法操做Excel,天然而然的也想使用這種生成word文檔。可是當咱們須要動態生成word時,一般不只要可以顯示word中的內容,還要可以很好的保持word中的複雜樣式。這時若是再使用ITextPOI去操做,就比如程序員去搬磚同樣痛苦。java

 

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

  具體過程以下:app

  1.建立帶有格式的word文檔,將該須要動態展現的數據使用變量符替換。編輯器

 

140726908.png

2. 將剛剛建立的word文檔另存爲xml格式。this

140752129.png

 

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

 

140826202.png

 

 

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

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

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方法生成所須要的文檔。xml

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

相關文章
相關標籤/搜索