參考
因對程式碼結構該動太大,沒有提交PR,程式碼核心思路和程式碼源於大腦補丁
功能介紹:
1.支援Freemarker匯出Excel的所有功能(完美匯出複雜的合併單元格、合併行和列、顏色、字型等)
2.支援匯出帶有圖片的Excel
3.支援多Sheet頁匯出
4.支援匯出單元格註釋
5.支援完美匯出.xls、.xlsx格式,生成檔案開啟無報錯提醒
6.適用於生成複雜樣式的Excel,不適用於大資料量匯出
需求背景
企業級需求中有較多複雜樣式的excel需求,包括各種單元格合併,插入圖片,而且變更頻繁,案例如下:
單純使用JAVA POI無法滿足此類開發需求。Freemarker匯出的Excel為xml格式,此格式所有的富文字資訊都會丟失,只留下文字內容,不能直接匯出帶有圖片的Excel。通常使用Freemaker直接將.xml重新命名為.xls的方法,對複雜樣式相容不友好,會有彈框報錯。基於此種需求,開發此工具匯出帶有圖片的Excel。
<dependencies> <!-- 僅僅需要基本的starter,不需要web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 模板引擎 --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <!-- java處理Excel檔案,支援excel2003 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <!--支援excel2007以上,效能特別好--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> <exclusions> <exclusion> <artifactId>poi</artifactId> <groupId>org.apache.poi</groupId> </exclusion> </exclusions> </dependency> <!-- java解析XML檔案 --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <!-- 使用其中的FileUtils工具類 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency>
使用步驟
1. 參考Freemaker語法設定佔位符,將Excel檔案另存為XML;
2. 將模板XML放到專案的模板目錄中
3. 匯出效果
@Test public void writeExcel() throws IOException { Map<String, Object> dataMap = getDemoDataMap(); String templateName = "圖片-顏色-單元格合併-樣例.xml"; /* 若改變圖片位置,修改後4個引數 dx1 dy1 起始單元格中的x,y座標. dx2 dy2 結束單元格中的x,y座標 col1,row1 指定起始的單元格,下標從0開始 col2,row2 指定結束的單元格 ,下標從0開始 */ HSSFClientAnchor hssfClientAnchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 5, 1, (short) 13, 21); // 讀取resource下的檔案 PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); // 獲取單個檔案 Resource resource = resolver.getResource("template/功能簡介.png"); File img = resource.getFile(); ExcelImage hssfImage = new ExcelImage(img, 0, hssfClientAnchor); List<ExcelImage> hssfImgs = new ArrayList<>(); hssfImgs.add(hssfImage); ExcelWriter.writeExcel2003(dataMap, templateName, "圖片-顏色-單元格合併-樣例-2003", hssfImgs); XSSFClientAnchor xssfClientAnchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 5, 1, (short) 13, 21); ExcelImage xssfImage = new ExcelImage(img, 0, xssfClientAnchor); List<ExcelImage> xssfImgs = new ArrayList<>(); xssfImgs.add(xssfImage); ExcelWriter.writeExcel2007(dataMap, templateName, "圖片-顏色-單元格合併-樣例-2007", xssfImgs); }
程式碼邏輯
1. 使用Freemaker給佔位符賦值,生成XML檔案,該XML檔案中包含Excel原始樣式和所有資料;
2. 解析XML中的Excel樣式,轉化為CellStyle;
3. 遍歷XML的資料格式,按照讀取的CellStyle重新生成Excel;
4. 將圖片插入到給定的單元格中;
結論:此方法的邏輯是通過Freemaker模板引擎,給預置的Excel模板動態賦值,生成中間態的XML檔案,再解析該XML檔案生成新的Excel檔案。將複雜的樣式和資料的編輯放在模板中,通過兩次IO生成檔案,不適合大資料量的匯出,適合結構複雜和多樣定製的Excel生成。