0


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")publicvoidexport(HttpServletResponse response)throwsIOException{// 获取模板文件流InputStream resourceAsStream =this.getClass().getResourceAsStream("/word/template.docx");//poi-tl 配置ConfigureBuilder builder =Configure.builder();
        builder.useSpringEL(false);Map<String,Object> map =newHashMap<>();
        map.put("title","hello,poi-tl!");XWPFTemplate template =XWPFTemplate.compile(Objects.requireNonNull(resourceAsStream), builder.build()).render(map);//输出文件流
        template.writeAndClose(newFileOutputStream("D:\\output.docx"));}

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

template.write(newFileOutputStream("output.docx"));

比如网络流:

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

二、表格合并

功能需求

导出的word中存在

单个

表格, 或

动态的多个

表格

word模板

在这里插入图片描述

poi-tl提供了抽象表格策略类

DynamicTableRenderPolicy

我们可以自定义模板渲染策略类,继承即可,从而动态渲染的部分单元格,实现我们需求

代码实现

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

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

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

ServerTablePolicy
publicclassServerTablePolicyextendsDynamicTableRenderPolicy{@Overridepublicvoidrender(XWPFTable xwpfTable,Object tableData)throwsException{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")publicvoidexport(HttpServletResponse response)throwsIOException{// 获取模板文件流InputStream resourceAsStream =this.getClass().getResourceAsStream("/word/template.docx");//poi-tl 配置ConfigureBuilder builder =Configure.builder();
        builder.useSpringEL(false);Map<String,Object> map =newHashMap<>();// 伪造一个表格数据//单个表格ServerTableData oneTable =getServerTableData();
        map.put("oneTable",oneTable);
        builder.bind("oneTable",newServerTablePolicy());//多个表格List<Map<String,Object>> dynamicFlag =newArrayList<>();// 伪造3个表格数据for(int i =0; i <3; i++){ServerTableData tableData =getServerTableData();Map<String,Object> dynamicTableMap =newHashMap<>();
            dynamicTableMap.put("serverListTable", tableData);
            dynamicTableMap.put("tableName","表名");
            dynamicFlag.add(dynamicTableMap);}
        map.put("listTable",dynamicFlag);
        builder.bind("serverListTable",newServerTablePolicy());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 =newBufferedOutputStream(out);
        template.write(bos);
        bos.flush();
        out.flush();PoitlIOUtils.closeQuietlyMulti(template, bos, out);}privateServerTableDatagetServerTableData(){ServerTableData serverTableData =newServerTableData();List<RowRenderData> serverDataList =newArrayList<>();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 =newArrayList<>();Map<String,Object> groupData1 =newHashMap<>();
        groupData1.put("typeName","索隆");
        groupData1.put("listSize","2");Map<String,Object> groupData2 =newHashMap<>();
        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.效果图

在这里插入图片描述

标签: word spring boot

本文转载自: https://blog.csdn.net/yuanay/article/details/127772831
版权归原作者 ufo21 所有, 如有侵权,请联系我们删除。

“poi-tl导出word复杂表格(单元格合并,生成复杂表格)”的评论:

还没有评论