poi-tl1.10.0动态合并同列不同行单元格动态数据
一、在有些业务场景下,我们需要导出一些word文档的报告等,这里我推荐一下poi-tl,这是我开发当中用到的。由于业务数据的复杂性,easyWord没法满足需求,所以这里推荐使用poi-tl,因为它提供了针对处理复杂数据的很多接口策略,还可以根据自己具体的业务需求来扩展。
二、这次是关于如何动态合并单元格。参考了其他帖子,但是他们用到的数据都是固定的,但是对于动态数据是不适用的,下面直接上代码,分享一下我是如何处理的?
-
package com.cantai.qmsat.utils.poi;
-
-
import com.cantai.qmsat.at.operate.entity.InstrumentEntity;
-
import com.deepoove.poi.data.CellRenderData;
-
import com.deepoove.poi.data.RowRenderData;
-
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
-
import com.deepoove.poi.policy.TableRenderPolicy;
-
import com.deepoove.poi.util.TableTools;
-
import org.apache.poi.xwpf.usermodel.XWPFTable;
-
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
-
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
-
-
import java.util.ArrayList;
-
import java.util.HashMap;
-
import java.util.HashSet;
-
import java.util.List;
-
import java.util.stream.Collectors;
-
-
/**
-
* @author shijin
-
* @create 2022-11-04 19:30
-
*/
-
public class RowspanPolicy extends DynamicTableRenderPolicy {
-
-
-
public void render(XWPFTable table, Object data) throws Exception {
-
int num = 0;
-
if (null == data) return;
-
List<RowRenderData> detailData = (List<RowRenderData>) data;
-
if (null != detailData) {
-
table.removeRow(2);
-
// 循环插入行,必须采用这种遍历,不然数据会反过来
-
for (int i = detailData.size() - 1; i >= 0; i--) {
-
//根据数据长度创建对应行数
-
XWPFTableRow insertNewTableRow = table.insertNewTableRow(2);
-
for (int j = 0; j < 5; j ) {
-
//根据列的数量创建对应单元格
-
insertNewTableRow.createCell();
-
}
-
// 单行渲染
-
TableRenderPolicy.Helper.renderRow(table.getRow(2), detailData.get(i));
-
}
-
//遍历完整个图表之后再合并
-
List<String> list = new ArrayList<>();
-
HashMap<String, Object> nameNumMap = new HashMap<>();
-
for (int i = 0; i < detailData.size(); i ) {
-
String typeName = detailData.get(i).getCells().get(1).getParagraphs().get(0).getContents().get(0).toString();
-
list.add(typeName);
-
}
-
List<String> collect = list.stream().distinct().collect(Collectors.toList());
-
for (String s : collect) {
-
for (int i = 0; i < detailData.size(); i ) {
-
String typeName1 = detailData.get(i).getCells().get(1).getParagraphs().get(0).getContents().get(0).toString();
-
if (s == typeName1) {
-
num ;
-
}
-
}
-
nameNumMap.put(s, num);
-
num = 0;
-
}
-
//开始合并
-
for (String s : collect) {
-
//从我们map中取出刚才放入的单位的个数
-
Integer change = Integer.parseInt(String.valueOf(nameNumMap.get(s)));
-
//开始循环数据
-
//元素第一次出现的位置
-
int firstLocation = list.lastIndexOf(s) 1;
-
int fromRow = firstLocation - change 2;
-
int toRow = list.lastIndexOf(s) 2;
-
if (change > 1) {
-
TableTools.mergeCellsVertically(table, 1, fromRow, toRow);
-
}
-
}
-
}
-
}
-
}
-
创建一个类RowspanPolicy继承DynamicTableRenderPolicy,重写render方法
-
准备数据:参考了官网的合并方法,data中的数据类型要转为RowRenderData,所以在组装数据的时候,直接组装成RowRenderData类型的,如下:
-
for (AfTtiInstrumentVo afTtiInstrumentVo : instrumentVos) {
-
int i = instrumentVos.indexOf(afTtiInstrumentVo) 1;
-
DateFormat cst = new SimpleDateFormat("yyyy-MM-dd");
-
DateFormat gmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
-
Date date1 = gmt.parse(afTtiInstrumentVo.getNextCalibrationDate().toString());
-
String date2 = cst.format(date1);
-
RowRenderData rowRenderData = Rows.of(Integer.toString(i), afTtiInstrumentVo.getTestName(), afTtiInstrumentVo.getDeviceName(), afTtiInstrumentVo.getFactoryNumber(), date2).center().create();
-
instrumentList1.add(rowRenderData);
-
}
-
数据准备好之后,开始重写DynamicTableRenderPolicy策略接口,首先是将数据逐个添加到每一个的单元格,如下:
-
//如果顺序遍历的话,数据的顺序和原来的顺序会相反(这是在debug的时候发现的,具体原因也没深究),所以采取倒叙遍历
-
for (int i = detailData.size() - 1; i >= 0; i--) {
-
//根据数据长度创建对应行数
-
XWPFTableRow insertNewTableRow = table.insertNewTableRow(2);
-
for (int j = 0; j < 5; j ) {
-
//根据列的数量创建对应单元格
-
insertNewTableRow.createCell();
-
}
-
// 单行渲染数据
-
TableRenderPolicy.Helper.renderRow(table.getRow(2), detailData.get(i));
-
}
-
下面就开始合并同一列下的数据相同的单元格
-
//收集操作列的全部数据,放在List中(我这里需要操作的是第2列数据getCells().get(1))
-
List<String> list = new ArrayList<>();
-
HashMap<String, Object> nameNumMap = new HashMap<>();
-
for (int i = 0; i < detailData.size(); i ) {
-
String typeName = detailData.get(i).getCells().get(1).getParagraphs().get(0).getContents().get(0).toString();
-
list.add(typeName);
-
}
-
//筛选出不同的数据重新放在新list中
-
List<String> collect = list.stream().distinct().collect(Collectors.toList());
-
//统计不同数据在全部数据中出现的次数num,并整合放在map中,后面合并的行数需要用到num
-
for (String s : collect) {
-
for (int i = 0; i < detailData.size(); i ) {
-
String typeName1 = detailData.get(i).getCells().get(1).getParagraphs().get(0).getContents().get(0).toString();
-
if (s == typeName1) {
-
num ;
-
}
-
}
-
nameNumMap.put(s, num);
-
//每统计完一个,需要重置num
-
num = 0;
-
}
-
//开始合并
-
for (String s : collect) {
-
//从我们map中取出刚才放入的单位的个数
-
Integer change = Integer.parseInt(String.valueOf(nameNumMap.get(s)));
-
//开始循环数据
-
//元素第一次出现的位置
-
int firstLocation = list.lastIndexOf(s) 1;
-
int fromRow = firstLocation - change 2;
-
int toRow = list.lastIndexOf(s) 2;
-
//由于TableTools.mergeCellsVertically中参数toRow要大于fromRow,否则会报错,所以num>1的才参与合并
-
if (change > 1) {
-
TableTools.mergeCellsVertically(table, 1, fromRow, toRow);
-
}
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfkjhak
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24