SpringBoot如何基于POI-tl和word模板導(dǎo)出龐大的Word文件
前言
poi-tl是一個基于Apache POI的Word模板引擎,也是一個免費開源的Java類庫,你可以非常方便的加入到你的項目中,并且擁有著讓人喜悅的特性。本文主要介紹通過SpringBoot集成poi-tl實現(xiàn)模板方式的Word導(dǎo)出功能。
知識準(zhǔn)備
需要理解文件上傳和下載的常見場景和技術(shù)手段。@pdai
什么是poi-tl
如下內(nèi)容來源于, ?poi-tl官網(wǎng)??。
poi-tl(poi template language)是Word模板引擎,使用Word模板和數(shù)據(jù)創(chuàng)建很棒的Word文檔。
優(yōu)勢:

它還支持自定義插件,如下是 官網(wǎng)代碼倉庫支持的特性
poi-tl supports custom functions (plug-ins), functions can be executed anywhere in the Word template, do anything anywhere in the document is the goal of poi-tl.
Feature | Description |
:white_check_mark: Text | Render the tag as text |
:white_check_mark: Picture | Render the tag as a picture |
:white_check_mark: Table | Render the tag as a table |
:white_check_mark: Numbering | Render the tag as a numbering |
:white_check_mark: Chart | 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 |
:white_check_mark: If Condition | Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to conditions |
:white_check_mark: Foreach Loop | Loop through certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to the collection |
:white_check_mark: Loop table row | Loop to copy a row of the rendered table |
:white_check_mark: Loop table column | Loop copy and render a column of the table |
:white_check_mark: Loop ordered list | Support the loop of ordered list, and support multi-level list at the same time |
:white_check_mark: Highlight code | Word highlighting of code blocks, supporting 26 languages and hundreds of coloring styles |
:white_check_mark: Markdown | Convert Markdown to a word document |
:white_check_mark: Word attachment | Insert attachment in Word |
:white_check_mark: Word Comments | Complete support comment, create comment, modify comment, etc. |
:white_check_mark: Word SDT | Complete support structured document tag |
:white_check_mark: Textbox | Tag support in text box |
:white_check_mark: Picture replacement | Replace the original picture with another picture |
:white_check_mark: bookmarks, anchors, hyperlinks | Support setting bookmarks, anchors and hyperlinks in documents |
:white_check_mark: Expression Language | Fully supports SpringEL expressions and can extend more expressions: OGNL, MVEL... |
:white_check_mark: Style | The template is the style, and the code can also set the style |
:white_check_mark: Template nesting | The template contains sub-templates, and the sub-templates then contain sub-templates |
:white_check_mark: Merge | Word merge Merge, you can also merge in the specified position |
:white_check_mark: custom functions (plug-ins) | Plug-in design, execute function anywhere in the document |
poi-tl的TDO模式
TDO模式:Template + data-model = output
以官網(wǎng)的例子為例:
XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
new HashMap<String, Object>(){{
put("title", "Hi, poi-tl Word模板引擎");
}});
template.writeAndClose(new FileOutputStream("output.docx"));- compile 編譯模板 - Template
- render 渲染數(shù)據(jù) - data-model
- write 輸出到流 - output
Template:模板
模板是Docx格式的Word文檔,你可以使用Microsoft office、WPS Office、Pages等任何你喜歡的軟件制作模板,也可以使用Apache POI代碼來生成模板。
所有的標(biāo)簽都是以{{開頭,以}}結(jié)尾,標(biāo)簽可以出現(xiàn)在任何位置,包括頁眉,頁腳,表格內(nèi)部,文本框等,表格布局可以設(shè)計出很多優(yōu)秀專業(yè)的文檔,推薦使用表格布局。
poi-tl模板遵循“所見即所得”的設(shè)計,模板和標(biāo)簽的樣式會被完全保留。
Data-model:數(shù)據(jù)
數(shù)據(jù)類似于哈?;蛘咦值洌梢允荕ap結(jié)構(gòu)(key是標(biāo)簽名稱):
Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");可以是對象(屬性名是標(biāo)簽名稱):
public class Data {
private String name;
private String startTime;
private Author author;
}數(shù)據(jù)可以是樹結(jié)構(gòu),每級之間用點來分隔開,比如??{ {author.name} }??標(biāo)簽對應(yīng)的數(shù)據(jù)是author對象的name屬性值。
Word模板不是由簡單的文本表示,所以在渲染圖片、表格等元素時提供了數(shù)據(jù)模型,它們都實現(xiàn)了接口RenderData,比如圖片數(shù)據(jù)模型PictureRenderData包含圖片路徑、寬、高三個屬性。
Output:輸出
以流的方式進行輸出:
template.write(OutputStream stream);
可以寫到任意輸出流中,比如文件流:
template.write(new FileOutputStream("output.docx"));比如網(wǎng)絡(luò)流:
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out); // 最后不要忘記關(guān)閉這些流。實現(xiàn)案例
這里展示SpringBoot集成poi-tl基于word模板導(dǎo)出Word, 以及導(dǎo)出markdown為word的例子。
Pom依賴
引入poi的依賴包
基礎(chǔ)的包:
<dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.0</version> </dependency>
插件的包如下,比如highlight,markdown包
<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>
導(dǎo)出基于template的word
controller中的方法:
@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();
}
}Service中的實際方法:
@Override
public 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 是創(chuàng)建和維護操作各種符合Office Open XML(OOXML)標(biāo)準(zhǔn)和微軟的OLE 2復(fù)合文檔格式(OLE2)的Java API。用它可以使用Java讀取和創(chuàng)建,修改MS Excel文件.而且,還可以使用Java讀取和創(chuàng)建MS Word和MSPowerPoint文件。更多請參考[官方文檔](https://poi.apache.org/index.html)");
content.put("poiText2", "生成xls和xlsx有什么區(qū)別?POI對Excel中的對象的封裝對應(yīng)關(guān)系?");
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;
}準(zhǔn)備模板:

