Java 根據模板動態生成word文件


最近項目中需要根據模板生成word文檔,模板文件也是word文檔。當時思考一下想用POI API來做,但是覺得用起來相對復雜。后來又找了一種方式,使用freemarker模板生成word文件,經過嘗試覺得還是相對簡單易行的。

使用freemarker模板生成word文檔主要有這么幾個步驟

1、創建word模板:因為我項目中用到的模板本身是word,所以我就直接編輯word文檔轉成freemarker(.ftl)格式的。

 

2、將改word文件另存為xml格式,注意使用另存為,不是直接修改擴展名。

3、將xml文件的擴展名改為ftl

4、編寫java代碼完成導出

使用到的jarfreemarker.jar (2.3.28) ,其中Configuration對象不推薦直接new Configuration(),仔細看Configuration.class文件會發現,推薦的是 Configuration(Version incompatibleImprovements) 這個構造方法,具體這個構造方法里面傳的就是Version版本類,而且版本號不能低於2.3.0

閑言碎語不再講,直接上代碼

 1 public static void exportDoc() {
 2         String picturePath = "D:/image.png";
 3         Map<String, Object> dataMap = new HashMap<String, Object>();
 4         dataMap.put("brand", "海爾");
 5         dataMap.put("store_name", "海爾天津");
 6         dataMap.put("user_name", "小明");
 7 
 8         //經過編碼后的圖片路徑
 9         String image = getWatermarkImage(picturePath);
10         dataMap.put("image", image);
11 
12         //Configuration用於讀取ftl文件
13         Configuration configuration = new Configuration(new Version("2.3.0"));
14         configuration.setDefaultEncoding("utf-8");
15 
16         Writer out = null;
17         try {
18             //輸出文檔路徑及名稱
19             File outFile = new File("D:/導出優惠證明.doc");
20             out = new BufferedWriter(new OutputStreamWriter(new 
21             FileOutputStream(new File("outFile")), "utf-8"), 10240);
22         } catch (UnsupportedEncodingException e) {
23             e.printStackTrace();
24         } catch (FileNotFoundException e) {
25             e.printStackTrace();
26         }
27         // 加載文檔模板
28         Template template = null;
29         try {
30             //指定路徑,例如C:/a.ftl 注意:此處指定ftl文件所在目錄的路徑,而不是ftl文件的路徑
31             configuration.setDirectoryForTemplateLoading(new File("C:/"));
32             //以utf-8的編碼格式讀取文件
33             template = configuration.getTemplate("導出優惠證明.ftl", "utf-8");
34         } catch (IOException e) {
35             e.printStackTrace();
36             throw new RuntimeException("文件模板加載失敗!", e);
37         }
38 
39         // 填充數據
40         try {
41             template.process(dataMap, out);
42         } catch (TemplateException e) {
43             e.printStackTrace();
44             throw new RuntimeException("模板數據填充異常!", e);
45         } catch (IOException e) {
46             e.printStackTrace();
47             throw new RuntimeException("模板數據填充異常!", e);
48         } finally {
49             if (null != out) {
50                 try {
51                     out.close();
52                 } catch (IOException e) {
53                     e.printStackTrace();
54                     throw new RuntimeException("文件輸出流關閉異常!", e);
55                 }
56             }
57         }
58     }
View Code

因為很多時候我們根據模板生成文件需要添加水印,也就是插入圖片

 1 /***
 2  * 處理圖片
 3  * @param watermarkPath 圖片路徑  D:/image.png
 4  * @return
 5  */
 6 private String getWatermarkImage(String watermarkPath) {
 7     InputStream in = null;
 8     byte[] data = null;
 9     try {
10         in = new FileInputStream(watermarkPath);
11         data = new byte[in.available()];
12         in.read(data);
13         in.close();
14     } catch (Exception e) {
15         e.printStackTrace();
16     }
17     BASE64Encoder encoder = new BASE64Encoder();
18     return encoder.encode(data);
19 }
View Code

注意點:

插入圖片后的word轉化為ftl模板文件(ps:水印圖片可以在word上調整到自己想要的大小,然后在執行下面的步驟)

1、先另存為xml

2、xml擴展名改為ftl

3、打開ftl文件, 搜索w:binData 或者 png可以快速定位圖片的位置,圖片 已經編碼成0-Z的字符串了, 如下

5、 將上述0-Z的字符串全部刪掉,寫上${image}(變量名隨便寫,跟dataMap里的key保持一致)后保存 

6、也是創建一個Map, 將數據存到map,只不過我們要把圖片用代碼進行編碼,將其也編成0-Z的字符串,代碼請看上邊

至此一個簡單的按照模板生成word並插入圖片(水印)功能基本完成。


免責聲明!

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



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