package com.unis.framework.excel.core.handler;


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 org.apache.poi.xssf.usermodel.XSSFCell;

import java.util.List;


/**
 * @author: duhuajie
 * @create: 2024-04-15
 * @description:
 *      合并Excel单元格（纵向）处理器 <br/>
 *      用法： <br/>
 *      ExcelWriter excelWriter = EasyExcel.write(filePath) <br/>
 *                 .registerWriteHandler(new MyExcelMergeCell(2)) //注入处理器<br/>
 *                 .withTemplate(templateFilePath).build();<br/>
 */
public class MyExcelMergeCellHandler implements CellWriteHandler {

    /**
     * 列数超过这个值之后不做合并
     */
    private int firstIndex = 0;
    private List<Integer> strnumToNumColumnIndex;

    public MyExcelMergeCellHandler() {
    }

    public MyExcelMergeCellHandler(int firstIndex) {
        this.firstIndex = firstIndex;
    }
    public MyExcelMergeCellHandler(int firstIndex, List<Integer> strnumToNumColumnIndex) {
        this.firstIndex = firstIndex;
        this.strnumToNumColumnIndex = strnumToNumColumnIndex;
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex,
                                 Boolean isHead) {
        /* 处理单独的列，文本型数字转换成数字型 */
        //如果当前列大于2，不做处理
        if(strnumToNumColumnIndex != null && !strnumToNumColumnIndex.isEmpty() && strnumToNumColumnIndex.contains(cell.getColumnIndex())){
            if(cell.getCellType() == CellType.STRING) {
                String content = cell.getStringCellValue();
                if (content != null && content.matches("-?\\d+(\\.\\d+)?")) {
                    if (cell instanceof XSSFCell) {
                        XSSFCell xssfCell = (XSSFCell) cell;
                        xssfCell.setCellType(CellType.NUMERIC);
                        xssfCell.setCellValue(Double.parseDouble(content));
                    }
                }
            }
        }

        /* 下面是处理合并单元格 */
        if (isHead) {
            //如果是表头不做处理
            return;
        }
        //如果当前是第一行不做处理
        if (relativeRowIndex == null || relativeRowIndex == 0) {
            return;
        }

        //如果当前列大于2，不做处理
        if (cell.getColumnIndex() >= firstIndex) {
            return;
        }

        //获取当前行下标，上一行下标，上一行对象，上一列对象
        Sheet sheet = cell.getSheet();
        int rowIndex = cell.getRowIndex();
        int rowIndexPrev = rowIndex - 1;
        Row row = sheet.getRow(rowIndexPrev);
        Cell cellPrev = row.getCell(cell.getColumnIndex());

        //得到当前单元格值和上一行单元格
        Object cellValue = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
        Object cellValuePrev = cellPrev.getCellType() == CellType.STRING ? cellPrev.getStringCellValue() : cellPrev.getNumericCellValue();

        //如果当前单元格和上一行单元格值相等就合并
        if (!cellValue.equals(cellValuePrev)) {
            return;
        }

        //获取已有策略
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
        // 这段代码是有合并的单元格，（三行合并），获取左上角信息，并入当前单元格，更新LastRow
        boolean mergn = false;
        for (int i = 0; i < mergedRegions.size(); i++) {
            CellRangeAddress cellAddresses = mergedRegions.get(i);
            if (cellAddresses.isInRange(rowIndexPrev, cell.getColumnIndex())) {
                sheet.removeMergedRegion(i);
                cellAddresses.setLastRow(rowIndex);
                sheet.addMergedRegion(cellAddresses);
                mergn = true;
                break;
            }

        }
        if (!mergn) {
            CellRangeAddress cellAddresses = new CellRangeAddress(rowIndexPrev, rowIndex, cell.getColumnIndex(), cell.getColumnIndex());
            sheet.addMergedRegion(cellAddresses);
        }

    }


}