package com.engine.jucailinkq.common.util.excel;

import com.engine.jucailinkq.common.util.DateUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;

import java.util.Date;
import java.util.List;

/**
 * @Author: sy
 * @Description:
 * @Date: 2024/6/5
 **/
public class ExcelUtil {

    public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);
        //遍历设置列宽
        List<Object> header = rowList.get(0);
        for (int i = 0; i < header.size(); i++) {
            sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256);
        }

        for (int rowIndex = 0; rowIndex < rowList.size(); rowIndex++) {
            List<Object> infoList = rowList.get(rowIndex);
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                XSSFCell cell = row.createCell(cellIndex);
                if (rowIndex == 0) {
                    cell.setCellStyle(titleCellStyle);
                } else {
                    cell.setCellStyle(cellStyle);
                }
                Object o = infoList.get(cellIndex);
                if (o instanceof String) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Boolean) {
                    cell.setCellType(CellType.BOOLEAN);
                    cell.setCellValue(String.valueOf(o));
                } else if (o instanceof Date) {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(DateUtil.getFormatLocalDate((Date) o));
                } else {
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(o == null ? "" : o.toString());
                }

                //判断是否要调整高度
                int width = sheet.getColumnWidth(cellIndex) / 256;
                finalHeight = getFinalHeight(o, width, finalHeight, height);
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    public static XSSFWorkbook genWorkbookV2(List<List<Object>> rowList, String sheetName, String title, int titleCellNum) {
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 设置title样式
        XSSFCellStyle titleCellStyle = workbook.createCellStyle();
        XSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontName("仿宋");
        titleFont.setFontHeightInPoints((short) 15);
        titleCellStyle.setFont(titleFont);
        titleCellStyle.setAlignment(HorizontalAlignment.CENTER);
        titleCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//背景色
        titleCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        titleCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleCellStyle.setBorderLeft(BorderStyle.THIN);
        titleCellStyle.setBorderRight(BorderStyle.THIN);
        titleCellStyle.setBorderTop(BorderStyle.THIN);
        titleCellStyle.setBorderBottom(BorderStyle.THIN);


        // 设置主体样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 10);// 设置字体大小
        cellStyle.setFont(font);// 选择需要用到的字体格式
        cellStyle.setWrapText(true);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);

        XSSFSheet sheet = workbook.createSheet(sheetName);
        //自适应宽度
        sheet.autoSizeColumn(0, true);
        //默认列宽
        sheet.setDefaultColumnWidth(20);
        //默认行高
        sheet.setDefaultRowHeightInPoints(18);
        // 合并第一行的前titleCellNum个单元格
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 0, titleCellNum - 1);
        sheet.addMergedRegion(cellRangeAddress);
        //遍历设置列宽
        List<Object> header = rowList.get(0);
        for (int i = 0; i < header.size(); i++) {
            sheet.setColumnWidth(i, Math.max(12, header.get(i).toString().length() * 4) * 256);
        }

        for (int rowIndex = 0; rowIndex <= rowList.size(); rowIndex++) {
            XSSFRow row = sheet.createRow(rowIndex);
            float height = 18;
            float finalHeight = 18;

            if (rowIndex == 0) {
                XSSFCell cell = row.createCell(0);
                cell.setCellStyle(titleCellStyle);
                cell.setCellType(CellType.STRING);
                cell.setCellValue(title);
            } else {
                List<Object> infoList = rowList.get(rowIndex - 1);
                for (int cellIndex = 0; cellIndex < infoList.size(); cellIndex++) {
                    XSSFCell cell = row.createCell(cellIndex);
                    if (rowIndex == 1) {
                        cell.setCellStyle(titleCellStyle);
                    } else {
                        cell.setCellStyle(cellStyle);
                    }
                    Object o = infoList.get(cellIndex);
                    if (o instanceof String) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(String.valueOf(o));
                    } else if (o instanceof Boolean) {
                        cell.setCellType(CellType.BOOLEAN);
                        cell.setCellValue(String.valueOf(o));
                    } else if (o instanceof Date) {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(DateUtil.getFormatLocalDate((Date) o));
                    } else {
                        cell.setCellType(CellType.STRING);
                        cell.setCellValue(o == null ? "" : o.toString());
                    }

                    //判断是否要调整高度
                    int width = sheet.getColumnWidth(cellIndex) / 256;
                    finalHeight = getFinalHeight(o, width, finalHeight, height);
                }
            }
            row.setHeightInPoints(finalHeight);
        }
        return workbook;
    }

    public static float getFinalHeight(Object o, int width, float finalHeight, float height) {
        if (o != null && getStrlength(o.toString()) > width) {
            float remainder = getStrlength(o.toString()) % width;
            int multiple = getStrlength(o.toString()) / width;
            int finalMultiple = remainder > 0 ? (multiple + 1) : multiple;
            float compareHeight = height * finalMultiple;
            finalHeight = Math.max(finalHeight, compareHeight);
        }
        return finalHeight;
    }

    public static int getStrlength(String str) {
        int strLength = 0;
        String chinese = "[\u0391-\uFFE5]";
        /* 获取字段值的长度，如果含中文字符，则每个中文字符长度为2，否则为1 */
        for (int i = 0; i < str.length(); i++) {
            /* 从字符串中获取一个字符 */
            String temp = str.substring(i, i + 1);
            /* 判断是否为中文字符 */
            if (temp.matches(chinese)) {
                /* 中文字符长度为2 */
                strLength += 2;
            } else {
                /* 其他字符长度为1 */
                strLength += 1;
            }
        }
        return strLength;
    }
}
