package com.gyee.frame.common.file;

import com.gyee.frame.util.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;

import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author：
 * @Date：
 * @Description：Excel导出工具类，依赖于ClassUtil工具类
 */
public final class ExcelExport {

    /**
     * 将传入的数据导出excel表并下载
     * @param response 返回的HttpServletResponse
     * @param importlist 要导出的对象的集合
     * @param attributeNames 含有每个对象属性在excel表中对应的标题字符串的数组（请按对象中属性排序调整字符串在数组中的位置）
     * @param heardName 导出文件 标题名称
     * @param cnt 合并单元格数 （一般标题字符串的数组长度-1）
     */
    public static void export(HttpServletResponse response, List<?> importlist, String[] attributeNames,
                              String heardName, int cnt ) {
        //获取数据集
        List<?> datalist = importlist;

        //声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一个表格
        HSSFSheet sheet = workbook.createSheet();
        //设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 18);
        //用于设置表格字体
        HSSFCellStyle style = workbook.createCellStyle();

        //获取字段名数组
        String[] tableAttributeName = attributeNames;
        //获取对象属性
        Field[] fields = ClassUtil.getClassAttribute(importlist.get(0));
        //获取对象get方法
        List<Method> methodList = ClassUtil.getMethodGet(importlist.get(0));

        //设置标题样式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        HSSFFont headerFont = workbook.createFont();
        headerFont.setFontHeightInPoints((short) 14);
        headerFont.setBold(true);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        headerStyle.setFont(headerFont);
        CellRangeAddress cra0 = new CellRangeAddress(0, 1, 0, cnt);// 合并单元格
        sheet.addMergedRegion(cra0);
        //创建标标题题
        Row row = sheet.createRow(0);
        Cell cell1 = row.createCell(0);
        cell1.setCellValue(heardName);
        cell1.setCellStyle(headerStyle);

        // 设置字体样式
        HSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontHeightInPoints((short) 10);

        style.setFont(titleFont);
        style.setAlignment(HorizontalAlignment.CENTER);
        //循环字段名数组，创建标题行
        row = sheet.createRow(2);
        for (int j = 0; j< tableAttributeName.length; j++){
            //创建列
            Cell cell = row.createCell(j);
            cell.setCellStyle(style);
            //设置单元类型为String
            cell.setCellType(CellType.STRING);
            cell.setCellValue(transCellType(tableAttributeName[j]));
        }
        //创建普通行
        for (int i = 0;i<datalist.size();i++){
            //因为第一行已经用于创建标题行，故从第二行开始创建
            row = sheet.createRow(i+3);
            //如果是第一行就让其为标题行
            Object targetObj = datalist.get(i);
            for (int j = 0;j<fields.length;j++){
                //创建列
                Cell cell = row.createCell(j);
                cell.setCellType(CellType.STRING);
                //
                try {
                    Object value = methodList.get(j).invoke(targetObj, new Object[]{});
                    cell.setCellValue(transCellType(value));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        response.setContentType("application/octet-stream");
        //默认Excel名称
        response.setHeader("Content-Disposition", "attachment;fileName="+"test.xls");
        try {
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();

//            response.flushBuffer();
//            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }



    /**
     * 将传入的数据导出excel表并下载
     * @param importlist 要导出的对象的集合
     * @param attributeNames 含有每个对象属性在excel表中对应的标题字符串的数组（请按对象中属性排序调整字符串在数组中的位置）
     * @param heardName 导出文件 标题名称
     * @param cnt 合并单元格数 （一般标题字符串的数组长度-1）
     * @param filename 文件名称
     */
    public static void exportToPath( List<?> importlist, String[] attributeNames,
                              String heardName, int cnt,String filename ) throws IOException {
        //获取数据集
        List<?> datalist = importlist;

        //声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一个表格
        HSSFSheet sheet = workbook.createSheet();
        //设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 18*2);
        //用于设置表格字体
        HSSFCellStyle style = workbook.createCellStyle();

        //获取字段名数组
        String[] tableAttributeName = attributeNames;
        //获取对象属性
        Field[] fields = ClassUtil.getClassAttribute(importlist.get(0));
        //获取对象get方法
        List<Method> methodList = ClassUtil.getMethodGet(importlist.get(0));

        //设置标题样式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        HSSFFont headerFont = workbook.createFont();
        headerFont.setFontHeightInPoints((short) 14);
        headerFont.setBold(true);
        headerStyle.setAlignment(HorizontalAlignment.CENTER);
        headerStyle.setFont(headerFont);
//        CellRangeAddress cra0 = new CellRangeAddress(0, 1, 0, cnt);// 合并单元格
//        sheet.addMergedRegion(cra0);
//        //创建标标题题
//        Row row = sheet.createRow(0);
//        Cell cell1 = row.createCell(0);
//        cell1.setCellValue(heardName);
//        cell1.setCellStyle(headerStyle);

        // 设置字体样式
        HSSFFont titleFont = workbook.createFont();
        titleFont.setBold(true);
        titleFont.setFontHeightInPoints((short) 10);

        style.setFont(titleFont);
        style.setAlignment(HorizontalAlignment.CENTER);
        //循环字段名数组，创建标题行
        Row row = sheet.createRow(0);
        for (int j = 0; j< tableAttributeName.length; j++){
            //创建列
            Cell cell = row.createCell(j);
            cell.setCellStyle(style);
            //设置单元类型为String
            cell.setCellType(CellType.STRING);
            cell.setCellValue(transCellType(tableAttributeName[j]));
        }

        int index = 0;
        //创建普通行
        for (int i = 0;i<datalist.size();i++){
            //因为第一行已经用于创建标题行，故从第二行开始创建


            if ((i + 1) % 65535 == 0) {
                sheet = workbook.createSheet("sheet" + (index+1));
                row = sheet.createRow(0);
                for (int j = 0; j< tableAttributeName.length; j++){
                    //创建列
                    Cell cell = row.createCell(j);
                    cell.setCellStyle(style);
                    //设置单元类型为String
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(transCellType(tableAttributeName[j]));
                }
                index++;
            }
            row = sheet.createRow((i + 1) - (index * 65535));

            //如果是第一行就让其为标题行
            Object targetObj = datalist.get(i);
            for (int j = 0;j<fields.length;j++){

                if(!fields[j].getName().equals("serialVersionUID"))
                {
                    //创建列
                    Cell cell = row.createCell(j);
                    cell.setCellType(CellType.STRING);
                    //
                    try {
                        Object value = methodList.get(j).invoke(targetObj, new Object[]{});
                        cell.setCellValue(transCellType(value));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

        if(StringUtils.notEmp(filename))
        {
            StringBuilder sb=new StringBuilder("D:\\");
            sb.append(filename);
            sb.append(".xls");

            FileUtils.deleteFile(String.valueOf(sb));

            FileOutputStream fileOutputStream = new FileOutputStream(String.valueOf(sb));

            workbook.write(fileOutputStream);
            fileOutputStream.close();

        }

    }
    private static String transCellType(Object value){
        String str = null;
        if (value instanceof Date){
            Date date = (Date) value;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            str = sdf.format(date);
        }else{
            str = String.valueOf(value);
            if (str == "null"){
                str = "";
            }
        }

        return str;
    }


}
