1.背景
最近在做個使用poi導出excel的需求,由於所需要的excel較爲複雜,所以我準備使用easypoi的模板導出功能去實現
2.使用
2.1 集成
<!--excel-->
<!--這裏如果直接引入easypoi集成springboot的包即easypoi-spring-boot-starter,
那麼啓動需要spring-boot-starter-web,而不是spring-boot-starter-->
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
使用起來很簡單,我就使用測試數據來說明我遇到的坑:
模板如下圖所示
數據回顯:
3 .坑
3.1
文檔上說使用$fe循環時,可以定義item的名稱,但是我實際操作發現,這是不行的,不能去定義t,或者將其命名爲其他字符,否則展示不出來,下圖就是錯誤的師範
正確寫法:只能寫成如下所示的寫法:
3.2 寫循環的時候注意只能單行或單列,不能合併單元格,否則效果不會是你想要的
如下圖:合併了縱向的單元格
出來的效果是:
即只有遍歷的第一行和最後一行格式正確,中間的都不正確,中間的都是按照單行去遍歷的
合併列也是一樣的:模板如下
出來的格式:
即只有第一行正確,其他行都是按照單列去處理的
所以在遍歷時一定要注意不要去合併單元格,如果你就是想合併單元格,那繼續往下看
3.3 遍歷的列中不能有空單元格
這樣就是錯誤的,如果你真不想有內容,就使用&NULL&去代替。如下圖
3.4 遍歷合併單元格
那遍歷完後如果我想合併單元格怎麼做呢?使用
PoiMergeCellUtil這個類的方法即可,通過mergeCells(合併行單元格)或addMergedRegion(合併列單元格或合併某個區域)方法去合併單元格
3.5 遍歷中使用常量
如果在遍歷中你想有一列是固定的某些字符串,那麼你就需要使用單引號,如下圖所示:
注意:在單元格中輸入單引號時,一定要在第一個單引號前使用一下空格鍵,如果不使用空格鍵,保存後雖然上面的文本中有單引號,但是單元格中的就只剩後面一個單引號了,這就是有問題的。
4.多層循環的bug
使用模板多層循環的功能時,發現有一個bug:
我的模板如下:
h是一個list集合,裝有map對象,然後map裏面有3個key,in1,in2,in3,循環出來後的結果:
其他行都是正確的,唯獨第一行,不知道爲什麼就少了,我看數據也沒有問題,所以這個問題我是沒有解決的
但是我發現使用fe或!fe去遍歷數據是對的,但是又會有一個問題,如果你的list數據下還存在數據,那麼就會被覆蓋,如下圖所示:
可以看到,上面的第三行直接被覆蓋了,這肯定就有問題了,所以使用這種方法的話,前提是你要能確定這個list到底有多少行,然後,在 下面去添加其他的數據,如我知道這個list就到10行,那麼我將數據寫到第11行的位置:
這時候我再遍歷就沒問題了
但是這種辦法顯然沒啥用,因爲在遍歷時,很難在模板中去確定list有多少行數據 ,所以能解決的朋友,分享下解決方法咯
5.代碼
@Test
public void a () throws Exception{
Map<String, Object> map = new HashMap<>();
map.put("a","我是");
map.put("b", "誰是");
map.put("c","瘋了");
List<Map<String,Object>> list = new ArrayList<>();
List<Map<String, Object>> inList = new ArrayList<>();
Map<String, Object> map5 = new HashMap<>();
map5.put("in1","我是4");
map5.put("in2", "誰是5");
map5.put("in3","瘋了6");
Map<String, Object> map6 = new HashMap<>();
map6.put("in1","我是4");
map6.put("in2", "誰是5");
map6.put("in3","瘋了6");
Map<String, Object> map7 = new HashMap<>();
map7.put("in1","我是4");
map7.put("in2", "誰是5");
map7.put("in3","瘋了6");
inList.add(map5);
inList.add(map6);
inList.add(map7);
Map<String, Object> map1 = new HashMap<>();
map1.put("e","我是1");
map1.put("f", "誰是2");
map1.put("g","瘋了3");
map1.put("h",inList);
Map<String, Object> map2 = new HashMap<>();
map2.put("e","我是4");
map2.put("f", "誰是5");
map2.put("g","瘋了6");
map2.put("h",inList);
Map<String, Object> map4 = new HashMap<>();
map4.put("e","我是4");
map4.put("f", "誰是5");
map4.put("g","瘋了6");
map4.put("h",inList);
list.add(map1);
list.add(map2);
list.add(map4);
map.put("d",list);
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "test.xls");
TemplateExportParams params = new TemplateExportParams(
file.getPath());
Workbook workbook = ExcelExportUtil.exportExcel(params, map);
// 這裏寫合併單元格的代碼,我的測試中沒有去寫這個
// PoiMergeCellUtil.mergeCells(workbook.getSheetAt(0), 1, 0);
File savefile = new File("D:/excel/");
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = new FileOutputStream("D:/excel/test_map.xls");
workbook.write(fos);
fos.close();
}