使用Poi-tl word模板的爬坑日記
1.簡介

POI-TL官網(wǎng)
poi-tl即poi template language的簡稱,是一款Word模板的處理引擎,由于現(xiàn)在根據(jù)模板導出對應word的需求,要求越來越高,比如各種表格格式,比如列表、圖片、表格、自定義表格內(nèi)容等等,poi-tl大多數(shù)功能都有實現(xiàn),有些需要個性化的配置一下比如復選框(都是淚。。。)。
2.使用
2.1 引入全部相關的依賴
2.1.1 多地方導入不同版本的依賴,造成的循環(huán)依賴問題
報錯信息:java.lang.NoSuchFieldError: DOUGHNUT
這里就出現(xiàn)了一個坑,因為項目本身集成了poi一個4.1.2的poi-ooxml依賴用于導出操作,但是里面沒有包含使用word模板的poi-tl依賴,當時沒有發(fā)現(xiàn)我引入的是4.1.3的依賴,在啟動poi-tl模板解析的時候出現(xiàn)了循環(huán)依賴錯誤,最后將依賴的版本都改為統(tǒng)一的4.1.2后問題得到解決
2.2 編寫工具類
這里這種寫法無法處理,特別定制的表格,如果需要處理特別定制的表格需要傳config過來進行個性化定制,編譯的時候加上傳過來的個性化的config即可
整體流程是:找到模板位置==》然后compile進行模板解析==》render進行數(shù)據(jù)加載和編譯==》初始化輸出流==》將加載了數(shù)據(jù)編譯后的模板進行輸出==》但是此時沒有文件讓我們輸出==》根據(jù)傳入的名稱創(chuàng)建文檔==》完成寫入操作==》關閉各種流==》完畢
XWPFTemplate template = XWPFTemplate.compile((path+"\"+fileName),config).render(dataMap);
public static void download(HttpServletRequest request, HttpServletResponse response, String newWordName, Map dataMap, String fileName) { String path = ClassUtils.getDefaultClassLoader().getResource("").getPath(); if(StringUtils.isBlank(fileName)){return;} XWPFTemplate template = XWPFTemplate.compile(path+"\"+fileName).render(dataMap); OutputStream out = null; try { out = new FileOutputStream("template.docx"); template.write(out); out.flush(); out.close(); template.close(); } catch (IOException e) { e.printStackTrace(); } InputStream fis = null; OutputStream toClient = null; File file = new File("template.docx"); try { fis = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空response response.reset(); // 設置response的Header newWordName = URLEncoder.encode(newWordName, "utf-8"); //這里要用URLEncoder轉下才能正確顯示中文名稱 response.addHeader("Content-Disposition", "attachment;filename=" + newWordName+""); response.addHeader("Content-Length", "" + file.length()); toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); } catch (Exception e) { e.printStackTrace(); } finally{ try { if(fis!=null){ fis.close(); } } catch (IOException e) { e.printStackTrace(); } try { if(toClient!=null){ toClient.close(); } } catch (Exception e) { e.printStackTrace(); } } }
//Object轉Map public static Map
2.3網(wǎng)絡圖片的處理方法
if(dataMap.containsKey("file")){ dataMap.put("file", new PictureRenderData(450, 450, ".png", BytePictureUtils.getUrlByteArray(en.getFile()))); }
2.4 表格輸出
2.4.1 方法一
這種方法需要手動調(diào)格式,如果沒有設置格式,會輸出一個默認的表格。
使用RowRenderData的build的創(chuàng)建好表格的框架,比如下圖的 創(chuàng)建的 序號列、第一列、第二列、第三列
然后將設置好的表格傳入最后處理的map中,并且使用MiniTableRenderData進行表格的初始化,就相當于告訴編譯方法這個是個表格,按我這個表格的設置來輸出。
int i = 1; RowRenderData content = RowRenderData.build(String.valueOf(i),第二列字段值,第三列字段值); list.add(content); dataMap.put("content",new MiniTableRenderData(list));
2.4.2 方法二
將需要處理的數(shù)據(jù)list集合,正常的放入需要處理的map中,然后使用Configure進行newBuilder個性化創(chuàng)建,然后將設置好的個性化config傳入都工具類中,在模板編譯的時候傳入進行加入個性化設置的編譯,這種方法可以根據(jù)原模板的樣式進行填充。
dataMap.put("content",content); HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy(); Configure config = Configure.newBuilder().bind("content", policy).build();
2.5 復選框
這種也是無奈的解決辦法,還有可以根據(jù)值和模板字段進行比對判斷的方法,目前還沒有研究透徹,由于比較項目著急,所以暫時使用這種粗暴的方法。
if(dataMap.containsKey("復選框")){ if (dataMap.get("復選框").equals("1")){ dataMap.put("復選框", "■值1 □值2"); }else if(dataMap.get("復選框").equals("2")){ dataMap.put("復選框", "□值1 ■值2"); } }
參考一:Java 使用 Poi-tl word模板導出word
參考二:JAVA使用POI-TL通過Word模板生成Word文件
參考三:POI-Tl表格處理可以看這個
參考四:復選框的實現(xiàn)
參考五:springboot整合poi-tl根據(jù)模板導出word
參考六:poi插入word 2007 Wingdings字符,可以插入各種特殊字符
參考七:使用poi-tl導出word文件的幾個技巧
參考八:使用POI導出Word(含表格)的實現(xiàn)方式及操作Word的工具類
參考九:表格合并的參考
參考十:poi-tl的使用
版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。
版權聲明:本文內(nèi)容由網(wǎng)絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權內(nèi)容。