package com.platform.utils.excelUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * @author chen
 * excel2007操作
 */
public class ExcelOperation {
	
	/** 写入excel
	 * @param workbook 模板
	 * @param excelInitRow 从第excelInitRow行 开始填充数据，( Constant.EXCEL_TEMPLATE_INIT_ROW)
	 * @param excelInitCell 从第excelInitCell列 开始填充数据，
	 * @param excelEndCell 到第excelEndCell列 结束，
	 * @param list list中对象的属性顺序和模板的列顺序一一对应
	 * @param filter list中对象的属性过滤（比如"id"）
	 * @return  带有数据的XSSFWorkbook
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static XSSFWorkbook writeExcelTemplate(XSSFWorkbook workbook, int excelInitRow, int excelInitCell, int excelEndCell,List list, String... filter) throws FileNotFoundException, IOException, IllegalArgumentException, IllegalAccessException {
		List<String> filters = new ArrayList<String>();
		filters.addAll(Arrays.asList(filter));
		 //读取工作表
		XSSFSheet sheet = workbook.getSheetAt(0);//getSheet("Sheet1");
	    XSSFRow row;
		XSSFCell cell = null;
		int size = list.size();
		int lengths = 0;
		XSSFCellStyle style = getStyle(workbook);
		for (int i = 0; i < size; i++) {
			row = sheet.createRow(excelInitRow);
			Object obj = list.get(i);
			Field[] fields = obj.getClass().getDeclaredFields();
			lengths  = fields.length;
			int num = 0;
			for (int j = 0; j < lengths; j++) {
				if (j - num >= lengths) {
					break;
				}
				if (j >= excelEndCell) {
					break;
				}
				num = getWriteIndex(filters, fields, j - num, num);
				if (num == 1) {
					break;
				}
				Field tmpField = fields[j - num];
				tmpField.setAccessible(true);
				cell = row.createCell((short) j,HSSFCellStyle.ALIGN_CENTER);
			    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			    Object value = tmpField.get(obj);
			    if (null != value) {
			    	//int型
			    	if (tmpField.getType().toString().contains("Integer") || tmpField.getType().toString().contains("int")) {
			    		if (filters.contains(tmpField.getName())) 
			    			cell.setCellValue("-");
			    		else
			    			cell.setCellValue(String.valueOf(value));
					}
			    	else {
			    		cell.setCellValue(value.toString());
					}
				}
			    else {
			    	cell.setCellValue("");
				}
			    cell.setCellStyle(style);
			}
			//下一行
			excelInitRow++;
		}
		for (int k = 0; k < lengths; k++) {
			sheet.autoSizeColumn(k);
			int width = sheet.getColumnWidth(k);
			if (width < 1600) {
				sheet.setColumnWidth(k, 1600);
			}else {
				sheet.setColumnWidth(k, width + 1000);
			}
		}
		return workbook; 
	}

	/** excel的cell样式设置
	 * @param workbook
	 * @return
	 */
	private static XSSFCellStyle getStyle(XSSFWorkbook workbook) {
//	     设置字体;
		  XSSFFont font = workbook.createFont();
		  //设置字体大小;
		  font.setFontHeightInPoints((short)9);
		  //设置字体名字;
		  font.setFontName("Courier New");
		  //font.setItalic(true);
		  //font.setStrikeout(true);
//		     设置样式;
		  XSSFCellStyle style = workbook.createCellStyle();
		  //设置底边框;
		  style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		  //设置底边框颜色;
		  style.setBottomBorderColor(HSSFColor.BLACK.index);
		  //设置左边框;
		  style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		  //设置左边框颜色;
		  style.setLeftBorderColor(HSSFColor.BLACK.index);
		  //设置右边框;
		  style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		  //设置右边框颜色;
		  style.setRightBorderColor(HSSFColor.BLACK.index);
		  //设置顶边框;
		  style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		  //设置顶边框颜色;
		  style.setTopBorderColor(HSSFColor.BLACK.index);
		  //在样式用应用设置的字体;
		  style.setFont(font);
		     //设置自动换行;
		  style.setWrapText(false);
		  //设置水平对齐的样式为居中对齐;
		  style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		  //设置垂直对齐的样式为居中对齐;
		  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		  return style;
	}
	
