欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

poi-tl二次开发

程序员文章站 2022-07-02 12:30:26
poi tl二次开发 "poi tl" 是一款非常好用的word模板生成库,更新响应快、文档demo齐全。堪称word模板界的小军刀! 写在前面 如果你对word模板技术有了解、或者有兴趣,更甚者工作中接触过,那么接下来的内容应该会让你有所收获。 介绍poi tl 功能如下: 文本 {{var}} ......

poi-tl二次开发

poi-tl是一款非常好用的word模板生成库,更新响应快、文档demo齐全。堪称word模板界的小军刀!

写在前面

如果你对word模板技术有了解、或者有兴趣,更甚者工作中接触过,那么接下来的内容应该会让你有所收获。

介绍poi-tl

功能如下:

  • 文本 {{var}}
  • 表格 {{#var}}
  • 图片 {{@var}}
  • 列表 {{*var}}
  • 嵌套 {{+var}}

更多文档参考如下:

这里不再更多的赘述poi-tl的功能了,非常优秀的一个word模板库。

二次开发

如果你还没使用过poi-tl,那么接下来的内容,你应该不太会感同身受。

poi-tl使用一段时间后会发现仍存在一些问题,比如行列表格需要自己写代码指定样式、图片需要写代码指定高度宽度、列表也写代码指定样式。

为最大化利用word的样式,减少代码量,这里在v1.6.0之上进行源码扩展。

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

  • name 为功能名称
  • attr 为属性
  • var 为数据变量名称

fork地址:

表格

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

  • table 说明是表格
  • limit 为数据填充的行数,数据不足补空
  • var 为填充数据(json)的 key,可以是一个对象或者对象数组。

模板:

poi-tl二次开发

其中:

  • 姓名的前面出现的{{table|5:[users]}},代表了这是一个表格模板(可以出现在表格的任意位置,建议在表头),users则说明数据中存在一个 users 的 key 。
  • 表格的第二行变量会根据传递的值动态替换,{name}、{age} 等模板,则说明 users 这个 key 中的对象或对象数组存在 name、age 这两个key。
  • 由于数据只有2条,限制5条,因此补空行3条

测试代码:

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

可以看到这里的 map 中存在 users 这个 key,且存在 2 条数据。user 这个对象有两个属性 name、age ,模板在解析时,会自动取值。

输出:

poi-tl二次开发

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

图片

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

  • image 说明是图片
  • height*width 代表图片的高度和宽度,单位为厘米
  • var 为填充数据的 key,是一个图片字节通过base64加密的字符串

模板:

poi-tl二次开发

测试代码:

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

输出:

poi-tl二次开发

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

列表

语法:list|limit:var

  • list 说明是列表
  • limit 为数据填充的行数,数据不足补空
  • var 为填充数据的 key,值可以是一个字符串或者一个字符串数组。

模板:

poi-tl二次开发

测试代码:

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

输出:

poi-tl二次开发

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

tips

看示例,你也许会觉得很奇怪,为什么语法明明写的var,但是截图中有的写的是[var]、有的却写的var

这是因为变量取值采用的 spring expression 语法:如果代码中是一个对象,就可以直接写var,是一个map,就写[var],数组则是var[下标]

写在最后

如果觉得有用,快快使用起来吧!