easyExcel自定义合并单元格导出

依赖包
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version>
</dependency>
Controller导出代码
/**
 * 导出
 *
 * @return
 */
@ApiOperation(value = "导出", notes = "导出", httpMethod = "GET")
@RequestMapping(value = "/export", method = RequestMethod.GET, produces = CTRL_PRODUCE)
public void export(HttpServletResponse response) throws IOException {
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    String fileName = "供应商评价汇总表" + LocalDate.now();
    fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    ExcelWriter excelWriter = null;
    try {
        //需要合并的列 (0,1,2 表示合并第一、二、三列)
        int[] mergeColumnIndex = {0, 1, 2};
        // 从第二行后开始合并
        int mergeRowIndex = 1;
        // 合并依据的列(0标识依据第一列合并)
        int mergeBaseIndex = 0;
        excelWriter = EasyExcel.write(response.getOutputStream()).build();
        // 写入第一个sheet
        WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet1").build();
        WriteTable writeTable = EasyExcel.writerTable(0).head(ExcelDto.class)
        .registerWriteHandler(new ExcelColumnWidth())
        .registerWriteHandler(new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex, mergeBaseIndex))
        .registerWriteHandler(ExcelMergeUtil.getStyleStrategy())
        .needHead(true).build();
        // getDataList() 获取的结果集
        excelWriter.write(getDataList(), writeSheet, writeTable);
        // 写入第二个sheet
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "sheet2").build();
        WriteTable writeTable1 = EasyExcel.writerTable(1).head(ExcelDto.class)
                .registerWriteHandler(new ExcelColumnWidth())
                .registerWriteHandler(new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex, mergeBaseIndex))
                .registerWriteHandler(ExcelMergeUtil.getStyleStrategy()))
                .needHead(true).build();
        excelWriter.write(getDataList(), writeSheet1, writeTable1);
        // 写入第三个sheet
        WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "sheet3").build();
        WriteTable writeTable2 = EasyExcel.writerTable(2).head(ExcelDto.class)
                .registerWriteHandler(new ExcelColumnWidth())
                .registerWriteHandler(new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex, mergeBaseIndex))
                .registerWriteHandler(ExcelMergeUtil.getStyleStrategy())
                .needHead(true).build();
        excelWriter.write(getDataList(), writeSheet2, writeTable2);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        Objects.requireNonNull(excelWriter).finish();
    }
}
表头 ExcelDto
package com.yunshang.service.modules.web.sysSupplier.dto;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class ExcelDto {

    @ExcelProperty({"一阶段评价", "供应商名称"})
    private String gysmc;

    @ExcelProperty({"一阶段评价", "累计合同数量"})
    private Integer ljhtsl;

    @ExcelProperty({"一阶段评价", "项目"})
    private String xm;

    @ExcelProperty({"一阶段评价", "设备名称"})
    private String sbmc;

    @ExcelProperty({"二阶段评价", "售后服务"})
    private String shfw;

    @ExcelProperty({"二阶段评价", "二阶段项目得分"})
    private String ejdxmzhdf;

    @ExcelProperty({"二阶段评价", "二阶段综合得分"})
    private String ejdzhdf;

}

设置列宽和默认行高 ExcelColumnWidth
package com.yunshang.service.modules.web.sysSupplier.entity;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;

import java.util.List;

public class ExcelColumnWidth  extends AbstractColumnWidthStyleStrategy {
    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> list, Cell cell, Head head,
                                    Integer integer, Boolean isHead) {
        //宽度定制.
        if (isHead && cell.getRowIndex() == 1) {
            int columnWidth = cell.getStringCellValue().getBytes().length;
            int cellIndex = cell.getColumnIndex();
            switch (cellIndex) {
                // 第一列列宽,下面以此类推
                case 0:
                    columnWidth = 35;
                    break;
                case 1:
                    columnWidth = 18;
                    break;
                case 2:
                    columnWidth = 20;
                    break;
                case 3:
                    columnWidth = 15;
                    break;
                default:
                    columnWidth = 15;
                    break;
            }
            writeSheetHolder.getSheet().setColumnWidth(cellIndex, columnWidth * 256);
            // 设置默认行高
            writeSheetHolder.getSheet().setDefaultRowHeight((short)(2* 200));
        }
    }
}
合并工具类 ExcelMergeUtil
package com.yunshang.service.modules.web.sysSupplier;


import com.alibaba.excel.metadata.Head;
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;
    //合并依据列
    private int mergeBaseIndex;

    public ExcelMergeUtil() {
    }

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

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {

    }

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

    }

    @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, mergeBaseIndex);
                    break;
                }
            }
        }
    }


    /**
     * 当前单元格向上合并
     *
     * @param writeSheetHolder sheet
     * @param cell             当前单元格
     * @param curRowIndex      当前行
     * @param curColIndex      当前列
     */
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex, int mergeBaseIndex) {
        Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellType() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
        // 将当前单元格数据与上一个单元格数据比较
        Boolean dataBool = preData.equals(curData);
        // 判断合并依据的列是否相同
        Boolean bool =  cell.getRow().getCell(mergeBaseIndex).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(mergeBaseIndex).getStringCellValue());
        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);
            }
        }
    }

    
    public static HorizontalCellStyleStrategy getStyleStrategy() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 设置对齐
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 背景色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontHeightInPoints((short) 10);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        //设置 自动换行
        contentWriteCellStyle.setWrapped(true);
        //设置 垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置 水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //设置边框样式
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
}
数据处理 getDataList
 private List<ExcelDto> getDataList() {
    List<ExcelDto> excelDtos = new ArrayList<>();
    // 自行处理
    return excelDtos;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
EasyExcel中,自定义合并单元格策略可以通过实现`com.alibaba.excel.metadata.CellStrategy`接口来实现。可以参考上面提到的技术斩博主的自定义策略进行优化。 具体步骤如下: 1. 创建一个类,实现`CellStrategy`接口,并重写`merge(CellRangeAddress cellRangeAddress, Sheet sheet)`方法。 2. 在`merge()`方法中,根据自定义合并单元格规则,通过`cellRangeAddress`参数来确定需要合并的单元格范围,然后通过`sheet`对象进行单元格合并操作。 3. 根据需要,在自定义策略中添加其他的处理逻辑,例如设置合并后单元格的样式等。 4. 在使用EasyExcel进行导出时,通过`excelWriter.setCustomCellWriteHandler()`方法来设置自定义合并单元格策略。 请注意,以上步骤仅是一种实现自定义合并单元格策略的方法,具体的实现方式可能会因项目需求而有所不同。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [利用easyExcel导出上万条数据,自定义策略合并单元格](https://download.csdn.net/download/qq_32734167/13408705)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [EasyExcel合并单元格,通过注解方式实现自定义合并策略](https://blog.csdn.net/q1468051413/article/details/127832071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值