ftl模板导出excel_freemarker导出复杂Excel
原文: freemarker導出復雜Excel
date: 2017-04-20 12:39:04
[TOC]
序言
用Freemarker做Excel導出確實很容易. 但是導出復雜Excel, 例如多行合并的還是費了一天時間
步驟
首先是pom依賴, 構建工具使用Maven
org.springframework.boot
spring-boot-starter-freemarker
準備模板
接下來, 制作ftl模板
在Office中編輯一個Excel文件, 這就是最后要生成的模板.
這里寫圖片描述
注意: 另存為xml格式. 不要直接改后綴名
拷貝到項目下, 修改后綴名為.ftl (這里我放到resources/templates目錄下)
用xml方式打開這個.ftl文件. 找到如下代碼
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
人員列表
name
age
address
1
zhangsan
22
BeiJing
主要看上面這段, 對比你的Excel很容易看出: 每個就是一行, 每個是一個單元格
找到要循環的一行, 添加表達式和標簽
加完標簽后如下:
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
人員列表
姓名
年齡
地址
${index}
${u.name}
${u.age}
${u.address}
#list>
注意ExpandedRowCount的值可以變量傳進來, 如果不好計算可以寫一個很大的值.
自己寫的值有什么影響我沒測試…
準備數據源
對于你要動態生成的List, 里面可以放Map, 也可以放對象, 都行.
這里我先用Map, 等下用對象
模擬獲取數據
/**
* 構造user數據List>
*/
private static List> getUserList(){
List> returnList = new ArrayList>();
Map map1 = new HashMap();
Map map2 = new HashMap();
map1.put("name", "張三");
map1.put("age", "18");
map1.put("address", "廣東");
map2.put("name", "王五");
map2.put("age", "22");
map2.put("address", "北京");
returnList.add(map1);
returnList.add(map2);
return returnList;
}
控制器
@SuppressWarnings("unchecked")
@RequestMapping(value="/exportExcel", method=RequestMethod.GET)
public void exportExcelByFreeMarker(HttpServletRequest request, HttpServletResponse response) {
try {
List> userList= this.getUserList();
configuration.setDefaultEncoding("UTF-8");
configuration.setTemplateUpdateDelayMilliseconds(0);
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//獲取模板
Template template = configuration.getTemplate("userlist.ftl");
Map root = new HashMap();
root.put("userList", userList);
root.put("userListSize", String.valueOf(userList.size()+2));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date today = new Date();
String fileName = "人員列表" + sdf.format(today);//以今天的日期為文件名
response.setContentType("application/msexcel;charset=UTF-8");
response.setHeader("Content-disposition","attachment;filename=\""+new String((fileName+".xls").getBytes("GBK"),"ISO8859-1")+"\"");
//response字符流轉換成字節流,template需要字節流作為輸出
OutputStream outputStream = response.getOutputStream();
OutputStreamWriter outputWriter = new OutputStreamWriter(outputStream,"UTF-8");
Writer writer = new BufferedWriter(outputWriter);
template.process(root, writer);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
在瀏覽器中輸入請求地址就可以導出了.
復雜Excel
生成Excel也有很多復雜的情況, 比如帶圖片, 跨行合并等.
這里例多行合并的, 例如:
這里寫圖片描述
生成的xml:
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
人員列表
姓名
年齡
孩子
地址
1
張三
22
小張
北京
二張
仔細觀察這段代碼, 跟上面的不帶合并的xml進行對比:
每個帶合并的Cell都帶有一個屬性MergeDown, 它的值為 (合并格數-1)
合并的格數是通過一個對象的循環來得到, 比如這里的”孩子”字段
擴展的Row會有一個Index屬性, 它的值就是字段的列數, 這里是4
分析好之后開始加標簽:
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
人員列表
姓名
年齡
孩子
地址
#if>
${index}
${u.name}
${u.age}
${firstChildren.name}
#if>
#list>
${u.address}
1 && c_index > 0 )>
${c.name}
#if>
#list>
#list>
注意:
MergeDown這個屬性中判斷了是否小于0, 親測在office中<0會導致Excel報錯, WPS不會, 最好還是判斷一下
ExpandedRowCount可以給個很大的值, 最好還是通過程序來傳大小
在這個Excel中需要兩個List:
User: List
Children: List
User -> Children : 1->N
也可以是Map: List>
總結
以上是生活随笔為你收集整理的ftl模板导出excel_freemarker导出复杂Excel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个qq网名情侣伤感带符号
- 下一篇: 赵奕欢出席韩方科颜公司年会真有这样的事情