package com.ag.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 * @Title excel导入操作类
 * @Package 
 * @ClassName: ExcelPoiUtil
 * @Description: TODO(导入操作类)
 * @author gxw
 * @date 2016-9-18 下午05:51:15
 * @verson
 */
public class ExcelPoiUtil {
	/**
	 * 转换excle 2003和2007
	 * @param in
	 * @return
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static Workbook create(InputStream in) throws
    IOException,InvalidFormatException {
	    if (!in.markSupported()) {
	        in = new PushbackInputStream(in, 8);
	    }
	    if (POIFSFileSystem.hasPOIFSHeader(in)) {
	        return new HSSFWorkbook(in);
	    }
	    if (POIXMLDocument.hasOOXMLHeader(in)) {
	        return new XSSFWorkbook(OPCPackage.open(in));
	    }
	    throw new IllegalArgumentException("你的excel版本目前poi解析不了");
	}
	/**
	 * 获取excel数据list
	 *
	 * @Title
	 * @Description TODO(获取excel数据list)
	 * @param stream
	 * @param startRow
	 * @param startCell
	 *            *@param sheetIndex
	 * @return
	 */
	public static List<HashMap<Integer, String>> readExcelEmptyBody(InputStream stream, int startRow,
			int endRow, int startCell, int endCell, int sheetIndex) {
		if (startRow < endRow && endRow != -1) {
			return null;
		}
		if (startCell < endCell && endCell != -1) {
			return null;
		}
		Workbook wb =null;
		List<HashMap<Integer, String>> resultList = new ArrayList<HashMap<Integer, String>>();

			try {
				wb = create(stream);
			} catch (InvalidFormatException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}


		Sheet sheet=null;
		int sheets= wb.getNumberOfSheets();
		int rows=0;
		for(int m=0;m<sheets;m++){
			 rows = wb.getSheetAt(m).getLastRowNum();

			if(rows>0){
				sheet = wb.getSheetAt(m);
			break;
			}
		}

		if(endRow != -1) {
			rows = endRow;
		}
		for (int i = startRow; i <= rows; i++) {
			Row row = sheet.getRow(i);
			if(row == null){
				continue;
			}
			int cells = row.getLastCellNum();
			if (endCell != -1) {
				cells = endCell;
			}
			int count = 0;
			HashMap<Integer, String> cellMap = new HashMap<Integer, String>();
			for (int j = startCell; j <= cells; j++) {
				Cell cell = row.getCell(j);
				String cellStr = getStringCellValue(cell);
				//System.out.print("\t" + cellStr);
                if(cellStr!=""||!cellStr.equals(""))
				cellMap.put(count, cellStr);
				count++;

			}
			resultList.add(cellMap);
		}
		return resultList;
	}
	/**
	 * 获取excel数据list
	 *
	 * @Title
	 * @Description TODO(获取excel数据list)
	 * @param stream
	 * @param startRow 开始行数 从0 开始
	 * @param startCell 开始列
	 * @param endCell 开始列
	 * @param startCell 开始列
	 *            *@param sheetIndex
	 * @return
	 */
	public static List readExcelBody(InputStream stream, int startRow,
			int endRow, int startCell, int endCell, int sheetIndex) {
		if (startRow < endRow && endRow != -1) {
			return null;
		}
		if (startCell < endCell && endCell != -1) {
			return null;
		}
		List resultList = new ArrayList();
		try {
			Workbook wb = create(stream);
			Sheet sheet = wb.getSheetAt(sheetIndex);
			int rows = sheet.getLastRowNum();
			if (rows <= 0) {
				sheet = wb.getSheetAt(wb.getActiveSheetIndex());
				rows = sheet.getLastRowNum();
			}

			if (endRow != -1) {
				rows = endRow;
			}
			for (int i = startRow; i <= rows; i++) {
				Row row = sheet.getRow(i);
				if (row == null) continue;
				int cells = row.getLastCellNum();
				if (endCell != -1) {
					cells = endCell;
				}
				if (cells==-1)
				{
					continue;
				}
				int count = 0;
				Map cellMap = new HashMap();
				for (int j = startCell; j <= cells; j++) {
					Cell cell = row.getCell(j);
					String cellStr = getStringCellValue(cell);

					cellMap.put(count, cellStr);
					count++;

				}

				resultList.add(cellMap);

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		 List<Integer> nullArr = new ArrayList<Integer>();
		    nullArr.add(null);
		    resultList.removeAll(nullArr);

		return resultList;
	}

	/**
	 * 获取excel数据list
	 *
	 * @Title
	 * @Description TODO(获取excel数据list)
	 * @param stream
	 * @param startRow
	 * @param startCell
	 *            *@param sheetName 使用工作表的名称
	 * @return
	 */
	public static List readExcelBody(InputStream stream, int startRow,
			int endRow, int startCell, int endCell, String sheetName) {
		if (startRow < endRow && endRow != -1) {
			return null;
		}
		if (startCell < endCell && endCell != -1) {
			return null;
		}
		List resultList = new ArrayList();
		try {
			Workbook wb = create(stream);
			Sheet sheet = wb.getSheet(sheetName);
			int rows = sheet.getLastRowNum();


			if (endRow != -1) {
				rows = endRow;
			}
			for (int i = startRow; i <= rows; i++) {
				Row row = sheet.getRow(i);

				int cells = row.getLastCellNum();
				if (endCell != -1) {
					cells = endCell;
				}
				if (cells==-1)
				{
					continue;
				}
				int count = 0;
				Map cellMap = new HashMap();
				for (int j = startCell; j <= cells; j++) {
					Cell cell = row.getCell(j);
					String cellStr = getStringCellValue(cell);

					cellMap.put(count, cellStr);
					count++;

				}

				resultList.add(cellMap);

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		 List<Integer> nullArr = new ArrayList<Integer>();
		    nullArr.add(null);
		    resultList.removeAll(nullArr);

		return resultList;
	}

	/**
	 *
	 * @Title 获取列值string
	 * @Description TODO(这里用一句话描述这个方法的作用)
	 * @param cell
	 * @return
	 */
	private static String getStringCellValue(Cell cell) {
		String strCell = "";
		if (cell == null) {
			return "";
		}
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_FORMULA:
			try {
				/*
				 * 此处判断使用公式生成的字符串有问题，因为HSSFDateUtil.isCellDateFormatted(cell)判断过程中cell
				 * .getNumericCellValue();方法会抛出java.lang.NumberFormatException异常
				 */
				if (HSSFDateUtil.isCellDateFormatted(cell)) {
					Date date = cell.getDateCellValue();
					SimpleDateFormat sdf = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm:ss");
					strCell = sdf.format(date);
					// strCell = (date.getYear() + 1900) + "-" +
					// (date.getMonth() + 1) +"-" +
					// date.getDate()+" "+date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
					break;
				} else {
					strCell = String.valueOf(cell.getNumericCellValue());
				}
			} catch (IllegalStateException e) {
				strCell = String.valueOf(cell.getRichStringCellValue());
			}
			break;
		case Cell.CELL_TYPE_STRING:
			strCell = cell.getStringCellValue();
			break;
		case Cell.CELL_TYPE_NUMERIC:
			if (HSSFDateUtil.isCellDateFormatted(cell)) {
				double d = cell.getNumericCellValue();
				Date date = HSSFDateUtil.getJavaDate(d);
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy-MM-dd HH:mm:ss");
				strCell = sdf.format(date);
				break;
			} else {
				//strCell = String.valueOf(cell.getNumericCellValue());
                DecimalFormat df = new DecimalFormat("0");
                strCell = df.format(cell.getNumericCellValue());
                break;
			}
		case Cell.CELL_TYPE_BOOLEAN:
			strCell = String.valueOf(cell.getBooleanCellValue());
			break;
		case Cell.CELL_TYPE_BLANK:
			strCell = "";
			break;
		default:
			strCell = "";
			break;
		}
		return strCell;
	}
	//判断Excel表格是否有内容
	public static int excelIsNull(InputStream stream) {
		int rows = 0;
		try {
			Workbook wb = new HSSFWorkbook(stream);
			Sheet sheet = wb.getSheetAt(0);
			rows = sheet.getLastRowNum();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return rows;
	}

	public static List<List<Object>> readExcel(String filePath) {
		ExcelReader reader = ExcelUtil.getReader(filePath);
		/*Iterator<Row> iterRow = reader.getWorkbook().getSheetAt(0).rowIterator();
		while(iterRow.hasNext()){
			Row row = iterRow.next();
			Iterator<Cell> iterCell = row.cellIterator();
			while(iterCell.hasNext()){
				Cell cell = iterCell.next();
				if (cell.getCellFormula())
				System.out.println(cell.getStringCellValue());
			}
		}*/
		return reader.read();
	}

	public static List<List<Object>> readExcel(InputStream inputStream) {
		ExcelReader reader = ExcelUtil.getReader(inputStream);
		return reader.read();
	}

	public static List<List<Object>> readExcel(File file) {
		ExcelReader reader = ExcelUtil.getReader(file);
		return reader.read();
	}

	public static void writeExcel(List<List<?>> data, String filePath, boolean isWriteKeyAsHead){
		ExcelWriter writer = ExcelUtil.getWriter(filePath);
		writer.write(data, isWriteKeyAsHead);
		writer.close();
	}

	public static void downloadXls(List<List<?>> data, String fileName, boolean isWriteKeyAsHead, HttpServletResponse response) throws IOException {
		// 通过工具类创建writer，默认创建xls格式
		ExcelWriter writer = ExcelUtil.getWriter();
        // 一次性写出内容，使用默认样式，强制输出标题
		writer.write(data, isWriteKeyAsHead);
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
		response.setHeader("Content-Disposition","attachment;filename="+fileName+".xls");
		ServletOutputStream out=response.getOutputStream();
		writer.flush(out, true);
		writer.close();
		IoUtil.close(out);
	}

	public static void downloadXlsx(List<List<?>> data, String fileName, boolean isWriteKeyAsHead, HttpServletResponse response) throws IOException {
		ExcelWriter writer = ExcelUtil.getWriter(true);
		writer.write(data, isWriteKeyAsHead);
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
		response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
		ServletOutputStream out = response.getOutputStream();
		writer.flush(out, true);
		writer.close();
		IoUtil.close(out);
	}
	public static void main(String[] args) {
		//List<List<Object>> data = ExcelPoiUtil.readExcel("e:\\data.xlsx");
		//System.out.println(JSON.toJSONString(data));
		List<String> row1 = CollUtil.newArrayList("aa", "bb", "cc", "dd");
		List<String> row2 = CollUtil.newArrayList("aa1", "bb1", "cc1", "dd1");
		List<List<?>> rows = CollUtil.newArrayList(row1, row2);
		ExcelPoiUtil.writeExcel(rows, "e:\\test.xlsx", true);

	}
}
