如何实现:列表导出时,合并单据头字段

1 业务背景
选择列表导出时,是“所见即所得”的。

同时,列表字段中可以选择“单头字段合并”。此时按列表导出,excel的展示如图所示:

但是,这种展示看起来仍不够好看,有些情况下希望做到单据头字段在excel中合并单元格。
2 解决方案
2.1 方案总述
需要编写列表导出插件,在插件中,获取到需要合并的行和列,然后对excel文件进行修改保存。
2.2 实现步骤
2.2.1 前提条件:此方案适用于选中行导出。整体逻辑需要实现在afterExportFile方法中,且修改excel文件使用的是org.apache.poi.xssf.usermodel.XSSFWorkbook类。
/** 导出文件后事件,可以用来修改导出的文件内容,比如修改excel数据、格式、加密等 */
public void afterExportFile(ExportFileEvent e) {}2.2.2 操作步骤
整体分为三步,第一步是获取需要合并的列;第二步是获取到需要合并的行;第三步是通过行和列,进行修改excel。
步骤1: 获取需要合并的列。excel中的列就是苍穹列表中的列表字段。需要合并的列自然就是单据头字段。所以,当前需要的就是获取到列表中的字段是否是单据头字段。
billlistap.getListFields();
通过以上代码可以获取到列表中的字段,然后遍历字段,可以再通过获取实体名称判断此名称是单据的实体名称还是单据体的实体名称来判断是否是单据头的字段。因为单据头字段的实体名称都是单据的实体名称。
步骤2: 获取需要合并的行。这个可以通过列表选中行,获取到选中行的主键。如果选中行的主键和下一行是同一个,那么说明是分录数据,则需要合并(如果是没有分录或者只有一条分录,也就不存在“合并”这个场景了)
步骤3:传入以上两个步骤获取到的行和列,调用XSSFWorkbook类的功能“合并单元格”:
//创建合并样式对象,四个参数从前到后分别为:起始行,终止行,起始列,终止列 CellRangeAddress cellAddresses = new CellRangeAddress(entry.getKey() + 1, entry.getValue() + 1, colmun, colmun); //样式加载 sheet.addMergedRegion(cellAddresses);
步骤4:最后写入excel。
2.3 实现效果
实现效果如下:下图为此插件生效后的样式。可以自行与开始的图片样式比较。

2.3 完整代码
package nm21.cosmic.plugin.list;
import kd.bos.entity.datamodel.ListField;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.form.events.ExportFileEvent;
import kd.bos.list.BillList;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.sdk.plugin.Plugin;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.*;
/**
* 标准单据列表插件
*/
public class ExportTestPlugin extends AbstractListPlugin implements Plugin {
@Override
public void afterExportFile(ExportFileEvent e) {
super.afterExportFile(e);
//计算需要合并的列
List<Integer> colmuns = calColumns();
//计算需要合并的行
Map<Integer, Integer> rowMap = calRows();
//导出修改的excel
modifyExcel(e, colmuns, rowMap);
}
private void modifyExcel(ExportFileEvent e, List<Integer> colmuns, Map<Integer, Integer> rowMap) {
//如果没有需要合并的列或者没有需要合并的行,那说明没有必要合并
if (colmuns.size() <= 0 || rowMap.size() <= 0) return;
//修改excel
File file = e.getFile();
if (file != null) {
try (FileInputStream fis = new FileInputStream(file);) {
Workbook wb = new XSSFWorkbook(fis);
Sheet sheet = wb.getSheetAt(0);
//遍历列
for (Integer colmun : colmuns) {
//遍历行
Set<Map.Entry<Integer, Integer>> entries = rowMap.entrySet();
for (Map.Entry<Integer, Integer> entry :
entries) {
//创建合并样式对象,四个参数从前到后分别为:起始行,终止行,起始列,终止列
CellRangeAddress cellAddresses = new CellRangeAddress(entry.getKey() + 1, entry.getValue() + 1, colmun, colmun);
//样式加载
sheet.addMergedRegion(cellAddresses);
}
}
// 保存
FileOutputStream out = new FileOutputSt如何实现:列表导出时,合并单据头字段
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。



