关于springboot:SpringBoot集成文件-如何基于POItl和word模板导出庞大的Word文件

40次阅读

共计 7263 个字符,预计需要花费 19 分钟才能阅读完成。

前文咱们介绍了通过 Apache POI 通过来导出 word 的例子;那如果是 word 模板形式,有没有开源库通过模板形式导出 word 呢?poi-tl 是一个基于 Apache POI 的 Word 模板引擎,也是一个收费开源的 Java 类库,你能够十分不便的退出到你的我的项目中,并且领有着让人喜悦的个性。本文次要介绍通过 SpringBoot 集成 poi-tl 实现模板形式的 Word 导出性能。

  • SpringBoot 集成文件 – 集成 POI-tl 之基于模板的 Word 导出

    • 常识筹备

      • 什么是 poi-tl
      • poi-tl 的 TDO 模式

        • Template:模板
        • Data-model:数据
        • Output:输入
    • 实现案例

      • Pom 依赖
      • 导出基于 template 的 word
      • 导出 markdown 为 word
    • 示例源码
    • 参考文章
    • 更多内容

常识筹备

须要了解文件上传和下载的常见场景和技术手段。@pdai

什么是 poi-tl

如下内容来源于,poi-tl 官网。

poi-tl(poi template language)是 Word 模板引擎,应用 Word 模板和数据创立很棒的 Word 文档。

劣势:

它还反对自定义插件,如下是官网代码仓库反对的个性

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
Text Render the tag as text
Picture Render the tag as a picture
Table Render the tag as a table
Numbering Render the tag as a numbering
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
If Condition Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to conditions
Foreach Loop Loop through certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to the collection
Loop table row Loop to copy a row of the rendered table
Loop table column Loop copy and render a column of the table
Loop ordered list Support the loop of ordered list, and support multi-level list at the same time
Highlight code Word highlighting of code blocks, supporting 26 languages ​​and hundreds of coloring styles
Markdown Convert Markdown to a word document
Word attachment Insert attachment in Word
Word Comments Complete support comment, create comment, modify comment, etc.
Word SDT Complete support structured document tag
Textbox Tag support in text box
Picture replacement Replace the original picture with another picture
bookmarks, anchors, hyperlinks Support setting bookmarks, anchors and hyperlinks in documents
Expression Language Fully supports SpringEL expressions and can extend more expressions: OGNL, MVEL…
Style The template is the style, and the code can also set the style
Template nesting The template contains sub-templates, and the sub-templates then contain sub-templates
Merge Word merge Merge, you can also merge in the specified position
custom functions (plug-ins) Plug-in design, execute function anywhere in the document

poi-tl 的 TDO 模式

TDO 模式:Template + data-model = output

以官网的例子为例:

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 渲染数据 – data-model
  • write 输入到流 – output

Template:模板

模板是 Docx 格局的 Word 文档,你能够应用 Microsoft office、WPS Office、Pages 等任何你喜爱的软件制作模板,也能够应用 Apache POI 代码来生成模板。

所有的标签都是以 {{ 结尾,以 }} 结尾,标签能够呈现在任何地位,包含页眉,页脚,表格外部,文本框等,表格布局能够设计出很多优良业余的文档,举荐应用表格布局。

poi-tl 模板遵循“所见即所得”的设计,模板和标签的款式会被齐全保留。

Data-model:数据

数据相似于哈希或者字典,能够是 Map 构造(key 是标签名称):

Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");

能够是对象(属性名是标签名称):

public class Data {
  private String name;
  private String startTime;
  private Author author;
}

数据能够是树结构,每级之间用点来分隔开,比方 {{author.name} } 标签对应的数据是 author 对象的 name 属性值。

Word 模板不是由简略的文本示意,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口 RenderData,比方图片数据模型 PictureRenderData 蕴含图片门路、宽、高三个属性。

Output:输入

以流的形式进行输入:

template.write(OutputStream stream);

能够写到任意输入流中,比方文件流:

template.write(new FileOutputStream("output.docx"));

比方网络流:

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); // 最初不要遗记敞开这些流。

实现案例

这里展现 SpringBoot 集成 poi-tl 基于 word 模板导出 Word,以及导出 markdown 为 word 的例子。

Pom 依赖

引入 poi 的依赖包

根底的包:

<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>

导出基于 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 是创立和保护操作各种合乎 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;
}

筹备模板

导出 word

导出 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 中实现的办法


@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);
}

筹备模板

导出 word

示例源码

https://github.com/realpdai/t…

参考文章

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

更多内容

辞别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈常识体系(https://pdai.tech)

正文完
 0