springboot集成easypoi並使用其模板導出功能和遇到的坑

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();
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章