easyExcel导出包括相同列id相同合并单元格,明细导出

easyExcel导出明细

controller方法

  /**
     * 导出流水明细
     *
     * @return
     */
    @PostMapping("/receipt/statement/detail/export")
    public void export(HttpServletResponse response, @RequestBody ExportDetailDto dto) throws ParseException {
        List<ExportFieldVo> exportField = dto.getExportField();
        List<String> names = exportField.stream().map(ExportFieldVo::getName).toList();
        //查询数据

        List<ExportDetailData> exportDetailData = receiptStatementDetailService.getExportData(dto);


        //  查询
        if (names.contains("明细表")) {
            try {

                int size = names.size() - 1;

                // 设置响应结果
                this.setExcelResponseProp(response, "流水明细");

                List<List<String>> list = generateHeadForDetail(names);
                List<List<Object>> dataList = new ArrayList<>();
                for (ExportDetailData detailData : exportDetailData) {
                    List<ContractInfo> contractInfoList = detailData.getContractInfoList();
                    // List<ProjectInfo> projectInfoList = detailData.getProjectInfoList();
                    if (CollUtil.isEmpty(contractInfoList)) {
                        List<Object> data1 = generateHeadCommon(names, detailData);
                        for (int i = 0; i < 10; i++) {
                            data1.add("");
                        }
                        dataList.add(data1);

                    } else {

                        setContractInfoData(names, dataList, detailData, contractInfoList);

                        // setProjectInfoData(names, dataList, detailData, projectInfoList);
                    }
                }


                WriteCellStyle writeCellStyle = new WriteCellStyle();
                writeCellStyle.setWrapped(true);

                // 每隔2行会合并 把eachColumn 设置成 3 也就是我们数据的长度,所以就第一列会合并。当然其他合并策略也可以自己写
                // LoopMergeStrategy loopMergeStrategy = new LoopMergeStrategy(2, 0);

                HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                        new HorizontalCellStyleStrategy(null, writeCellStyle);

                // 调用合并单元格工具类,此工具类是根据工程名称相同则合并后面数据
                //需要合并的列
                //int[] mergeColumeIndex = {0, 1,2,3,4,5,6,7,8,9,10,11,12};

                //int[] index = generateArray(mergeColumeIndex, size);

                int[] mergeColumnIndex = new int[size];

                for (int i = 0; i < size; i++) {
                    mergeColumnIndex[i] = i;
                }

                //从第1列开始合并
                int mergeRowIndex = 0;
                ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex);

                EasyExcel.write(response.getOutputStream())
                        .head(list)
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        .registerWriteHandler(excelFillCellMergeStrategy)
                        .registerWriteHandler(new AutoColumnWidthHandler())
                        .excelType(ExcelTypeEnum.XLSX)
                        .sheet("流水明细")
                        .doWrite(dataList);
            } catch (IOException e) {
                throw new ServiceException(e);
            }
        } else {
            try {

                // 设置响应结果
                Map<String, String> headMap = new HashMap<>();
                this.setExcelResponseProp(response, "流水明细");
                List<List<String>> list = getHead(names, headMap);

                List<List<Object>> dataList = new ArrayList<>();
                for (ExportDetailData detailData : exportDetailData) {
                    setDataCommonExport(headMap, dataList, detailData);
                }


                WriteCellStyle writeCellStyle = new WriteCellStyle();
                writeCellStyle.setWrapped(true);

                HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                        new HorizontalCellStyleStrategy(null, writeCellStyle);

                EasyExcel.write(response.getOutputStream())
                        .head(list)
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        .registerWriteHandler(new AutoColumnWidthHandler())
                        .excelType(ExcelTypeEnum.XLSX)
                        .sheet("流水明细")
                        .doWrite(dataList);
            } catch (IOException e) {
                throw new ServiceException(e);
            }
        }

    }

ExcelMergeUtil

package com.crfsdi.ocm.receipt.utils;

import com.alibaba.excel.metadata.Head;

import com.alibaba.excel.metadata.data.CellData;

import com.alibaba.excel.metadata.data.WriteCellData;

import com.alibaba.excel.write.handler.CellWriteHandler;

import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;

import com.alibaba.excel.write.metadata.holder.WriteTableHolder;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellType;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public class ExcelMergeUtil implements CellWriteHandler {

private int[] mergeColumnIndex;

private int mergeRowIndex;

public ExcelMergeUtil() {
}

public ExcelMergeUtil(int mergeRowIndex, int[] mergeColumnIndex) {
    this.mergeRowIndex = mergeRowIndex;
    this.mergeColumnIndex = mergeColumnIndex;
}

@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

}

@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

}


public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

}

@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    //当前行
    int curRowIndex = cell.getRowIndex();
    //当前列
    int curColIndex = cell.getColumnIndex();

    if (curRowIndex > mergeRowIndex) {
        for (int i = 0; i < mergeColumnIndex.length; i++) {
            if (curColIndex == mergeColumnIndex[i]) {
                mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                break;
            }
        }
    }
}


