package com.jpsoft.shinestar.modules.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.w3c.dom.Document;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Description:POI解析Excel获取所有数据(支持xls/xlsx)
 *
 * @author zhjun 2015-11-5
 */
public class POIUtils {
    InputStream ins = null;
    Workbook wb = null;
    List<Object[]> dataList = new ArrayList<Object[]>(100);

    public static void CreateBorder(CellStyle cellStyle) {
        if (cellStyle != null) {
            cellStyle.setBorderTop(BorderStyle.THIN);
            cellStyle.setBorderBottom(BorderStyle.THIN);
            cellStyle.setBorderLeft(BorderStyle.THIN);
            cellStyle.setBorderRight(BorderStyle.THIN);
        }
    }

    public static Cell setCellValue(Row row, int i, String value) {
        // TODO Auto-generated method stub
        Cell cell = row.createCell(i);
        cell.setCellValue(value);

        return cell;
    }

    public static Cell setCellValue(Row row, int i, int value) {
        // TODO Auto-generated method stub
        Cell cell = row.createCell(i);
        cell.setCellValue(value);

        return cell;
    }

    public static Cell setCellValue(Row row, int cellIndex, CellStyle cellStyle, Object value) {
        Cell cell = row.createCell(cellIndex);
        cell.setCellStyle(cellStyle);

        if (value != null) {
            if (value instanceof BigDecimal) {
                cell.setCellValue(((BigDecimal) value).doubleValue());
            } else if (value instanceof String) {
                cell.setCellValue(value.toString());
            } else if (value instanceof Integer) {
                cell.setCellValue(Double.valueOf(value.toString()));
            } else if (value instanceof Long) {
                cell.setCellValue(Double.valueOf(value.toString()));
            }
        }

        return cell;
    }

