最近作了一個需求,要求導出一個採購合同的Excel表格,這個表格樣式比較多。因爲是合同,這個Excel表格裏面有好多格式要求,好比結尾處簽字那部分就有格式要求。這裏介紹種採用FreeMarker的api來生成Excel文件的方案
1、方案的對比
針對這個需求我想了2個方案,介紹以下
方案一:先作一個合同的表格模板,而後把變量都填充成相似EL表達式的樣子。而後經過poi 相關類把模板讀到內存中,把裏面的變量的值替換,而後生成下載文件。
方案二:先作一個合同的表格模板,而後轉換成xml文件,而後再改爲FreeMarker的ftl文件。經過FreeMarker的Api 把往模板上填充數據,而後生成下載文件。
簡單分析下上面的2個方案:
方案一比較適合那種模板中的行數不會變的場景,若是合同的頭和尾是固定的,中間的行數不固定,那麼就方案就不適合了。
方案二比方案一更靈活,因爲FreeMarker的模板文件中能夠使用不少標籤,如(<#List></#List>);應付這種中間行數不固定的場景就是小case了。
因此,這種導出的Excel有格式要求的,採用FreeMarker生成Excel是最好實現的。
2、介紹下FreeMarker方案實現過程
(1)把Excel模板的格式調好,另存爲xml文件
(2)製做一個ftl模板,把xml文件內容copy進去,把變量換成FreeMarker的插值
(3)針對一些動態的行和列,採用FreeMarker的標籤來實現
(4)代碼中的處理,主要是調用FreeMarker的標籤,把模板和數據一結合,就生成了文件了
下面附上一段後臺的java代碼
public void exportExcel(){
try {
/** 1.從數據庫查出數據 */
List<User> uList = userService.findAll();
/** 2.封裝數據 */
Map<String, Object> dataMap = new HashMap<String, Object>();
List<Map<String, String>> userList = new ArrayList<>(uList.size());
for (User u : uList) {
Map<String, String> rowData = new HashMap<>();
rowData.put("name", u.getName());
rowData.put("account", u.getAccount());
rowData.put("dept", u.getDept());
rowData.put("gender", u.isGender() ? "男" : "女");
rowData.put("email", u.getEmail());
userList.add(rowData);
}
dataMap.put("userList", userList);
/** 3.調用FreeMarker的Api生成Excel */
Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
// 設置加載模板文件的位置
cfg.setServletContextForTemplateLoading(ServletActionContext.getServletContext(), "/ftl");
// 獲取模板
Template template = cfg.getTemplate("exportExcel.ftl");
// 設置response的header
HttpServletResponse response = ServletActionContext.getResponse();
// 防止亂碼,設置下編碼
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment; filename=testExcel.xls");
// 生成Excel
template.process(dataMap, response.getWriter());
} catch (Exception e) {
e.printStackTrace();
}
}