easyexcle处理导出合并单元格图片填充

发布时间:2023年12月21日
@GetMapping("getStyleSummaryExport")
@ApiOperation("款式汇总报表--导出")
@ApiImplicitParams({
        @ApiImplicitParam(name = Constant.PAGE, value = "当前页码,从1开始", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = Constant.LIMIT, value = "每页显示记录数", paramType = "query", dataType = "int"),
        @ApiImplicitParam(name = Constant.ORDER_FIELD, value = "排序字段", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = Constant.ORDER, value = "排序方式,可选值(asc、desc)", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "season", value = "季节", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "batch", value = "批次", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "series", value = "系列", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "styleNo", value = "款号", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "brand", value = "品牌", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "stage", value = "阶段", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "materialNo", value = "主身面料编号", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "supplier", value = "供应商", paramType = "query", dataType = "String"),
        @ApiImplicitParam(name = "shipmentDate", value = "上货日期", paramType = "query", dataType = "Date"),
        @ApiImplicitParam(name = "ids", value = "勾选列表id,多个逗号隔开", paramType = "query", dataType = "String")
})
public void getStyleSummaryExport(@ApiIgnore @RequestParam Map<String, Object> params, HttpServletResponse response) throws Exception {
    if(!ParamUtil.paramsIsNotNull(params,"limit") || !ParamUtil.paramsIsNotNull(params,"page")){
        params.put("limit", "1000");
        params.put("page", "1");
    }
    if(ParamUtil.paramsIsNotNull(params, "ids")){
        params.put("ids", Arrays.asList(params.get("ids").toString().split(",")));
    }else {
        params.remove("ids");
    }
    List<StyleSummaryDTO> list = styleSummaryService.getStyleSummaryReportPage(params).getList();
    List<List<Object>> resList = new ArrayList<>();
    //合并图片问题
    List<Integer> imgCount = new ArrayList<>();
    //合并的行
    List<Integer> merge = new ArrayList<>();
    AtomicInteger index = new AtomicInteger();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    if(CollectionUtils.isNotEmpty(list)) {
        list.forEach(e ->{
            if(CollectionUtils.isNotEmpty(e.getItemList())){
                for (int i = 0; i < e.getItemList().size(); i++) {
                    index.addAndGet(1);
                    if(i > 0){
                        merge.add(index.intValue());
                    }
                    List<Object> itemList = new ArrayList<>();
                    if (i == 0 && CollectionUtils.isNotEmpty(e.getStyleUrlList())){
                        try {
                            itemList.add(new URL(e.getStyleUrlList().get(0).getUrl()));
                            imgCount.add(e.getItemList().size());
                        } catch (MalformedURLException malformedURLException) {
                            log.info(malformedURLException.getMessage());
                        }
                    }else {
                        itemList.add("");
                    }
                    itemList.add(e.getBrand());
                    itemList.add(e.getSeason());
                    itemList.add(e.getStage());
                    itemList.add(e.getYbType());
                    itemList.add(e.getBatch());
                    itemList.add(e.getSeries());
                    itemList.add(e.getStyleNo());
                    if(e.getShipmentDate() != null){
                        itemList.add(simpleDateFormat.format(e.getShipmentDate()));
                    }else {
                        itemList.add("");
                    }
                    itemList.add(e.getItemList().get(i).getMaterialNo());
                    itemList.add(e.getItemList().get(i).getSupplier());
                    resList.add(itemList);
                }
            }else {
                index.addAndGet(1);
                List<Object> itemList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(e.getStyleUrlList())){
                    try {
                        itemList.add(new URL(e.getStyleUrlList().get(0).getUrl()));
                        imgCount.add(1);
                    } catch (MalformedURLException malformedURLException) {
                        log.info(malformedURLException.getMessage());
                    }
                }else {
                    itemList.add("");
                }
                itemList.add(e.getBrand());
                itemList.add(e.getSeason());
                itemList.add(e.getStage());
                itemList.add(e.getYbType());
                itemList.add(e.getBatch());
                itemList.add(e.getSeries());
                itemList.add(e.getStyleNo());
                if(e.getShipmentDate() != null){
                    itemList.add(simpleDateFormat.format(e.getShipmentDate()));
                }else {
                    itemList.add("");
                }
                resList.add(itemList);
            }
        });
    }
    response.setContentType("application/json;charset=utf-8");
    response.setCharacterEncoding("UTF-8");
    String fileName = URLEncoder.encode("开发款式汇总导出-"+  DateUtils.format(new Date()), "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    ExcelWriter excelWriter = null;
    try{
        excelWriter = EasyExcel.write(response.getOutputStream()).build();
        //excelWriter = EasyExcel.write("D:\\2023\\test222111.xlsx").build();
        if(null != excelWriter) {
            //需要合并的列
            int[] mergeColumeIndex = {0,1,2,3,4,5,6,7,8};
            // 从那一列开始合并
            int mergeRowIndex = 1;
            // 内容的策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.index);
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
            List<List<String>> userHeadList = getHeader();
            WriteSheet writeSheet = EasyExcel.writerSheet( "开发款式汇总").head(userHeadList)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new CustomCellWeightWeightForDevStyleUtil())
                    .registerWriteHandler(new MergeSameRowsStrategy(mergeRowIndex, mergeColumeIndex, merge))
                    .registerWriteHandler(new StyleImageCellWriteHandler(imgCount))
                    .build();
            excelWriter.write(resList, writeSheet);
        }
    }finally {
        //关闭流
        if(excelWriter != null){
            excelWriter.finish();
        }
    }
}

