poi-tl 循环表格合并重复项
2023-02-18 00:00:00
poi
官网表格行循环: http://deepoove.com/poi-tl/#hack-loop-table
下面展示一些 内联代码片
。
创建类工具类:RowspanPolicy
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import java.util.List;
import java.util.Map;
/**
* 根据,字段值判断是否合并单元格,
* Results 泛型传入实体类,
* 0 为第0列(列下标)
* “type” 为字段名称
* 使用方式如下
* new RowspanPolicy<Results>(0, "type")
* <p>
* 仅适需要于用实体类列表循环的表格
* 循环单元格,改变字体颜色等,为完成
*/
public class RowspanPolicy<T> extends HackLoopTableRenderPolicy {
private int rowIndex;
private String fieldName;
public RowspanPolicy2(boolean onSameLine) {
this("[", "]", onSameLine, 0, "");
}
public RowspanPolicy2(int rowIndex, String fieldName) {
this("[", "]", false, rowIndex, fieldName);
}
public RowspanPolicy2(String prefix, String suffix) {
this(prefix, suffix, false, 0, "");
}
public RowspanPolicy2(String prefix, String suffix, boolean onSameLine, int rowIndex, String fieldName) {
super(prefix, suffix, onSameLine);
this.rowIndex = rowIndex;
this.fieldName = fieldName;
}
protected void afterloop(XWPFTable table, Object data) {
if (null == data) return;
if (null == fieldName || "".equals(fieldName)) return;
List<T> list = (List<T>) data;
String curr = null;
int count = 0;//重复数量
for (int i = 0; i < list.size(); i++) {
String str = getFieldValue(list.get(i), fieldName);
if (curr == null) {
curr = str;
count = 1;
} else if (curr.equals(str)) {
++count;
} else {
mergeCellsVertically(table, rowIndex, i, count);
curr = str;
count = 1;
}
}
mergeCellsVertically(table, rowIndex, list, count);
}
/**
* 合并行
*
* @param rowIndex 列
* @param index 重复行下标
* @param count 重复数量
*/
static void mergeCellsVertically(XWPFTable table, int rowIndex, int index, int count) {
if (count > 1) TableTools.mergeCellsVertically(table, rowIndex, index - count + 1, index);
}
static <T> void mergeCellsVertically(XWPFTable table, int rowIndex, List<T> list, int count) {
if (count > 1) TableTools.mergeCellsVertically(table, rowIndex, list.size() - count + 1, list.size());
}
/**
* 获取值,判断是重复
*
* @param target 数据源
* @param fieldName 字段名
* @return 值
*/
public String getFieldValue(Object target, String fieldName) {
try {
if (target instanceof Map) {
return ((Map<?, ?>) target).get(fieldName).toString();
}
Object HSSFCell = FieldUtils.readField(target, fieldName, true);
if (HSSFCell instanceof String) {
return (String) HSSFCell;
}
TextRenderData textRenderData = (TextRenderData) HSSFCell;
return textRenderData.getText();
} catch (IllegalAccessException e) {
throw new RuntimeException("字段类型不匹配,请检查字段类型和实体类是否一致");
}
}
}
应用示例
//第1列,0为下标需要-1
//字段名为name
//TableData: 实体类名称,如果使用的是map 传入map
RowspanPolicy<TableData> rowspanPolicy = new RowspanPolicy<>(0, "name");
RowspanPolicy<Map> rowspanPolicy = new RowspanPolicy<>(0, "name");
Configure.builder().bind("tableData", rowspanPolicy).build();
实现思路:
1.基础原来的循环组件,在循环结束的地方重写 afterloop 方法
2.通过循环判断当前字段是否于上一个字段内容一致,
3.发现不一致的就合并上一组数据,结束时合并未循环的数据
注意
数据合并之前要先按照要合并的列排序
只能合并相邻并且内容一致的数据
原文作者:年少一去不复返
原文地址: https://blog.csdn.net/qq_44810112/article/details/123496591
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/qq_44810112/article/details/123496591
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章