最近做了一個需求,要求導出一個采購合同的Excel表格,這個表格樣式比較多。由於是合同,這個Excel表格里面有好多格式要求,比如結尾處簽字那部分就有格式要求。這里介紹種采用FreeMarker的api來生成Excel文件的方案
一、方案的對比
針對這個需求我想了2個方案,介紹如下
方案一:先做一個合同的表格模板,然后把變量都填充成類似EL表達式的樣子。然后通過poi 相關類把模板讀到內存中,把里面的變量的值替換,然后生成下載文件。
方案二:先做一個合同的表格模板,然后轉換成xml文件,然后再改成FreeMarker的ftl文件。通過FreeMarker的Api 把往模板上填充數據,然后生成下載文件。
簡單分析下上面的2個方案:
方案一比較適合那種模板中的行數不會變的場景,如果合同的頭和尾是固定的,中間的行數不固定,那么就方案就不適合了。
方案二比方案一更靈活,由於FreeMarker的模板文件中可以使用很多標簽,如(<#List></#List>);應付這種中間行數不固定的場景就是小case了。
所以,這種導出的Excel有格式要求的,采用FreeMarker生成Excel是最好實現的。
二、介紹下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();
}
}
1
public void exportExcel(){
2
try {
3
/** 1.從數據庫查出數據 */
4
List<User> uList = userService.findAll();
5
6
/** 2.封裝數據 */
7
Map<String, Object> dataMap = new HashMap<String, Object>();
8
List<Map<String, String>> userList = new ArrayList<>(uList.size());
9
for (User u : uList) {
10
Map<String, String> rowData = new HashMap<>();
11
rowData.put("name", u.getName());
12
rowData.put("account", u.getAccount());
13
rowData.put("dept", u.getDept());
14
rowData.put("gender", u.isGender() ? "男" : "女");
15
rowData.put("email", u.getEmail());
16
userList.add(rowData);
17
}
18
dataMap.put("userList", userList);
19
20
/** 3.調用FreeMarker的Api生成Excel */
21
Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
22
// 設置加載模板文件的位置
23
cfg.setServletContextForTemplateLoading(ServletActionContext.getServletContext(), "/ftl");
24
// 獲取模板
25
Template template = cfg.getTemplate("exportExcel.ftl");
26
// 設置response的header
27
HttpServletResponse response = ServletActionContext.getResponse();
28
// 防止亂碼,設置下編碼
29
response.setCharacterEncoding("utf-8");
30
response.setHeader("Content-Disposition", "attachment; filename=testExcel.xls");
31
// 生成Excel
32
template.process(dataMap, response.getWriter());
33
} catch (Exception e) {
34
e.printStackTrace();
35
}
36
}