/**
 * 当前单元格向上合并
 *
 * @param writeSheetHolder
 * @param cell             当前单元格
 * @param curRowIndex      当前行
 * @param curColIndex      当前列
 */
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
    Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
    Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
    Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
    // 将当前单元格数据与上一个单元格数据比较
    Boolean dataBool = preData.equals(curData);

    String stringCellValue = cell.getRow().getCell(0).getStringCellValue();

    String stringCellValue1 = cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue();

    //此处需要注意:因为我是按照工程名称确定是否需要合并的,所以获取每一行第二列数据和上一行第一列数据进行比较,如果相等合并,getCell里面的值,是工程名称所在列的下标
    Boolean bool = cell.getRow().getCell(0).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue());
    System.out.println("A");
    if (dataBool && bool) {
        Sheet sheet = writeSheetHolder.getSheet();
        List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
        boolean isMerged = false;
        for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
            CellRangeAddress cellRangeAddr = mergeRegions.get(i);
            // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
            if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                sheet.removeMergedRegion(i);
                cellRangeAddr.setLastRow(curRowIndex);
                sheet.addMergedRegion(cellRangeAddr);
                isMerged = true;
            }
        }
        // 若上一个单元格未被合并,则新增合并单元
        if (!isMerged) {
            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
            sheet.addMergedRegion(cellRangeAddress);
        }
    }
}

}

表头设置方法

    private static List<List<String>> getHead(List<String> names, Map<String, String> headMap) {
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        if (names.contains("流水号")) {
            head0.add("流水号");
            list.add(head0);
            headMap.put("流水号", "流水号");
        }

        if (names.contains("金额(元)")) {
            List<String> head1 = new ArrayList<String>();
            head1.add("金额(元)");
            list.add(head1);
            headMap.put("金额(元)", "金额(元)");
        }

        if (names.contains("付款方")) {
            List<String> head2 = new ArrayList<String>();
            head2.add("付款方");
            list.add(head2);
            headMap.put("付款方", "付款方");
        }

        if (names.contains("用途")) {
            List<String> head3 = new ArrayList<String>();
            head3.add("用途");
            list.add(head3);
            headMap.put("用途", "用途");
        }
        if (names.contains("款项类别")) {
            List<String> head4 = new ArrayList<String>();
            head4.add("款项类别");
            list.add(head4);
            headMap.put("款项类别", "款项类别");
        }

        if (names.contains("到款时间")) {
            List<String> head5 = new ArrayList<String>();
            head5.add("到款时间");
            list.add(head5);
            headMap.put("到款时间", "到款时间");
        }

        if (names.contains("转至账户")) {
            List<String> head6 = new ArrayList<String>();
            head6.add("转至账户");
            list.add(head6);
            headMap.put("转至账户", "转至账户");
        }
        if (names.contains("款项类型")) {
            List<String> head7 = new ArrayList<String>();
            head7.add("款项类型");
            list.add(head7);
            headMap.put("款项类型", "款项类型");
        }

        if (names.contains("确认人")) {
            List<String> head8 = new ArrayList<String>();
            head8.add("确认人");
            list.add(head8);
            headMap.put("确认人", "确认人");
        }

        if (names.contains("单位名称")) {
            List<String> head9 = new ArrayList<String>();
            head9.add("单位名称");
            list.add(head9);
            headMap.put("单位名称", "单位名称");
        }

        if (names.contains("附件")) {
            List<String> head10 = new ArrayList<String>();
            head10.add("附件");
            list.add(head10);
            headMap.put("附件", "附件");
        }

        if (names.contains("当前节点")) {
            List<String> head11 = new ArrayList<String>();
            head11.add("当前节点");
            list.add(head11);
            headMap.put("当前节点", "当前节点");
        }

        if (names.contains("审批状态")) {
            List<String> head12 = new ArrayList<String>();
            head12.add("审批状态");
            list.add(head12);
            headMap.put("审批状态", "审批状态");
        }
        return list;
    }
相关推荐
骆晨学长25 分钟前
基于Spring的社区防疫公益管理系统设计与实现
java·开发语言·spring boot·后端·spring
子非吾喵33 分钟前
Spring MVC中实现一个文件上传和下载功能
java·spring·mvc
OLDERHARD1 小时前
Java基础 — 正则表达式+函数式编程
java
百锦再1 小时前
学习Python的难点分析
java·python·学习
灯火不休ᝰ1 小时前
6--苍穹外卖-SpringBoot项目中菜品管理 详解(二)
java·spring boot·后端
埋头编程~2 小时前
【Linux】趣味讲解“权限“的那些事(重点讲解文件权限,内含su、sudo、chmod、chown、umask等指令)
java·linux·运维
J不A秃V头A2 小时前
Java中的继承和实现
java·开发语言
Studying 开龙wu2 小时前
4.3章节python中循环结构:两种类型:for 循环和 while 循环用法
android·java·python
计算机学姐2 小时前
基于基于微信小程序的社区订餐系统
vue.js·spring boot·后端·微信小程序·小程序·intellij-idea·mybatis
zqh176736464692 小时前
阿里云ACP大数据高级工程师知识点,超详细,看完就够了!
java·大数据·阿里云