	/** 读取excel模板
	 * @param workbook  excel的带数据的XSSFWorkbook
	 * @param excelInitRow 读取数据的起始行
	 * @param excelInitCell 读取数据的起始列
	 * @param classz excel的每行数据导出 到的 类
	 * @param filter excel的每行数据导出 到的 类 的属性的过滤
	 * @return 类 的集合
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public static List readExcel4Update(XSSFWorkbook workbook, int excelInitRow, int excelInitCell, Object obj, String... filter) throws InstantiationException, IllegalAccessException {
		List<String> filters = new ArrayList<String>();
		Class<?> classz = obj.getClass();
		filters.addAll(Arrays.asList(filter));
		List list = null;
		 //读取工作表
		XSSFSheet sheet = workbook.getSheetAt(0);//getSheet("Sheet1");
	    XSSFRow row;
		XSSFCell cell = null;
		//excel总行数
		int rowNum = sheet.getLastRowNum();
//        row = sheet.getRow(excelInitRow);
//        //excel总列数
//        int colNum = row.getPhysicalNumberOfCells();
        // 填充数据的类的 属性个数
        int objColl = classz.getDeclaredFields().length;
        //如果有数据
        if (rowNum > excelInitRow) {
			list =  new ArrayList<Object>();
			//遍历每行数据
	        for (int i = excelInitRow; i < rowNum; i++) {
	        	//获得当前行
	        	row = sheet.getRow(i);
	        	cell = row.getCell(excelInitCell);
	        	if ("-".equals(getValue(cell))) {
					continue;
				}
	        	//实例化
	        	Object newObj = classz.newInstance();
	        	Field[] fields = classz.getDeclaredFields();
	        	int fieldSize = fields.length;
	        	boolean isAddObj = false;
	        	int num = 0;
	        	//遍历每列的数据
	        	for (int j = excelInitCell; j < objColl; j++) {
	        		cell = row.getCell(j);
	        		if (j + num >= fieldSize) {
						break;
					}
	        		num = getIndex(filters, fields, j + num, num);
	        		if (num == -1) {
						break;
					}
	        		Field tmpField = fields[j + num];
	        		if (null != cell) {
	        			tmpField.setAccessible(true);
		        		String cellString = getValue(cell);
		        		if (!"".equals(cellString)) {
		        			isAddObj = true;
		        			String type = tmpField.getGenericType().toString();
			        		//int型
					    	if (type.contains("Integer") ||type.contains("int")) {
					    		double dnum = Double.valueOf(cellString);
					    		int inum = (int) dnum;
					    		tmpField.set(newObj, inum);
							}
					    	//double型
					    	else if (type.contains("Double") ||type.contains("double")) {
					    		tmpField.set(newObj, Double.valueOf(cellString));
							}
					    	//boolean型
					    	else if (type.contains("boolean") ||type.contains("Boolean")) {
					    		tmpField.set(newObj, Boolean.valueOf(cellString));
							}
					    	else {
					    		tmpField.set(newObj, cellString);
							}
		        		}
		        		
	        		}
				}
	        	if (isAddObj) {
	        		list.add(newObj);
				}
			}
        }
		return list;
	}

	/** 获得cell里的字符串
	 * @param cell
	 * @return
	 */
	private static String getValue(XSSFCell cell) {
		String value ="";
		if (null == cell) {
			return value;
		}
		switch (cell.getCellType()) {
			case XSSFCell.CELL_TYPE_NUMERIC:
				double	doubleVal = cell.getNumericCellValue();
			    long longVal = Math.round(cell.getNumericCellValue());  
			    if(Double.parseDouble(longVal + ".0") == doubleVal)  
			    	value = String.valueOf(longVal);  
			    else  
			    	value = String.valueOf(doubleVal);
				break;
			case XSSFCell.CELL_TYPE_BOOLEAN:
				value = String.valueOf(cell.getBooleanCellValue());
				break;
			case XSSFCell.CELL_TYPE_STRING:
				value = cell.getStringCellValue();
				break;
			default:
				break;
		}
		return value.trim();
	}
	
	/** 过滤掉 filters中含有的 属性
	 * @param filters
	 * @param fields
	 * @param cur
	 * @param num
	 * @return
	 */
	private static int getIndex(List<String> filters, Field[] fields,int cur, int num) {
		if (null == filters || filters.size() == 0) {
			return num;
		}
		if (cur >= fields.length) {
			return -1;
		}
		if (filters.contains(fields[cur].getName())) {
			num++;
			num = getIndex(filters, fields, cur+1, num);
		}
		return num;
	}
	/** 过滤掉 filters中含有的 属性
	 * @param filters
	 * @param fields
	 * @param cur
	 * @param num
	 * @return
	 */
	private static int getWriteIndex(List<String> filters, Field[] fields,int cur, int num) {
		if (null == filters || filters.size() == 0) {
			return num;
		}
		if (cur >= fields.length) {
			return 1;
		}
		if (filters.contains(fields[cur].getName())) {
			num--;
			num = getWriteIndex(filters, fields, cur+1, num);
		}
		return num;
	}
}
