<article class=“article fmt article-content”><blockquote>前文咱们介绍了通过Apache POI通过来导出word的例子;那如果是word模板形式,有没有开源库通过模板形式导出word呢?poi-tl是一个基于Apache POI的Word模板引擎,也是一个收费开源的Java类库,你能够十分不便的退出到你的我的项目中,并且领有着让人喜悦的个性。本文次要介绍通过SpringBoot集成poi-tl实现模板形式的Word导出性能。</blockquote><ul><li><p>SpringBoot集成文件 - 集成POI-tl之基于模板的Word导出</p><ul><li><p>常识筹备</p><ul><li>什么是poi-tl</li><li><p>poi-tl的TDO模式</p><ul><li>Template:模板</li><li>Data-model:数据</li><li>Output:输入</li></ul></li></ul></li><li><p>实现案例</p><ul><li>Pom依赖</li><li>导出基于template的word</li><li>导出markdown为word</li></ul></li><li>示例源码</li><li>参考文章</li><li>更多内容</li></ul></li></ul><h2>常识筹备</h2><blockquote>须要了解文件上传和下载的常见场景和技术手段。@pdai</blockquote><h3>什么是poi-tl</h3><blockquote>如下内容来源于,poi-tl官网。</blockquote><p>poi-tl(poi template language)是Word模板引擎,应用Word模板和数据创立很棒的Word文档。</p><p>劣势:</p><p></p><p>它还反对自定义插件,如下是官网代码仓库反对的个性</p><blockquote>poi-tl supports <strong>custom functions (plug-ins)</strong>, functions can be executed anywhere in the Word template, do anything anywhere in the document is the goal of poi-tl.</blockquote><table><thead><tr><th>Feature</th><th>Description</th></tr></thead><tbody><tr><td><span class=“emoji emoji-white_check_mark”></span> Text</td><td>Render the tag as text</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Picture</td><td>Render the tag as a picture</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Table</td><td>Render the tag as a table</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Numbering</td><td>Render the tag as a numbering</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Chart</td><td>Bar chart (3D bar chart), column chart (3D column chart), area chart (3D area chart), line chart (3D line chart), radar chart, pie chart (3D pie Figure) and other chart rendering</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> If Condition</td><td>Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to conditions</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Foreach Loop</td><td>Loop through certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to the collection</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Loop table row</td><td>Loop to copy a row of the rendered table</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Loop table column</td><td>Loop copy and render a column of the table</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Loop ordered list</td><td>Support the loop of ordered list, and support multi-level list at the same time</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Highlight code</td><td>Word highlighting of code blocks, supporting 26 languages and hundreds of coloring styles</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Markdown</td><td>Convert Markdown to a word document</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Word attachment</td><td>Insert attachment in Word</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Word Comments</td><td>Complete support comment, create comment, modify comment, etc.</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Word SDT</td><td>Complete support structured document tag</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Textbox</td><td>Tag support in text box</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Picture replacement</td><td>Replace the original picture with another picture</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> bookmarks, anchors, hyperlinks</td><td>Support setting bookmarks, anchors and hyperlinks in documents</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Expression Language</td><td>Fully supports SpringEL expressions and can extend more expressions: OGNL, MVEL…</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Style</td><td>The template is the style, and the code can also set the style</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Template nesting</td><td>The template contains sub-templates, and the sub-templates then contain sub-templates</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> Merge</td><td>Word merge Merge, you can also merge in the specified position</td></tr><tr><td><span class=“emoji emoji-white_check_mark”></span> custom functions (plug-ins)</td><td>Plug-in design, execute function anywhere in the document</td></tr></tbody></table><h3>poi-tl的TDO模式</h3><blockquote>TDO模式:Template + data-model = output</blockquote><p>以官网的例子为例:</p><pre><code class=“java”>XWPFTemplate template = XWPFTemplate.compile(“template.docx”).render( new HashMap<String, Object>(){{ put(“title”, “Hi, poi-tl Word模板引擎”);}}); template.writeAndClose(new FileOutputStream(“output.docx”)); </code></pre><ul><li>compile 编译模板 - Template</li><li>render 渲染数据 - data-model</li><li>write 输入到流 - output</li></ul><h4>Template:模板</h4><p>模板是Docx格局的Word文档,你能够应用Microsoft office、WPS Office、Pages等任何你喜爱的软件制作模板,也能够应用Apache POI代码来生成模板。</p><p>所有的标签都是以<code>{{</code>结尾,以<code>}}</code>结尾,标签能够呈现在任何地位,包含页眉,页脚,表格外部,文本框等,表格布局能够设计出很多优良业余的文档,举荐应用表格布局。</p><p>poi-tl模板遵循“所见即所得”的设计,模板和标签的款式会被齐全保留。</p><h4>Data-model:数据</h4><p>数据相似于哈希或者字典,能够是Map构造(key是标签名称):</p><pre><code class=“java”>Map<String, Object> data = new HashMap<>();data.put(“name”, “Sayi”);data.put(“start_time”, “2019-08-04”);</code></pre><p>能够是对象(属性名是标签名称):</p><pre><code class=“java”>public class Data { private String name; private String startTime; private Author author;}</code></pre><p>数据能够是树结构,每级之间用点来分隔开,比方<code>{ {author.name} }</code>标签对应的数据是author对象的name属性值。</p><p><strong>Word模板不是由简略的文本示意,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口RenderData</strong>,比方图片数据模型PictureRenderData蕴含图片门路、宽、高三个属性。</p><h4>Output:输入</h4><p>以流的形式进行输入:</p><pre><code class=“java”>template.write(OutputStream stream);</code></pre><p>能够写到任意输入流中,比方文件流:</p><pre><code class=“java”>template.write(new FileOutputStream(“output.docx”));</code></pre><p>比方网络流:</p><pre><code class=“java”>response.setContentType(“application/octet-stream”);response.setHeader(“Content-disposition”,“attachment;filename=""+“out_template.docx”+”"");// HttpServletResponse responseOutputStream out = response.getOutputStream();BufferedOutputStream bos = new BufferedOutputStream(out);template.write(bos);bos.flush();out.flush();PoitlIOUtils.closeQuietlyMulti(template, bos, out); // 最初不要遗记敞开这些流。</code></pre><h2>实现案例</h2><blockquote>这里展现SpringBoot集成poi-tl基于word模板导出Word, 以及导出markdown为word的例子。</blockquote><h3>Pom依赖</h3><p>引入poi的依赖包</p><p>根底的包:</p><pre><code class=“xml”><dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.0</version></dependency></code></pre><p>插件的包如下,比方highlight,markdown包</p><pre><code class=“xml”><dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl-plugin-highlight</artifactId> <version>1.0.0</version></dependency><dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl-plugin-markdown</artifactId> <version>1.0.3</version></dependency></code></pre><h3>导出基于template的word</h3><p>controller中的办法</p><pre><code class=“java”>@ApiOperation(“Download Word”)@GetMapping("/word/download")public void download(HttpServletResponse response) { try { XWPFTemplate document = userService.generateWordXWPFTemplate(); response.reset(); response.setContentType(“application/octet-stream”); response.setHeader(“Content-disposition”, “attachment;filename=user_word_” + System.currentTimeMillis() + “.docx”); OutputStream os = response.getOutputStream(); document.write(os); os.close(); } catch (Exception e) { e.printStackTrace(); }}</code></pre><p>Service中的理论办法</p><pre><code class=“java”>@Overridepublic XWPFTemplate generateWordXWPFTemplate() throws IOException { Map<String, Object> content = new HashMap<>(); content.put(“title”, “Java 全栈常识体系”); content.put(“author”, “pdai”); content.put(“site”, new HyperlinkTextRenderData(“https://pdai.tech”, “https://pdai.tech”)); content.put(“poiText”, “Apache POI 是创立和保护操作各种合乎Office Open XML(OOXML)规范和微软的OLE 2复合文档格局(OLE2)的Java API。用它能够应用Java读取和创立,批改MS Excel文件.而且,还能够应用Java读取和创立MS Word和MSPowerPoint文件。更多请参考官网文档”); content.put(“poiText2”, “生成xls和xlsx有什么区别?POI对Excel中的对象的封装对应关系?”); content.put(“poiList”, Numberings.create(“excel03只能关上xls格局,无奈间接关上xlsx格局”, “xls只有65536行、256列; xlsx能够有1048576行、16384列”, “xls占用空间大, xlsx占用空间小,运算速度也会快一点”)); RowRenderData headRow = Rows.of(“ID”, “Name”, “Email”, “TEL”, “Description”).textColor(“FFFFFF”) .bgColor(“4472C4”).center().create(); TableRenderData table = Tables.create(headRow); getUserList() .forEach(a -> table.addRow(Rows.create(a.getId() + “”, a.getUserName(), a.getEmail(), a.getPhoneNumber() + “”, a.getDescription()))); content.put(“poiTable”, table); Resource resource = new ClassPathResource(“pdai-guli.png”); content.put(“poiImage”, Pictures.ofStream(new FileInputStream(resource.getFile())).create()); return XWPFTemplate.compile(new ClassPathResource(“poi-tl-template.docx”).getFile()).render(content);}private List<User> getUserList() { List<User> userList = new ArrayList<>(); for (int i = 0; i < 5; i++) { userList.add(User.builder() .id(Long.parseLong(i + “”)).userName(“pdai” + i).email(“pdai@pdai.tech” + i).phoneNumber(121231231231L) .description(“hello world” + i) .build()); } return userList;}</code></pre><p>筹备模板</p><p></p><p>导出word</p><p></p><h3>导出markdown为word</h3><p>controller中的办法</p><pre><code class=“java”>@ApiOperation(“Download Word based on markdown”)@GetMapping("/word/downloadMD")public void downloadMD(HttpServletResponse response) { try { XWPFTemplate document = userService.generateWordXWPFTemplateMD(); response.reset(); response.setContentType(“application/octet-stream”); response.setHeader(“Content-disposition”, “attachment;filename=user_word_” + System.currentTimeMillis() + “.docx”); OutputStream os = response.getOutputStream(); document.write(os); os.close(); } catch (Exception e) { e.printStackTrace(); }}</code></pre><p>Service中实现的办法</p><pre><code class=“java”>@Overridepublic XWPFTemplate generateWordXWPFTemplateMD() throws IOException { MarkdownRenderData code = new MarkdownRenderData(); Resource resource = new ClassPathResource(“test.md”); code.setMarkdown(new String(Files.readAllBytes(resource.getFile().toPath()))); code.setStyle(MarkdownStyle.newStyle()); Map<String, Object> data = new HashMap<>(); data.put(“md”, code); Configure config = Configure.builder().bind(“md”, new MarkdownRenderPolicy()).build(); return XWPFTemplate.compile(new ClassPathResource(“markdown_template.docx”).getFile(), config).render(data);}</code></pre><p>筹备模板</p><p></p><p>导出word</p><p></p><h2>示例源码</h2><p>https://github.com/realpdai/t…</p><h2>参考文章</h2><p>http://deepoove.com/poi-tl/</p><h2>更多内容</h2><p>辞别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈常识体系(https://pdai.tech)</p></article>