package cn.com.qmth.stmms.ms.commons.utils.excel;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;

/**
 * 
 * @Description: 读取excel
 * @author ting.yin
 * @date 2016年8月19日
 */
public class ExcelReader extends ExcelUtils {

	public ExcelReader(Class<?> dataClass) {
		super(dataClass,true);
	}

	/**
	 * 
	 * @param inputStream
	 *            输入流
	 * @param handle
	 *            单个对象处理器
	 * @return 错误信息集合
	 */
	public List<ExcelError> reader(InputStream inputStream,
			ExcelReaderHandle handle) {
		List<ExcelError> excelErrors = new ArrayList<ExcelError>();
		try {
			Workbook wb = WorkbookFactory.create(inputStream);
			Sheet sheet = wb.getSheetAt(0);
			//校验表头信息
			Row row0 = sheet.getRow(0);
			for (int j = 0; j < this.getColumnSettings().size(); j++) {
				ColumnSetting columnSetting = this.getColumnSettings().get(j);
				Cell cell = row0.getCell(columnSetting.getIndex() - 1);
				String obj = String.valueOf(convert(cell));
				if(!Objects.equals(columnSetting.getHeader(), obj)){
					ExcelError error = new ExcelError();
					error.setRow(1);
					error.setExcelErrorType("表头格式有误,请检查");
					excelErrors.add(error);
					return excelErrors;
				}
			}
			for (int i = 1; i <= sheet.getLastRowNum(); i++) {
				Row row = sheet.getRow(i);
				if (row == null) {
					return excelErrors;
				}
				Object dto = getDataClass().newInstance();
//				FieldAccess access = FieldAccess.get(getDataClass());
				for (int j = 0; j < this.getColumnSettings().size(); j++) {
					ColumnSetting columnSetting = this.getColumnSettings().get(j);
					Cell cell = row.getCell(columnSetting.getIndex() - 1);
					Object obj = convert(cell);
					Field field = getDataClass().getDeclaredField(columnSetting.getFieldName());
					field.setAccessible(true);
					field.set(dto, obj);
				}
				ExcelError error = handle.handle(dto);
				if (error != null) {
					error.setRow(i+1);
					excelErrors.add(error);
				}
			}
		}catch (InvalidFormatException e) {
				e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return excelErrors;
	}

	private Object convert(Cell cell) {
		if(cell!=null){
			switch (cell.getCellType()) {
			case Cell.CELL_TYPE_STRING:
				return cell.getStringCellValue().toString();
			case Cell.CELL_TYPE_BOOLEAN:
				return String.valueOf(cell.getBooleanCellValue());
			case Cell.CELL_TYPE_NUMERIC:
				return Math.round(cell.getNumericCellValue());
			}
		}
		
		return null;
	}
}
