word模板引擎

/ poi / 没有评论 / 29浏览

介绍一款基于word模板引擎,poi-tl。

功能

文档参考如下:poi-tl

扩展

官方项目仍存在一些问题,比如行列这种表格需要自己写代码指定样式、图片写代码指定高度宽度、列表写代码指定样式。为最大化利用word的样式,减少代码量,这里在v1.6.0之上进行源码扩展。

加入模板语法:name|attr:var

fork地址:github

表格

语法:{{table|limit:var}}

模板:

extend-table

其中:

测试代码:

@Test
public void run() {
  Path path = Paths.get("src/test/resources", "table_pattern.docx");
  XWPFTemplate template = XWPFTemplate.compile(path.toFile())
    // 数据
    .render(new HashMap<String, Object>() {{
      put("users", Arrays.asList(new User("张三", 1), new User("李四", 2)));
    }});
  // 输出
  Path outPath = Paths.get("src/test/resources", "table_pattern_out.docx");
  try (OutputStream os = new BufferedOutputStream(new FileOutputStream(outPath.toFile()))) {
    template.write(os);
  } catch (IOException e) {
    LOG.error("render tpl error", e);
  } finally {
    try {
      template.close();
    } catch (IOException e) {
      LOG.error("close template error", e);
    }
  }
}

可以看到这里的 JSON 对象(Java中可以是一个hashmap)存在 users 这个 key,且存在 2 条数据。User 这个对象有两个属性 name、age ,模板在解析时,会自动取值。

输出:

extend-table-out

总结:表格正常渲染,而且样式也正常保留,原来的数据也会保留下来,数据不足补空行。

图片

语法:{{image|height*width:var}}

模板:

extend-image

测试代码:

@Test
public void run() throws IOException {
  Path logoPath = Paths.get("src/test/resources", "logo.png");
  byte[] bytes = Files.readAllBytes(logoPath);
  byte[] encode = Base64.getEncoder().encode(bytes);

  Path path = Paths.get("src/test/resources", "image_pattern.docx");
  XWPFTemplate template = XWPFTemplate.compile(path.toFile())
    // 数据
    .render(new HashMap<String, Object>() {{
      put("logo", new String(encode));
    }});
  // 输出
  Path outPath = Paths.get("src/test/resources", "image_pattern_out.docx");
  try (OutputStream os = new BufferedOutputStream(new FileOutputStream(outPath.toFile()))) {
    template.write(os);
  } catch (IOException e) {
    LOG.error("render tpl error", e);
  } finally {
    try {
      template.close();
    } catch (IOException e) {
      LOG.error("close template error", e);
    }
  }
}

输出:

extend-image-out

总结:图片能正常根据高度宽度渲染出来

列表

语法:list|limit:var

模板:

extend-list

测试代码:

@Test
public void run() {
  Path inPath = Paths.get("src/test/resources", "list_pattern.docx");
  Path outPath = Paths.get("src/test/resources", "list_pattern_out.docx");
  Map<String, Object> model = new HashMap<String, Object>() {{
    put("items", Arrays.asList("张三", "李四", "王五"));
  }};
  try (InputStream is = Files.newInputStream(inPath); OutputStream os = Files.newOutputStream(outPath)) {
    Tpl.render(is, model).out(os);
  } catch (IOException e) {
    LOG.info("render tpl failed", e);
  }
}

输出:

extend-list-out

总结:列表也能正常渲染,保证原有的格式。

tips

看示例,你也许会觉得很奇怪,为什么语法明明写的var,但是截图中有的写的是[var]、有的却写的var。这是因为变量取值,采用的 spring expression 语法。如果代码中是一个对象,就可以直接写var,是一个map,就写[var],数组则是var[下标]