    public static String xls2html(HSSFWorkbook wb) {
        String result = "";

        try {
            ExcelToHtmlConverter converter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
            converter.setOutputColumnHeaders(false);
            converter.setOutputRowNumbers(false);

            converter.processWorkbook(wb);

            Document htmlDocument = converter.getDocument();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            DOMSource domSource = new DOMSource(htmlDocument);
            StreamResult streamResult = new StreamResult(out);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();
            serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.setOutputProperty(OutputKeys.METHOD, "html");
            serializer.transform(domSource, streamResult);
            out.close();

            result = new String(out.toByteArray(), "UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return result;
    }

    /**
     * 通过流读取
     *
     * @param ins
     */
    public POIUtils(InputStream ins) {
        try {
            wb = WorkbookFactory.create(ins);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public POIUtils() {
        wb = new HSSFWorkbook();
    }

    public Sheet getSheetAt(int sheetIndex){
        return wb.getSheetAt(sheetIndex);
    }

    public Workbook getWorkbook(){
        return wb;
    }

    /**
     * 通过文件读取
     *
     * @param file
     */
    public POIUtils(File file) {
        try {
            ins = new FileInputStream(file);
            wb = WorkbookFactory.create(ins);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 通过文件路径读取
     *
     * @param path
     */
    public POIUtils(String path) {
        try {
            ins = new FileInputStream(path);
            wb = WorkbookFactory.create(ins);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 取Excel所有数据，包含header
     *
     * @return List<Object   [   ]>
     */
    public List<Object[]> getAllData(int sheetIndex) {
        int columnNum = 0;
        Sheet sheet = wb.getSheetAt(sheetIndex);
        if (sheet.getRow(0) != null) {
            columnNum = sheet.getRow(0).getLastCellNum() - sheet.getRow(0).getFirstCellNum();
        }
        if (columnNum > 0) {
            for (Row row : sheet) {
                Object[] singleRow = new Object[columnNum];
                int n = 0;

                for (int i = 0; i < columnNum; i++) {
                    Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                    singleRow[n] = getCellValue(cell);
                    n++;
                }

                //在后续方法中校验
//				if("".equals(singleRow[0])){continue;}//如果第一列为空，跳过

                dataList.add(singleRow);
            }
        }
        return dataList;
    }

    public List<Object[]> getAllData(int sheetIndex, int firstRowNum) {
        int columnNum = 0;
        Sheet sheet = wb.getSheetAt(sheetIndex);
        if (sheet.getRow(0) != null) {
            columnNum = sheet.getRow(firstRowNum).getLastCellNum();
        }
        if (columnNum > 0) {
            for (Row row : sheet) {
                Object[] singleRow = new Object[columnNum];
                int n = 0;
                for (int i = 0; i < columnNum; i++) {
                    Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                    singleRow[n] = getCellValue(cell);
                    n++;
                }
                if ("".equals(singleRow[0])) {
                    continue;
                }//如果第一行为空，跳过
                dataList.add(singleRow);
            }
        }
        return dataList;
    }

    public Object getCellValue(int sheetIndex,int rowIndex,int colIndex){
        Row row = wb.getSheetAt(sheetIndex).getRow(rowIndex);
        Cell cell = row.getCell(colIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);

        return getCellValue(cell);
    }

    /**
     * 获取列的数据信息
     *
     * @param cell
     * @return
     */
    private Object getCellValue(Cell cell) {
        Object cellValue = null;
        FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

        switch (cell.getCellType()) {
            case BLANK:
                cellValue = "";
                break;
            case BOOLEAN:
                cellValue = Boolean.toString(cell.getBooleanCellValue());
                break;
            //数值
            case NUMERIC:
                DecimalFormat df = new DecimalFormat("0");
                double value = cell.getNumericCellValue();

                if (value > Math.floor(value)) {
                    df = new DecimalFormat("0.00");
                }

                cellValue = df.format(value);
                break;
            case STRING:
                cellValue = cell.getStringCellValue().trim();
                break;
            case ERROR:
                cellValue = "";
                break;
            case FORMULA:
                CellValue cv = evaluator.evaluate(cell);

                if (cv.getCellType() == CellType.STRING) {
                    cellValue = cv.getStringValue();
                } else if (cv.getCellType() == CellType.NUMERIC) {
                    cellValue = cv.getNumberValue();
                } else {
                    cellValue = cell.getCellFormula();
                }

                break;
            default:
                cellValue = "";
        }

        return cellValue;
    }


    /**
     * 返回Excel最大行index值，实际行数要加1
     *
     * @return
     */
    public int getRowNum(int sheetIndex) {
        Sheet sheet = wb.getSheetAt(sheetIndex);
        return sheet.getLastRowNum();
    }

    /**
     * 返回数据的列数
     *
     * @param sheetIndex
     * @return
     */
    public int getColumnNum(int sheetIndex) {
        Sheet sheet = wb.getSheetAt(sheetIndex);
        Row row = sheet.getRow(0);
        if (row != null && row.getLastCellNum() > 0) {
            return row.getLastCellNum();
        }
        return 0;
    }

    /**
     * 获取某一行数据
     *
     * @param rowIndex 计数从0开始，rowIndex为0代表header行
     * @return
     */
    public Object[] getRowData(int sheetIndex, int rowIndex) {
        Object[] dataArray = null;
        if (rowIndex > this.getColumnNum(sheetIndex)) {
            return dataArray;
        } else {
//			dataArray = new Object[this.getColumnNum(sheetIndex)];
            return this.dataList.get(rowIndex);
        }
    }


    /**
     * 获取某一列数据
     *
     * @param colIndex
     * @return
     */
    public Object[] getColumnData(int sheetIndex, int colIndex) {
        Object[] dataArray = null;
        if (colIndex > this.getColumnNum(sheetIndex)) {
            return dataArray;
        } else {
            if (this.dataList != null && this.dataList.size() > 0) {
                dataArray = new Object[this.getRowNum(sheetIndex) + 1];
                int index = 0;
                for (Object[] rowData : dataList) {
                    if (rowData != null) {
                        dataArray[index] = rowData[colIndex];
                        index++;
                    }
                }
            }
        }

        return dataArray;
    }

    public static void main(String[] args) {
        POIUtils re = new POIUtils("D:\\fpb.xlsx");

        List<Object[]> objList = re.getAllData(0);

        for (int i = 0; i < objList.size(); i++) {
            String result = "";
            for (int j = 0; j < objList.get(i).length; j++) {
                result += objList.get(i)[j] + "_";
            }

            System.out.println(result);
        }
    }

    public Workbook exportErrorXls(int sheetIndex,int validateColIndex, int rowNum) {
        Workbook destBook = new HSSFWorkbook();
        Sheet destSheet = destBook.createSheet();

        //复制列头
        Sheet srcSheet = wb.getSheetAt(sheetIndex);
        Row srcHeaderRow = wb.getSheetAt(sheetIndex).getRow(0);
        Row destHeaderRow = destSheet.createRow(0);

        for (int i=0;i<srcHeaderRow.getLastCellNum();i++){
            if (srcHeaderRow.getCell(i)!=null) {
                destHeaderRow.createCell(i).setCellValue(srcHeaderRow.getCell(i).getStringCellValue());
            }
            else{
                break;
            }
        }

        int srcRowIndex = 1;
        int destRowIndex = 1;

        while(srcRowIndex<= rowNum){
            Row dataRow1 = srcSheet.getRow(srcRowIndex);

            if(dataRow1!=null) {
                Cell cell = dataRow1.getCell(validateColIndex);

                if (cell != null && StringUtils.isNotEmpty(cell.getStringCellValue())) {
                    Row dataRow2 = destSheet.createRow(destRowIndex);

                    int lastCellNum = Math.min(dataRow1.getLastCellNum(),100);

                    for (int i = 0; i < lastCellNum; i++) {
                        if (dataRow1.getCell(i) != null) {
                            dataRow2.createCell(i).setCellValue((String) getCellValue(0, srcRowIndex, i));
                        }
                    }

                    destRowIndex++;
                }
            }

            srcRowIndex++;
        }

        return destBook;
    }
}