導(dǎo)出word:

導(dǎo)出markdown為word
controller中的方法:
@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();
}
}Service中實現(xiàn)的方法:
@Override
public 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);
}準(zhǔn)備模板:

導(dǎo)出word:

到此這篇關(guān)于SpringBoot如何基于POI-tl和word模板導(dǎo)出龐大的Word文件的文章就介紹到這了,更多相關(guān)SpringBoot導(dǎo)出Word文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中使用?POI的示例代碼
- SpringBoot EasyPoi動態(tài)導(dǎo)入導(dǎo)出的兩種方式實現(xiàn)方法詳解
- SpringBoot集成POI實現(xiàn)Excel導(dǎo)入導(dǎo)出的示例詳解
- SpringBoot?AOP?@Pointcut切入點表達式排除某些類方式
- springboot?aop里的@Pointcut()的配置方式
- springboot中EasyPoi實現(xiàn)自動新增序號的方法
- 淺談springboot之JoinPoint的getSignature方法
- SpringBoot中使用JeecgBoot的Autopoi導(dǎo)出Excel的方法步驟
- springboot中poi使用操作方法
相關(guān)文章
Java中byte輸出write到文件的實現(xiàn)方法講解
今天小編就為大家分享一篇關(guān)于Java中byte輸出write到文件的實現(xiàn)方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
Java實現(xiàn)InputStream的任意拷貝方式
這篇文章主要介紹了Java實現(xiàn)InputStream的任意拷貝方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
java中優(yōu)化大量if...else...方法總結(jié)
在我們平時的開發(fā)過程中,經(jīng)??赡軙霈F(xiàn)大量If else的場景,代碼顯的很臃腫,非常不優(yōu)雅,下面這篇文章主要給大家介紹了關(guān)于java中優(yōu)化大量if...else...方法的相關(guān)資料,需要的朋友可以參考下2023-03-03
springcloud gateway設(shè)置context-path的操作
這篇文章主要介紹了springcloud gateway設(shè)置context-path的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07

