package com.sino.publicclass.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class BaseExcel {
	
	protected OutputStream os;
	protected HSSFWorkbook workbook;
	protected HSSFRow row;
	protected HSSFCell cell;
	protected HSSFCellStyle style_title1;
	protected HSSFCellStyle style_title2;
	protected HSSFCellStyle style_title3;
	protected HSSFCellStyle style_input;
	protected HSSFCellStyle style_input_int;
	protected HSSFCellStyle style_input_double;
	protected HSSFCellStyle style_input_formula;
	
	protected HSSFCellStyle caption9;//9号字标题
	protected HSSFCellStyle caption10;//10号字标题
	protected HSSFCellStyle caption11;//11号字标题
	protected HSSFCellStyle caption12;//12号字标题
	protected HSSFCellStyle caption16;//16号字标题
	protected HSSFCellStyle caption20;//20号字标题
	
	protected HSSFCellStyle data9;//9号字数据左对齐
	protected HSSFCellStyle data10;//10号字数据左对齐
	protected HSSFCellStyle data11;//11号字数据左对齐
	protected HSSFCellStyle data12;//12号字数据左对齐
	protected HSSFCellStyle data16;//16号字数据左对齐
	
	protected HSSFCellStyle data9Right;//9号字数据右对齐
	protected HSSFCellStyle data10Right;//10号字数据右对齐
	protected HSSFCellStyle data11Right;//11号字数据右对齐
	protected HSSFCellStyle data12Right;//12号字数据右对齐
	protected HSSFCellStyle data16Right;//16号字数据右对齐
	
	protected int rowNum;
	protected int cellNum;
	protected DecimalFormat df;
	protected SimpleDateFormat sdfLong;

	protected void init(HttpServletResponse res, String filename) throws Exception {
		workbook = new HSSFWorkbook();
		HSSFFont font = workbook.createFont();
		font.setFontHeightInPoints((short) 13);
		font.setBoldweight((short) 700);
		HSSFFont font1 = workbook.createFont();
		font1.setFontHeightInPoints((short) 10);
		font1.setBoldweight((short) 700);
		HSSFFont font2 = workbook.createFont();
		font2.setFontHeightInPoints((short) 10);
		HSSFPalette palette = workbook.getCustomPalette();
		palette.setColorAtIndex(HSSFColor.BLUE.index, (byte) 214, (byte) 244, (byte) 244);
		style_title1 = createCellStyle(workbook, font, 1, 1, 1, 1, 2, 1, false, false, 0x31);
		style_title1.setFillForegroundColor(HSSFColor.BLUE.index);
		style_title1.setFillPattern(CellStyle.SOLID_FOREGROUND);
		style_title2 = createCellStyle(workbook, font1, 1, 1, 1, 1, 2, 1, false, false, 0x31);
		style_title2.setFillForegroundColor(HSSFColor.BLUE.index);
		style_title2.setFillPattern(CellStyle.SOLID_FOREGROUND);
		style_title3 = createCellStyle(workbook, font2, 1, 1, 1, 1, 1, 1, false, false, 0x31);
		style_input = createCellStyle(workbook, font2, 1, 1, 1, 1, 1, 1, false, false, 0x31);
		style_input_int = createCellStyle(workbook, font2, 1, 1, 1, 1, 1, 1, false, false, 1);
		style_input_double = createCellStyle(workbook, font2, 1, 1, 1, 1, 1, 1, false, false, 0);
		style_input_formula = createCellStyle(workbook, font2, 1, 1, 1, 1, 1, 1, false, false, 0);
		
		caption9  = createCellStyle(workbook, createFont(9, true) , 1, 1, 1, 1, 2, 1, false, false, 0x31);
		caption10 = createCellStyle(workbook, createFont(10, true), 1, 1, 1, 1, 2, 1, false, false, 0x31);
		caption11 = createCellStyle(workbook, createFont(11, true), 1, 1, 1, 1, 2, 1, false, false, 0x31);
		caption12 = createCellStyle(workbook, createFont(12, true), 1, 1, 1, 1, 2, 1, false, false, 0x31);
		caption16 = createCellStyle(workbook, createFont(16, true), 1, 1, 1, 1, 2, 1, false, false, 0x31);
		caption20 = createCellStyle(workbook, createFont(20, true), 1, 1, 1, 1, 2, 1, false, false, 0x31);
		
		data9  = createCellStyle(workbook, createFont(9, false) , 1, 1, 1, 1, 1, 1, false, false, 0x31);
		data10 = createCellStyle(workbook, createFont(10, false), 1, 1, 1, 1, 1, 1, false, false, 0x31);
		data11 = createCellStyle(workbook, createFont(11, false), 1, 1, 1, 1, 1, 1, false, false, 0x31);
		data12 = createCellStyle(workbook, createFont(12, false), 1, 1, 1, 1, 1, 1, false, false, 0x31);
		data16 = createCellStyle(workbook, createFont(16, false), 1, 1, 1, 1, 1, 1, false, false, 0x31);
		
		data9Right  = createCellStyle(workbook, createFont(9, false) , 1, 1, 1, 1, 3, 1, false, false, 0x31);
		data10Right = createCellStyle(workbook, createFont(10, false), 1, 1, 1, 1, 3, 1, false, false, 0x31);
		data11Right = createCellStyle(workbook, createFont(11, false), 1, 1, 1, 1, 3, 1, false, false, 0x31);
		data12Right = createCellStyle(workbook, createFont(12, false), 1, 1, 1, 1, 3, 1, false, false, 0x31);
		data16Right = createCellStyle(workbook, createFont(16, false), 1, 1, 1, 1, 3, 1, false, false, 0x31);
		
		rowNum = 0;
		cellNum = 0;
		df = new java.text.DecimalFormat("0.#");
		sdfLong = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		res.reset();
		res.setContentType("application/octet-stream; charset=UTF-8");
		res.addHeader("Content-Disposition", "attachment; filename=" + filename + ".xls");
		os = res.getOutputStream();
	}
	
	protected HSSFCellStyle createCellStyle(int fontSize, boolean boldweight, int align) {
		return createCellStyle(workbook, createFont(fontSize, boldweight), 1, 1, 1, 1, align, 1, false, false, 0x31);
	}
			
	
	protected HSSFCellStyle createCellStyle(HSSFWorkbook hworkbook, HSSFFont font, int border_top, int border_bottom, int border_left, int border_right, int align, int v_align, boolean islock,
			boolean iswrap, int format) {
		HSSFCellStyle style = hworkbook.createCellStyle();
		style.setFont(font);
		style.setBorderTop((short) border_top);
		style.setBorderBottom((short) border_bottom);
		style.setBorderLeft((short) border_left);
		style.setBorderRight((short) border_right);
		style.setAlignment((short) align);
		style.setVerticalAlignment((short) v_align);
		style.setLocked(islock);
		style.setWrapText(iswrap);
		style.setDataFormat((short) format);
		return style;
	}
	
	/**
	 * 创建字体
	 * @param fontSize
	 * @return
	 */
	protected HSSFFont createFont(int fontSize, boolean boldweight){
		HSSFFont font = workbook.createFont();
		font.setFontHeightInPoints((short) fontSize);
		font.setBoldweight((short) (boldweight ? 700 : 400));
		
		return font;
	}

	protected double format(double value) {
		return Double.parseDouble(df.format(value));
	}

	protected HSSFCell createCell(HSSFRow hrow, int cellnum, HSSFCellStyle style, String value) {
		HSSFCell hcell = hrow.createCell((short) cellnum);
		//hcell.setEncoding((short) 1);
		hcell.setCellStyle(style);
		hcell.setCellType(Cell.CELL_TYPE_STRING);
		hcell.setCellValue(value);
		return hcell;
	}

	protected HSSFCell createCell(HSSFRow hrow, int cellnum, HSSFCellStyle style, int value) {
		HSSFCell hcell = hrow.createCell((short) cellnum);
		//hcell.setEncoding((short) 1);
		hcell.setCellStyle(style);
		hcell.setCellType(Cell.CELL_TYPE_NUMERIC);
		hcell.setCellValue(value);
		return hcell;
	}

	protected HSSFCell createCell(HSSFRow hrow, int hcellNum, HSSFCellStyle style, double value) {
		HSSFCell hcell = hrow.createCell((short) hcellNum);
		//hcell.setEncoding((short) 1);
		hcell.setCellStyle(style);
		hcell.setCellType(Cell.CELL_TYPE_NUMERIC);
		hcell.setCellValue(value);
		return hcell;
	}

	protected HSSFCell createCellNumeric(HSSFRow hrow, int hcellNum, HSSFCellStyle style) {
		HSSFCell hcell = hrow.createCell((short) hcellNum);
		//hcell.setEncoding((short) 1);
		hcell.setCellStyle(style);
		hcell.setCellType(Cell.CELL_TYPE_NUMERIC);
		return hcell;
	}

	protected HSSFCell createCellFormula(HSSFRow hrow, int hcellNum, HSSFCellStyle style) {
		HSSFCell hcell = hrow.createCell((short) hcellNum);
		//hcell.setEncoding((short) 1);
		hcell.setCellStyle(style);
		hcell.setCellType(Cell.CELL_TYPE_FORMULA);
		return hcell;
	}
	


	protected String praseFormula(List list, int column) {
		String str = "";
		int offset = 7 + 1;
		char col = (char) (65 + column);
		String sign = "";
		for (int i = 0; i < list.size(); i++) {
			int value = ((Integer) list.get(i)).intValue() + offset;
			str += sign + col + value;
			sign = "+";
		}
		return "SUM(" + str + ")";
	}

	protected String praseFormula(int hrow, char column1, char column2) {
		String str = "";
		String sign = "+";
		str = "" + column1 + hrow + sign + column2 + hrow;
		return "SUM(" + str + ")";
	}

	protected String praseFormula(int hrow, char column1, char column2, char column3) {
		String str = "";
		String sign = "+";
		str = "" + column1 + hrow + sign + column2 + hrow + sign + column3 + hrow;
		return "SUM(" + str + ")";
	}
	
	/**
	 * 读取excel, 只读 sheet 0
	 * @param file
	 * @return 行号和list下标一一对应,如果某行没有数据则为null
	 * @throws IOException
	 */
	public static List<List<String>> readExcel(File file) throws IOException{
		return readExcel(file,0);
	}
	/**
	 * 读取excel
	 * @param file
	 * @param sheetIndex sheet 下标,从0开始
	 * @return 行号和list下标一一对应,如果某行没有数据则为null
	 * @throws IOException
	 */
	public static List<List<String>> readExcel(File file, int sheetIndex) throws IOException{  
	   String fileName = file.getName();
	   System.out.println("BaseExcel.readExcel(" + fileName + "," + sheetIndex + ")");
	   String extension = fileName.lastIndexOf(".")==-1 ? "" : fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
	   if ("xls".equals(extension)){  
		   return read2003Excel(file, sheetIndex);  
	   } else if ("xlsx".equals(extension)){  
		   return read2007Excel(file, sheetIndex);  
	   }else{  
		   throw new IOException("不支持的文件类型[" + extension + "]");  
	   }  
	}
	
	/**
	 * 读取 office 2003 excel
	 * @param file
	 * @param sheetIndex sheet 下标,从0开始
	 * @return 行号和list下标一一对应,如果某行没有数据则为null
	 * @throws IOException
	 */
	private static List<List<String>> read2003Excel(File file, int sheetIndex) throws IOException{
		DecimalFormat     df = new DecimalFormat("0");// 格式化 number String 字符  
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化日期字符串  
		DecimalFormat     nf = new DecimalFormat("0.00");// 格式化数字  
		 
	   HSSFWorkbook hwb = new HSSFWorkbook(new FileInputStream(file));  
	   HSSFSheet sheet = hwb.getSheetAt(sheetIndex);
	   
	   int rows = sheet.getLastRowNum(); //sheet.getPhysicalNumberOfRows();
	   List<List<String>> list = new ArrayList<List<String>>(rows + 2);
	   
	   String value = null;  
	   HSSFRow row = null;  
	   HSSFCell cell = null;
	   List<String> listRow;
	   int cols,j;
	   for(int i = 0; i <= rows ;i++){  
		   row = sheet.getRow(i);  
		   if (row == null) {
			   list.add(null);
			   continue;  
		   }
		   
		   cols = row.getLastCellNum();
		   listRow = new ArrayList<String>(cols + 1);  
		   for (j = 0; j < cols; j++) {  
			   cell = row.getCell(j);  
			   if (cell == null) {  
				   listRow.add(null);
				   continue;  
			   }  
			 
			   switch (cell.getCellType()) {  
			   case Cell.CELL_TYPE_STRING:  
//					System.out.println(i+"行"+j+" 列 is String type");  
					value = cell.getStringCellValue();  
					break;  
			   case Cell.CELL_TYPE_NUMERIC:  
//				   System.out.println(i+"行"+j+" 列 is Number type ; DateFormt:"+cell.getCellStyle().getDataFormatString());  
				   if ("@".equals(cell.getCellStyle().getDataFormatString())){  
					   value = df.format(cell.getNumericCellValue());  
				   } else if ("General".equals(cell.getCellStyle().getDataFormatString())){  
					   value = nf.format(cell.getNumericCellValue());  
				   }else{  
					   value = sdf.format(DateUtil.getJavaDate(cell.getNumericCellValue()));  
				   }  
				   break;  
			   case Cell.CELL_TYPE_BOOLEAN:  
//				   System.out.println(i+"行"+j+" 列 is Boolean type");  
				   value = cell.getBooleanCellValue() ? "true" : "false";  
				   break;  
			   case Cell.CELL_TYPE_BLANK:  
//				   System.out.println(i+"行"+j+" 列 is Blank type");  
				   value = "";  
				   break;  
			   default:  
				   System.out.println(i+"行"+j+" 列 is default type");  
				   value = cell.toString();  
			   }
			   
			   listRow.add(value);    
		   }  
		   
		   list.add(listRow);  
	   }  
	   
	   return list;  
	}
	
	/**
	 * 读取Office 2007 excel
	 * @param file
	 * @param sheetIndex  sheet 下标,从0开始
	 * @return 行号和list下标一一对应,如果某行没有数据则为null
	 * @throws IOException
	 */
	private static List<List<String>> read2007Excel(File file, int sheetIndex) throws IOException {
		DecimalFormat     df = new DecimalFormat("0");// 格式化 number String 字符  
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化日期字符串  
		DecimalFormat     nf = new DecimalFormat("0.00");// 格式化数字  
		
	   // 构造 XSSFWorkbook 对象，strPath 传入文件路径  
	   XSSFWorkbook xwb = new XSSFWorkbook(new FileInputStream(file));  
	   // 读取指定表格内容  
	   XSSFSheet sheet = xwb.getSheetAt(sheetIndex);
	   
	   int rows = sheet.getLastRowNum(); //sheet.getPhysicalNumberOfRows();
	   List<List<String>> list = new ArrayList<List<String>>(rows + 2);
	   
	   String value = null;  
	   XSSFRow row = null;  
	   XSSFCell cell = null;
	   
	   List<String> listRow;
	   int cols,j;
	   
	   for (int i = 0; i <= rows; i++) {  
		   row = sheet.getRow(i);  
		   if (row == null) {
			   list.add(null);
			   continue;  
		   }
		   
		   cols = row.getLastCellNum();
		   listRow = new ArrayList<String>(cols + 1);  
		   for (j = 0; j < cols; j++) {
			   cell = row.getCell(j);  
			   if (cell == null) {
				   listRow.add(null);
				   continue;  
			   }
			   
	    
			   switch (cell.getCellType()) {  
			   case Cell.CELL_TYPE_STRING:  
//				   System.out.println(i+"行"+j+" 列 is String type");  
				   value = cell.getStringCellValue();  
				   break;  
			   case Cell.CELL_TYPE_NUMERIC:  
//				   System.out.println(i+"行"+j+" 列 is Number type ; DateFormt:"+cell.getCellStyle().getDataFormatString());  
				   if ("@".equals(cell.getCellStyle().getDataFormatString())){  
					   value = df.format(cell.getNumericCellValue());  
				   } else if ("General".equals(cell.getCellStyle().getDataFormatString())){  
					   value = nf.format(cell.getNumericCellValue());  
				   } else {  
					   value = sdf.format(DateUtil.getJavaDate(cell.getNumericCellValue()));  
				   }  
				   break;  
			   case Cell.CELL_TYPE_BOOLEAN:  
//				   System.out.println(i+"行"+j+" 列 is Boolean type");  
				   value = cell.getBooleanCellValue() ? "true" : "false";  
				   break;  
			   case Cell.CELL_TYPE_BLANK:  
//				   System.out.println(i+"行"+j+" 列 is Blank type");  
				   value = "";  
				   break;  
			   default:  
//				   System.out.println(i+"行"+j+" 列 is default type");  
				   value = cell.toString();  
			   }  
	      
			   listRow.add(value);  
		   } 
		   
		   list.add(listRow);  
	   	}
	   
	   	return list;
	}
	
	/**
	 * 返回行高
	 * @param points 点数(一英寸=72点)
	 * @return
	 */
	protected short getRowHeight(int points){
		//equals points * 20
		return (short) ((points << 4) + (points << 2));
	}
	
	/**
	 * 列宽
	 * @param characters 列字符数量 <= 255
	 * @return
	 */
	protected int getColumnWidth(int characters){
		return characters << 8;
	}
	
	public static void main(String[] args){
		try {
			File file = new File("f:\\vehicleUser.xls");
			List<List<String>> list = readExcel(file,0);
			System.out.println("listsize="+list.size());
			List<String> clist= list.get(3);
			System.out.println("clist="+clist.size());
			for(String str : clist){
				System.out.println(str);
			}
			
		} catch (Exception e){
			e.printStackTrace();
		}
	}
}
