In the previous article, we introduced the example of exporting word through Apache POI; if it is the word template method, is there any open source library to export word through the template method? poi-tl is a Word template engine based on Apache POI, and it is also a free and open source Java class library. You can easily add it to your project, and it has pleasant features. This article mainly introduces the Word export function of the template method implemented by SpringBoot integrated poi-tl.
Knowledge preparation
Need to understand common scenarios and technical means of file upload and download. @pdai
what is poi-tl
The following content comes from the poi-tl official website .
poi-tl (poi template language) is a Word template engine that uses Word templates and data to create awesome Word documents.
Advantage:
It also supports custom plugins, the following are the features supported by the official website code repository
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 |
TDO mode of poi-tl
TDO mode: Template + data-model = output
Take the example of the official website as an example:
XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
new HashMap<String, Object>(){{
put("title", "Hi, poi-tl Word模板引擎");
}});
template.writeAndClose(new FileOutputStream("output.docx"));
- compile compile template - Template
- render render data - data-model
- write output to stream - output
Template: Template
Templates are Word documents in Docx format. You can use Microsoft office, WPS Office, Pages and any software you like to make templates, or you can use Apache POI code to generate templates.
All labels start with {{
}}
and end with ---3b9f120251a6af624f7a251ad1f51d37---. Labels can appear anywhere, including headers, footers, inside tables, text boxes, etc. The table layout can be designed A lot of excellent professional documents are produced, and the table layout is recommended.
The poi-tl template follows the "what you see is what you get" design, and the styles of templates and tags are completely preserved.
Data-model: data
The data is similar to a hash or a dictionary, and can be a Map structure (the key is the tag name):
Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");
Can be an object (the property name is the tag name):
public class Data {
private String name;
private String startTime;
private Author author;
}
The data can be a tree structure, and each level is separated by dots, for example { {author.name} }
The data corresponding to the tag is the value of the name attribute of the author object.
Word templates are not represented by simple text, so a data model is provided when rendering elements such as pictures and tables. They all implement the interface RenderData . For example, the picture data model PictureRenderData contains three attributes of image path, width and height.
Output: output
Output as a stream:
template.write(OutputStream stream);
You can write to any output stream, such as a file stream:
template.write(new FileOutputStream("output.docx"));
For example network flow:
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); // 最后不要忘记关闭这些流。
Implementation case
Here is an example of SpringBoot integrating poi-tl to export Word based on word template, and exporting markdown to word.
Pom dependencies
Import the dependency package of poi
Basic package:
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.0</version>
</dependency>
The package of the plugin is as follows, such as highlight, markdown package
<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>
Export template-based word
method in 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();
}
}
Actual method in 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 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。更多请参考[官方文档](https://poi.apache.org/index.html)");
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;
}
Prepare the template
export word
Export markdown to word
method in 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();
}
}
Methods implemented in Service
@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);
}
Prepare the template
export word
Sample source code
https://github.com/realpdai/tech-pdai-spring-demos
Reference article
more content
Say goodbye to fragmented learning, one-stop systematic learning without routines Back-end development: Java full-stack knowledge system (https://pdai.tech)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。