easyExcel导出合并指定的单元格

项目中需要导出并合并指定的单元格,直接上代码:

/**
 * 项目列表导出
 */

@GetMapping("v1/export_excel.do")
@ApiOperation(value = "项目导出", httpMethod = "GET")
@CrossOrigin
public void excel(@RequestParam("id") String id, HttpServletResponse response) throws IOException {
       //查询需要导出的数据
       List<ExcelInfo> excelInfos = projectService.getExcelInfo(Long.valueOf(id));
       try {
              //需要合并的列
              int[] mergeColumeIndex = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
              //从哪一列开始合并
              int mergeRowIndex = 0;
              //项目名称
              String projectName = "空项目";
              if (DggCollectionUtils.isNotEmpty(excelInfos)){
                     projectName = excelInfos.get(0).getProjectName();
              }
              response.setHeader("content-Type", "application/vnd.ms-excel");
              response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(projectName + LocalDate.now(), "UTF-8") + ".xlsx");
              response.setCharacterEncoding("UTF-8");
              EasyExcel.write(response.getOutputStream(), ExcelInfo.class)
                      .excelType(ExcelTypeEnum.XLSX).head(ExcelInfo.class)
                      //这里如果需要设置标题请放开,设置自定义标题
                      //.registerWriteHandler(new TitleSheetWriteHandler("我是一个小标题",2)) // 标题及样式,lastCol为标题第0列到底lastCol列的宽度
                      //设置默认样式及写入头信息开始的行数
                      .relativeHeadRowIndex(0)
                      .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumeIndex))
                      .sheet(projectName)
                      .doWrite(excelInfos);
       }catch (Exception e) {
              e.printStackTrace();
              response.reset();
              response.setCharacterEncoding("utf-8");
              response.setContentType("application/json");
              response.getWriter().println("打印失败");
       }

}

/**
 * @program: pms-service
 * @Description: excel导出数据
 * @Author: zwx
 * @Date: 2021/7/9 13:44
 */
@Data
public class ExcelInfo {

    /**
     * 项目编号
     */
    @ExcelProperty(value = {"项目编号"}, index = 0)
    private String projectCode;
    /**
     * 项目名称
     */
    @ExcelProperty(value = {"项目名称"}, index = 1)
    private String projectName;

    /**
     * 所属板块
     */
    @ExcelProperty(value = {"所属板块"}, index = 2)
    private String projectSectionName;
    /**
     * 项目来源
     */
    @ExcelProperty(value = {"项目来源"}, index = 3)
    private String projectSourceName;

    /**
     * 项目级别
     */
    @ExcelProperty(value = {"项目级别"}, index = 4)
    private String projectLevelName;

    /**
     * 项目周期
     */
    @ExcelProperty(value = {"项目周期"}, index = 5)
    private String projectCycleName;
    /**
     * 关联OKR
     */
    @ExcelProperty(value = {"关联OKR"}, index = 6)
    private String relatedOkr;
    /**
     * 项目进度
     */
    @ExcelProperty(value = {"项目进度百分比"}, index = 7)
    private String projectRateName;

    /**
     * 项目计划开始日期
     */
    @ExcelProperty(value = {"项目计划开始日期"}, index = 8)
    private String projectStartDate;
    /**
     * 项目计划结束日期
     */
    @ExcelProperty(value = {"项目计划结束日期"}, index = 9)
    private String projectEndDate;

    /**
     * 项目完成时间
     */
    @ExcelProperty(value = {"项目完成时间"}, index = 10)
    private String projectRealTime;
    /**
     * 项目进度情况
     */
    @ExcelProperty(value = {"项目进度情况"}, index = 11)
    private String progressName;

    /**
     * 项目负责人/工号
     */
    @ExcelProperty(value = {"项目负责人/工号"}, index = 12)
    private String projectManagerName;
    /**
     * 项目状态
     */
    @ExcelProperty(value = {"项目状态"}, index = 13)
    private String projectStatusName;

    /**
     * 项目是否超期
     */
    @ExcelProperty(value = {"项目是否超期"}, index = 14)
    private String projectOverdueName;

    /**
     * 项目里程碑名称
     */
    @ExcelProperty(value = {"里程碑"}, index = 15)
    private String milepostName;
    /**
     * 任务标题
     */
    @ExcelProperty(value = {"任务标题"}, index = 16)
    private String title;
    /**
     * 任务内容
     */
    @ExcelProperty(value = {"任务内容"}, index = 17)
    private String content;
    /**
     * 交付标准
     */
    @ExcelProperty(value = {"交付标准"}, index = 18)
    private String deliverSdd;

    /**
     * 交付成果
     */
    @ExcelProperty(value = {"交付成果"}, index = 19)
    private String deliverAch;
    /**
     * 是否关键任务
     */
    @ExcelProperty(value = {"是否关键任务"}, index = 20)
    private String taskCruxName;

    /**
     * 是否需要评审
     */
    @ExcelProperty(value = {"是否需要评审"}, index = 21)
    private String taskDemandReviewName;

    /**
     * 任务进度
     */
    @ExcelProperty(value = {"任务进度"}, index = 22)
    private String taskProgress;
    /**
     * 任务负责人/工号
     */
    @ExcelProperty(value = {"任务负责人/工号"}, index = 23)
    private String taskDirectorName;
    /**
     * 任务计划开始时间
     */
    @ExcelProperty(value = {"任务计划开始时间"}, index = 24)
    private String startDate;
    /**
     * 任务计划结束时间
     */
    @ExcelProperty(value = {"任务计划结束时间"}, index = 25)
    private String endDate;
    /**
     * 任务实际完成时间
     */
    @ExcelProperty(value = {"任务实际完成时间"}, index = 26)
    private String finishDate;
    /**
     * 任务是否超期
     */
    @ExcelProperty(value = {"任务是否超期"}, index = 27)
    private String taskOvertime;
    /**
     * 任务创建时间
     */
    @ExcelProperty(value = {"任务创建时间"}, index = 28)
    private String taskCreateTime;
    /**
     * 任务创建人
     */
    @ExcelProperty(value = {"任务创建人"}, index = 29)
    private String taskCreateName;

}

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.Data;
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;

/**
 * @program: pms-service
 * @Description: 自定义合并单元格列
 * @Author: zwx
 * @Date: 2021/7/11 17:12
 */
@Data
public class ExcelFillCellMergeStrategy implements CellWriteHandler {
    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public ExcelFillCellMergeStrategy() {
    }

    public ExcelFillCellMergeStrategy(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) {

    }

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

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        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();
        // 将当前单元格数据与上一个单元格数据比较
        if (preData.equals(curData)) {
            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);
            }
        }
    }
}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值