Java中使用freemarker匯出word文件(詳細案例,含圖片和表格)
Java中使用freemarker匯出word文件(自己真實專案案例)
最近做了一個專案,有一個需求是要將職員的一些資料按照指定的樣式匯出成一個word文件出來,由於自己是一個Java小白,不懂,於是便在網上找方法,網上介紹的有很多,因為原來用poi匯出過ppt,於是便想用poi來做,但是由於時間不夠,最終選擇了用freemarker來做,在做的過程中遇到了一些問題,但最終還是完成了。於是把自己完成這個功能所做的一切從頭到尾的記錄一編,希望能對其他人有幫助。
1.專案需要匯出圖片和表格
可以看出在這個樣式中,需要匯出圖片和迴圈表格。
2.開始製作模板
在製作模板時,用office word 2003或以上的版本來製作,不要用wps做。在畫模板遇到一些問題,我的解決如下:
1.關於圖片,我畫了一個文字框來放圖片,然後隨便放了一個圖片進去(一定要插入一張圖片,方便後面找到圖片的位置好 進行替換)。
2.一些需要動態生成的資料寫如個人資訊用personInfo來代替,注意,單詞要先用一個文字框寫好,再複製黏貼過來,不要再word上手動敲,不然再轉成xml時單詞會被拆散。也不要直接黏貼過來一個${personInfo}
3.表格只需要畫一行,迴圈在xml中配置。
模板畫好之後,直接將word另存為xml格式,儲存完後將word關掉。
用notepad++開啟你儲存的xml格式的文件找到你寫的單詞如stdName
在單詞前後加上${},所有你寫的單詞都加上。
搜尋w:tr找到表格
在表格標籤<w:tr>
的首尾分別加上<#list expList as exp>
和</#list>
標籤,並且標籤裡的單詞要改成${exp.time}
這種形式。解釋一下:list標籤可以使標籤內的表格自動迴圈生成相應的行數,expList是自己命名的,是表格的資料來源,是一個list集合。exp是別名。
搜尋<pkg:binaryData>
,你會發現這個標籤裡的內容特別多,這就是你畫模板時插入的圖片的BASE64字串。
將<pkg:binaryData>
標籤裡的內容刪完,替換為${images}
,這樣就可以在程式碼中設定,然後匯出自己獲取的圖片了,當然名字自己取,叫img也可以,只要在程式碼中和這對應就好了。
3.完成模板
將上面修改好的xml文件儲存好,點選重新命名將其型別修改為ftl。我的是將template.xml改為template.ftl。
好了,至此,模板就製作好了,在後面程式碼中你要用的模板就是template.ftl。我是直接將template.ftl文件複製到我的專案中,當然,你放本地也可以,只是引用時方法和路徑不一樣而已。
4.Java程式碼
private void exportWord(String ssdw, String image64Str, String stdName, String personInfo, List<FamilyInfo> familyInfos,
Map<String, String> maps) {
Map<String, Object> dataMap = new HashMap<String, Object>();
//ssdw 是我前面獲取的職員資訊
dataMap.put("orgName", ssdw);
//image64Str 是職員的照片轉換後的BASE64字串
dataMap.put("images", image64Str);
//stdName 是我前面獲取的職員資訊
dataMap.put("stdName", stdName);
//personInfo 是我前面獲取的職員資訊
dataMap.put("personInfo", personInfo);
//familyList 是職員的家庭資訊的集合,對應模板中的表格
List<Map<String, Object>> familyList = new ArrayList<Map<String, Object>>();
for (int i = 0; i < familyInfos.size(); i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("gx", familyInfos.get(i).getYbrgx());
map.put("xm", familyInfos.get(i).getCyxm());
map.put("dwjzw", familyInfos.get(i).getDwjzw());
familyList.add(map);
}
dataMap.put("familyList", familyList);
//expList 是職員的工作經歷資訊的集合,對應模板中的表格
List<Map<String, Object>> expList = new ArrayList<Map<String, Object>>();
Iterator<Entry<String, String>> it = maps.entrySet().iterator();
while (it.hasNext()) {
Map<String, Object> map = new HashMap<String, Object>();
Map.Entry<String, String> entity = (Entry<String, String>) it.next();
map.put("time", entity.getKey());
map.put("experience", entity.getValue());
expList.add(map);
}
dataMap.put("expList", expList);
@SuppressWarnings("deprecation")
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
//有兩種方式獲取你的模板,模板在專案中時用第一個,模板在本地時用第二個。
//注意:兩種方式的路徑都只需要寫到模板的上一級目錄
configuration.setClassForTemplateLoading(this.getClass(), "/tem");
// configuration.setDirectoryForTemplateLoading(new File("C:/"));
File outFile = new File("D:/outFilessa"+Math.random()*10000+".doc");//輸出路徑
Template t=null;
Writer out = null;
try {
t = configuration.getTemplate("template.ftl", "utf-8"); //檔名,獲取模板
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"));
t.process(dataMap, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e1) {
e.printStackTrace();
}
}
}
將獲取的圖片轉換為BASE64字串
public String getImageStr() {
//data是獲取圖片的二進位制碼;怎麼獲取圖片以及怎麼將圖片轉為二進位制碼的方法就不多說了
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
要使用BASE64Encoder還得有如下操作:
點選你的專案名右鍵,選擇Properties,進去後選擇Java Build Path,然後如圖:
操作完成,應用並OK。
Over 使用freemarker匯出word完成。