package com.jack.modules.dsr.common.utils;

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.commons.collections.CollectionUtils;
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;

@Data
public class MergeSameRowsStrategy implements CellWriteHandler{
    private int[] mergeColumnIndex;
    private int mergeRowIndex;
    private List<Integer> merge;

    public MergeSameRowsStrategy() {
    }
    public MergeSameRowsStrategy(int mergeRowIndex, int[] mergeColumnIndex, List<Integer> merge) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
        this.merge = merge;
    }


    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        if (CollectionUtils.isNotEmpty(merge)){
            // 当前行
            int curRowIndex = cell.getRowIndex();
            if (merge.contains(curRowIndex)){
                // 当前列
                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 sheet保持对象
     * @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();
        if (cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex) == null){
            return;
        }
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();

        // 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
        if (curData.equals(preData) || ("0.0".equals(preData.toString()) && "".equals(curData))) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergedRegions.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);
            }
        }
    }

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

    }

    @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) {

    }

}

package com.jack.modules.dsr.common.handler;

import com.alibaba.excel.enums.CellDataTypeEnum;
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.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;

import java.util.ArrayList;
import java.util.List;

/**
 * EasyExcel图片填充拦截器
 *
 * @author piyc
 */
@Data
public class StyleImageCellWriteHandler implements CellWriteHandler {


    private List<Integer> imgCount;

    public StyleImageCellWriteHandler() {
    }
    public StyleImageCellWriteHandler(List<Integer> imgCount) {
        this.imgCount = imgCount;
    }

    int zab = 0;
    List<byte[]> imageList = new ArrayList<>();


    @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 afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        // 在 数据转换成功后 ,修改第一列 当然这里也可以根据其他判断 然后不是头 就把类型设置成空 这样easyexcel 不会去处理该单元格
        if (head.getColumnIndex() != 0 || aBoolean) {
            return;
        }
        if (cellData.getImageValue() != null && cellData.getImageValue().length > 0){
            cellData.setType(CellDataTypeEnum.EMPTY);
        }
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        // 在 单元格写入完毕后 ,自己填充图片
        if (head.getColumnIndex() != 0 || aBoolean || CollectionUtils.isEmpty(list) || list.get(0) == null) {
            return;
        }
        if (list.get(0).getStringValue() != null && StringUtils.isNotEmpty(list.get(0).getStringValue())){
            list.get(0).setType(CellDataTypeEnum.STRING);
            return;
        }

        Sheet sheet = cell.getSheet();
        // cellDataList 是list的原因是 填充的情况下 可能会多个写到一个单元格 但是如果普通写入 一定只有一个
        if (list.get(0).getImageValue() != null && list.get(0).getImageValue().length > 0){
            int index = sheet.getWorkbook().addPicture(list.get(0).getImageValue(), HSSFWorkbook.PICTURE_TYPE_PNG);
            Drawing drawing = sheet.getDrawingPatriarch();
            if (drawing == null) {
                drawing = sheet.createDrawingPatriarch();
            }
            CreationHelper helper = sheet.getWorkbook().getCreationHelper();
            ClientAnchor anchor = helper.createClientAnchor();
            // 设置图片坐标
            anchor.setDx1(0);
            anchor.setDx2(0);
            anchor.setDy1(0);
            anchor.setDy2(0);
            //设置图片位置
            anchor.setCol1(cell.getColumnIndex());
            anchor.setCol2(cell.getColumnIndex() +1);
            anchor.setRow1(cell.getRowIndex());
            if (head.getColumnIndex() == 0 && CollectionUtils.isNotEmpty(imgCount)){
                anchor.setRow2(cell.getRowIndex() + imgCount.get(zab));
                zab++;
            } else {
                anchor.setRow2(cell.getRowIndex() + 1);
            }
            // 设置图片可以随着单元格移动
            anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
            drawing.createPicture(anchor, index);
        }
    }
}
package com.jack.modules.dsr.common.utils;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.nacos.common.utils.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;

import java.util.List;

public class CustomCellWeightWeightForDevStyleUtil extends AbstractColumnWidthStyleStrategy {

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
        if (needSetWidth) {
            Sheet sheet = writeSheetHolder.getSheet();
            int columnIndex = cell.getColumnIndex();
            if (columnIndex == 0 || columnIndex == 6 || columnIndex == 7 || columnIndex == 8 || columnIndex == 9 || columnIndex == 10){
                sheet.setColumnWidth(columnIndex,4576);
            }
        }
    }
}
文章来源:https://blog.csdn.net/piyingcheng/article/details/135130241
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。