2
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

http://deepoove.com/poi-tl/

more content

Say goodbye to fragmented learning, one-stop systematic learning without routines Back-end development: Java full-stack knowledge system (https://pdai.tech)


pdai
67 声望158 粉丝