文章目录

  • poi-tl介绍
  • 一、快速开始
  • 二、表格合并
    • 功能需求
    • word模板
    • 代码实现

poi-tl介绍

官方文档地址:http://deepoove.com/poi-tl/
源码地址:https://github.com/Sayi/poi-tl

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

最近在做项目时候有一个关于导出Word的文件的需求,需要导出的word文件较大,并且格式比较复杂,使用poi-tl可以很好的解决。在这里记录一下关于复杂表格的合并与生成。

poi-tl的优势

poi-tl 是基于 Apache POI ,使用时请注意poi的版本依赖冲突问题


一、快速开始

1. 添加依赖

        <!--poi-tl--><dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.0</version></dependency>

2.快速入门
新建Word文档template.docx,这里模板文件存放resources/word目录下,模板包含标签 {{title}}

代码示例

    @GetMapping("/export")public void export(HttpServletResponse response) throws IOException {// 获取模板文件流InputStream resourceAsStream =this.getClass().getResourceAsStream("/word/template.docx");//poi-tl 配置ConfigureBuilder builder = Configure.builder();builder.useSpringEL(false);Map<String,Object> map = new HashMap<>();map.put("title","hello,poi-tl!");XWPFTemplate template = XWPFTemplate.compile(Objects.requireNonNull(resourceAsStream), builder.build()).render(map);//输出文件流template.writeAndClose(new FileOutputStream("D:\\output.docx"));}

3.输出
可以写到任意输出流中,比如文件流:

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

比如网络流:

         //输出网络流response.setContentType("application/octet-stream");response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");// HttpServletResponse responseOutputStream out = response.getOutputStream();BufferedOutputStream bos = new BufferedOutputStream(out);template.write(bos);bos.flush();out.flush();PoitlIOUtils.closeQuietlyMulti(template, bos, out);

二、表格合并

功能需求

导出的word中存在单个表格, 或动态的多个表格

word模板

poi-tl提供了抽象表格策略类 DynamicTableRenderPolicy
我们可以自定义模板渲染策略类,继承即可,从而动态渲染的部分单元格,实现我们需求

代码实现

1.新建数据存储实体类-ServerTableData

@Data
public class ServerTableData {/***  携带表格中真实数据*/private List<RowRenderData> serverDataList;/*** 携带要分组的信息*/private List<Map<String, Object>> groupDataList;/*** 需要合并的列,从0开始*/private Integer mergeColumn;
}

2.新建自定义表格渲染策略类-ServerTablePolicy-

public class ServerTablePolicy extends DynamicTableRenderPolicy {@Overridepublic void render(XWPFTable xwpfTable, Object tableData) throws Exception {if (null == tableData) {return;}// 参数数据声明ServerTableData serverTableData = (ServerTableData) tableData;List<RowRenderData> serverDataList = serverTableData.getServerDataList();List<Map<String, Object>> groupDataList = serverTableData.getGroupDataList();Integer mergeColumn = serverTableData.getMergeColumn();if (CollectionUtils.isNotEmpty(serverDataList)) {// 先删除一行, demo中第一行是为了调整 三线表 样式xwpfTable.removeRow(1);// 行从中间插入, 因此采用倒序渲染数据for (int i = serverDataList.size() - 1; i >= 0; i--) {XWPFTableRow newRow = xwpfTable.insertNewTableRow(1);newRow.setHeight(400);for (int j = 0; j < 4; j++) {newRow.createCell();}// 渲染一行数据TableRenderPolicy.Helper.renderRow(newRow, serverDataList.get(i));}// 处理合并for (int i = 0; i < serverDataList.size(); i++) {// 获取要合并的名称那一列数据 mergeColumn代表要合并的列,从0开始String typeNameData = serverDataList.get(i).getCells().get(mergeColumn).getParagraphs().get(0).getContents().get(0).toString();for (int j = 0; j < groupDataList.size(); j++) {String typeNameTemplate = String.valueOf(groupDataList.get(j).get("typeName"));int listSize = Integer.parseInt(String.valueOf(groupDataList.get(j).get("listSize")));// 若匹配上 就直接合并if (typeNameTemplate.equals(typeNameData)) {TableTools.mergeCellsVertically(xwpfTable, 0, i + 1, i + listSize);groupDataList.remove(j);break;}}}}}
}

3.接口类

    @GetMapping("/export")public void export(HttpServletResponse response) throws IOException {// 获取模板文件流InputStream resourceAsStream =this.getClass().getResourceAsStream("/word/template.docx");//poi-tl 配置ConfigureBuilder builder = Configure.builder();builder.useSpringEL(false);Map<String,Object> map = new HashMap<>();// 伪造一个表格数据//单个表格ServerTableData oneTable = getServerTableData();map.put("oneTable",oneTable);builder.bind("oneTable",new ServerTablePolicy());//多个表格List<Map<String, Object>> dynamicFlag = new ArrayList<>();// 伪造3个表格数据for (int i = 0; i < 3; i++) {ServerTableData tableData = getServerTableData();Map<String, Object> dynamicTableMap = new HashMap<>();dynamicTableMap.put("serverListTable", tableData);dynamicTableMap.put("tableName", "表名");dynamicFlag.add(dynamicTableMap);}map.put("listTable",dynamicFlag);builder.bind("serverListTable",new ServerTablePolicy());XWPFTemplate template = XWPFTemplate.compile(Objects.requireNonNull(resourceAsStream), builder.build()).render(map);//输出网络流response.setContentType("application/octet-stream");response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");// HttpServletResponse responseOutputStream out = response.getOutputStream();BufferedOutputStream bos = new BufferedOutputStream(out);template.write(bos);bos.flush();out.flush();PoitlIOUtils.closeQuietlyMulti(template, bos, out);}private ServerTableData getServerTableData() {ServerTableData serverTableData = new ServerTableData();List<RowRenderData> serverDataList = new ArrayList<>();for (int j = 0; j < 4; j++) {String typeName;RowRenderData serverData;if (j > 1) {typeName = "索隆";serverData = Rows.of(typeName, "喝酒", "三千世界", "无").center().create();}else {typeName = "路飞";serverData = Rows.of(typeName, "大鸡腿", "巨人手枪", "橡胶果实").center().create();}serverDataList.add(serverData);}List<Map<String, Object>> groupDataList = new ArrayList<>();Map<String, Object> groupData1 = new HashMap<>();groupData1.put("typeName", "索隆");groupData1.put("listSize", "2");Map<String, Object> groupData2 = new HashMap<>();groupData2.put("typeName", "路飞");groupData2.put("listSize", "2");groupDataList.add(groupData1);groupDataList.add(groupData2);serverTableData.setServerDataList(serverDataList);serverTableData.setGroupDataList(groupDataList);serverTableData.setMergeColumn(0);return serverTableData;}

4.效果图

poi-tl导出word复杂表格(单元格合并,生成复杂表格)相关推荐

  1. LAY-EXCEL导出excel并实现单元格合并

    通过lay-excel插件实现Excel导出,并实现单元格合并,样式设置等功能. 更详细描述,请去lay-excel插件文档查看,地址:http://excel.wj2015.com/_book/do ...

  2. elementUI——表格单元格合并——技能提升

    elementUI--表格单元格合并--技能提升 之前写过一个关于单元格合并的功能,要求根据某一个参数比如序号,如果同一个序号下的某些参数前后的数据一致,则需要实现单元格的合并. 效果图如下: 还有一 ...

  3. Layui table表格单元格合并问题

    Layui table表格单元格合并 人丑话不多, 直接上方法: /*** * @param fieldName 要合并列的field属性值* @param index 表格的索引值 从1开始* @d ...

  4. POI导出word中cell单元格内换行问题

    利用POI导出word时,换行符"\r\n"无法被正常识别,利用以下方式进行了word中cell单元格内的换行问题. 首先在需要换行字符串的对应位置处插入相应标记符,然后在设置wo ...

  5. java word导出表格_Java Word模板导出包含表格单元格合并

    java通过freemarker导出word循环合并表格单元格 本文主要讲解通过freemarker模板引擎来导出word,并且在word中包含表格的合并部分需要循环生成. 一.Java需要通过模板导 ...

  6. 计算机表格单元格合并,excel表格数据拆分和合并单元格-excel中如何将已经合并的单元格拆分,并将该单元格......

    Excel怎么把一个合并单元格的内容拆分为几个单元格... 要直接位置得到,则有俩种可能性 第一种,合元格是格得来的假合并单元格,单元格都有内容,直接解除合并即可 第二种,若确实是真实合并单元格,则需 ...

  7. Layui之表格单元格合并

    前言 layui是一个不错的后台UI框架,最近一直在学习.但是它原来的表格不支持单元格合并.比如项目这一列,有相同的行,我们就需要合并一下. 就像是这样: 一.实现 我们需要在表格实例化之后再对其样式 ...

  8. HTML——表格单元格合并

    <!DOCTYPE html> <html><head><meta charset="utf-8"><title>表格单 ...

  9. 使用POI创建word表格-在表格单元格中创建子表格

    要实现的功能如下:表格中的单元格中有子表格 实现代码如下: XWPFParagraph cellPara = row.getCell(j).getParagraphArray(0); //row.ge ...

  10. word中将表格单元格合并后,如何让文字上下也处于居中的位置

    如图所示,表格第一行的"类别2"到"类别5"这些文字处于顶部,如果想要这些文字像类别1一样垂直居中,可以通过如下方式进行调整: 1.选中需要调整的单元格,右键单 ...

最新文章

  1. 新版蚂蚁网有抄袭怪兽吗?
  2. Ueditor配置及在项目中的使用
  3. 计算机设备报废界定,福建省国家税务局关于印发《计算机及其附属设备报废淘汰暂行办法》的通知...
  4. 报名 | “智见AI”SpringCamp:物体检测与深度神经网络模型设计
  5. make 调试和传参
  6. 进程上下文与中断上下文的理解
  7. jquery源码解析:proxy,access,swap,isArraylike详解
  8. androidru使用adb启动activity和monkeyrunner启动activity
  9. Proteus软件仿真学习——整流桥电路
  10. 3D数学基础:矩阵的几何解释
  11. STM32串口驱动(拼音检索测试通过)(环形队列+内存动态分配+DMA)
  12. java统计字数_Java 8的字数统计
  13. 如何将XML转换为HL7
  14. 2019年系统架构师考试心得
  15. Linux账户管理详解
  16. http://www.cnblogs.com/dolphin0520/p/3923167.html
  17. Windows10 64位系统设置FRPC开机自动启动
  18. 项目经理 VS 产品经理 (工作职责和要求)
  19. 【虚拟化与云计算】走进Docker
  20. python pip安装第三方包速度慢,这篇博客给你安排清楚了

热门文章

  1. 小程序内嵌webview实现支付
  2. 【DP】LeetCode91 解码方法 【java】
  3. 程序员如何管理自己的财富
  4. pyspark:ML和MLlib
  5. vue各类轮播图大全
  6. 监控系统相关的常见面试问题
  7. 电脑必备软件合集,实用工具推荐
  8. 企业发放的奖金根据利润I提成
  9. SQL Server求解最近多少销售记录的销售额占比总销售额的指定比例
  10. 超3成医院未通过等保测评?亚信安全终端一体化赋能医疗行业安全