package cn.com.capcloud.core.execl.xlsx;

import cn.com.capcloud.ccui.core.common.json.JackJSONArray;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.*;

public class ExcelUtil {
    public static int DEFAULT_COLOUMN_WIDTH = 17;
    /**
     * 导出Excel 2007 OOXML (.xlsx)格式
     * @param headMap 属性-列头
     * @param jsonArray 数据集
     * @param colWidth 列宽 默认 至少17个字节
     * @param out 输出流
     */
    public static void exportExcelX(String sheetName, Map<String, Object> headMap, JackJSONArray jsonArray, int colWidth, OutputStream out) {
        // 声明一个工作薄
        SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//缓存
        workbook.setCompressTempFiles(true);
        // 列头样式
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setFontHeightInPoints((short) 16);//字体大小
        headerStyle.setFont(headerFont);
        headerStyle.setFillBackgroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex());//设置背景色
        headerStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex());//设置前景色
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 单元格样式
        CellStyle cellStyle = workbook.createCellStyle();
        Font cellFont = workbook.createFont();
        cellFont.setFontHeightInPoints((short) 12);
        cellStyle.setFont(cellFont);
        // 生成一个表格
        SXSSFSheet sheet = workbook.createSheet();
        //设置列宽
        int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少字节数
        int[] arrColWidth = new int[headMap.size()];
        // 产生表格标题行,以及设置列宽
        String[] properties = new String[headMap.size()-1];//headMap要减一,headMap里存了一个headList
        String[] headers = new String[headMap.size()-1];
        int ii = 0;
        List<String> headList= (List<String>) headMap.get("headList");
        for (int i = 0; i < headList.size(); i++) {
            String fieldName=String.valueOf(headMap.get(headList.get(i)));
            properties[ii] = headList.get(i);
            headers[ii] = fieldName;
            int bytes = fieldName.getBytes().length;
            arrColWidth[ii] = bytes < minBytes ? minBytes : bytes;
            sheet.setColumnWidth(ii,arrColWidth[ii]*256);
            ii++;
        }
        // 遍历集合数据，产生数据行
        int rowIndex = 0;
        if(jsonArray.size()==0){
            SXSSFRow headerRow = sheet.createRow(0); //列头 rowIndex =0
            for(int i=0;i<headers.length;i++){
                headerRow.createCell(i).setCellValue(headers[i]);
                headerRow.getCell(i).setCellStyle(headerStyle);
            }
        }else{
            for (Object obj : jsonArray) {
                //一页展示显示全部
                if(rowIndex == 0){
                    SXSSFRow headerRow = sheet.createRow(0); //列头 rowIndex =0
                    for(int i=0;i<headers.length;i++){
                        headerRow.createCell(i).setCellValue(headers[i]);
                        headerRow.getCell(i).setCellStyle(headerStyle);
                    }
                    rowIndex = 1;
                }
                JackJSONObject jo = JackJSONObject.fromObject(obj);
                SXSSFRow dataRow = sheet.createRow(rowIndex);
                for (int i = 0; i < properties.length; i++){
                    SXSSFCell newCell = dataRow.createCell(i);
                    Object o = jo.get(properties[i]);
                    String cellValue = "";
                    if(o==null){
                        cellValue = "";
                    } else if(o instanceof Float || o instanceof Double){
                        cellValue= new BigDecimal(o.toString()).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
                    }else{
                        cellValue = o.toString();
                    }
                    int maxLength = 32767; // 单元格内容的最大字符数限制（Excel 规定的最大字符数）
                    if (cellValue.length() > maxLength) {
                        // 截取文本，保留最大允许的长度，并加上省略号和提示信息
                        // 这里的32767字符限制来源于Excel的限制，单个单元格的文本最多只能包含32,767个字符
                        // 超过这个长度会导致报错，因此我们需要做截断处理
                        cellValue = cellValue.substring(0, maxLength - 15) + "...（内容过长，已省略）";  // 截取并加详细提示
                    }
                    newCell.setCellValue(cellValue);
                    newCell.setCellStyle(cellStyle);
                }
                rowIndex++;
            }
        }
        try {
            workbook.setSheetName(0,sheetName);
            workbook.write(out);
            workbook.close();
            workbook.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
