package com.fuzamei.util;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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 com.mchange.util.AssertException;
/**
 * 
 * @author ylx
 * @since 2018-1-10 10:37 AM
 *	用于比对两个Excel表中数据的比对，如果有一个数据不一致返回false，只有全部一致返回true
 */
public final class ExcelUtil {
	private ExcelUtil(){
		throw new AssertException("instaniation is not permitted");
	}
	
	/**
	* @Title: matchExcel
	* @Description: TODO(针对多个区域进行比较，同时还有数据类型的选定)
	* @param @param file1(要进行比较的文件1)
	* @param @param file2(要进行比较的文件2)
	* @param @param c(Column类对象，包含有开始列，开始行，结束行还有要比较的数据类型)
	* @return boolean    返回类型true说明划定的区域中数据一致。false说明划定的区域中数据有不一致的情况
	* @author ylx
	* @date 2018年1月10日 上午11:27:26
	 */
	public static final boolean matchExcel(File file1,File file2,Area...c){
		if(c.length==0){
			throw new RuntimeException("必须放置Area对象");
		}
		Workbook wb1 = readWorkbook(file1);
		Workbook wb2 = readWorkbook(file2);
		Sheet sheet1 = wb1.getSheet("Sheet1");
		Sheet sheet2 = wb2.getSheet("Sheet1");
		for (Area column : c) {
			Integer fromCol = column.getFromCol();
			Integer toCol = column.getToCol();
			Integer fromRow = column.getFromRow();
			Integer toRow = column.getToRow();
			int compareType = column.getCompareType();
			for (int j = fromCol; j <= toCol; j++) {
				for (int i = fromRow; i <= toRow; i++) {
					Row row1 = sheet1.getRow(i);
					Row row2 = sheet2.getRow(i);
					Cell cell1 = row1.getCell(j);
					Cell cell2 = row2.getCell(j);
					if(Area.NUMERIC==compareType){
						double numericCellValue1 = cell1.getNumericCellValue();
						double numericCellValue2 = cell2.getNumericCellValue();
						if(numericCellValue1!=numericCellValue2)
							return false;	
					}else if(Area.STRING==compareType){
						String str1 = cell1.getStringCellValue();
						String str2 = cell2.getStringCellValue();
						if(!str1.equals(str2))
							return false;	
					}else if(Area.DATE==compareType){
						Date date1 = cell1.getDateCellValue();
						Date date2 = cell2.getDateCellValue();
						if(!date1.equals(date2))
							return false;
					}else{
						closeStream(wb1,wb2);
						throw new RuntimeException("读取的数据类型错误");
					}
					
				}
			}
			
		}
		closeStream(wb1,wb2);
		return true;
	}
	
	/**
	* @Title: matchExcel
	* @Description: TODO(针对单个区域进行比较，同时还有数据类型的选定)
	* @param @param file1(要进行比较的文件1)
	* @param @param file2(要进行比较的文件2)
	* @param @param c(Column类对象，包含有开始列，开始行，结束行还有要比较的数据类型)
	* @return boolean    返回类型true说明划定的区域中数据一致。false说明划定的区域中数据有不一致的情况
	* @author ylx
	* @date 2018年1月10日 上午11:27:26
	 */
	public static final boolean matchExcel(File file1,File file2,Area c){
		return matchExcel(file1,file2,c);
	}
	
	/**
	* @Title: matchExcel
	* @Description: TODO(这里用一句话描述这个方法的作用)
	* @param @param colPos 选定的列数(第一列为0)
	* @param @param fromRow	开始的行号(第一行为0)
	* @param @param toRow	结束的行号
	* @param @param compareType 1代表数字，2代表字符串，3代表日期格式，除此以外的数据类型会报错
	* @param @return    设定文件
	* @return boolean    返回类型
	* @author ylx
	* @date 2018年1月10日 上午11:33:47
	 */
	public static final boolean matchExcel(File file1,File file2,int colPos,int fromRow,int toRow,int compareType){
		return matchExcel(file1,file2,new Area(colPos,colPos, fromRow, toRow, compareType));
	}
	
	public static final boolean matchNumericExcel(File file1,File file2,int colPos,int fromRow,int toRow){
		return matchExcel(file1,file2,new Area(colPos,colPos, fromRow, toRow, Area.NUMERIC));
	}
	public static final boolean matchStringExcel(File file1,File file2,int colPos,int fromRow,int toRow){
		return matchExcel(file1,file2,new Area(colPos,colPos, fromRow, toRow, Area.STRING));
	}
	
	private static final void closeStream(Closeable...c){//关闭流的内部方法
		for (Closeable closeable : c) {
			if(closeable!=null){
				try {
					closeable.close();
				} catch (IOException e) {
					closeable=null;
				}
			}
		}
	}
	
	private static final Workbook readWorkbook(File file){//读取workbook
		InputStream is=null;
		Workbook wb=null;
		try {
			is = new FileInputStream(file);
		} catch (FileNotFoundException e) {
			closeStream(is);
			throw new RuntimeException("未找到文件");
		}
		try {
			wb=new XSSFWorkbook(is);
		} catch (IOException e) {
			try {
				wb=new HSSFWorkbook(is);
			} catch (IOException e1) {
				throw new RuntimeException("非Excel文件");
			}finally{
				closeStream(is);
			}
		}
		return wb;
	}
	
	public static void main(String[] args) throws Exception{
		File file1=new File("C:\\Users\\fuzamei\\Desktop\\测试用上传文件\\估值核算表.xlsx");
		File file2=new File("C:\\Users\\fuzamei\\Desktop\\测试用上传文件\\估值核算表2.xlsx");
		Area[] columns=new Area[]{new Area(4,5,2,4,Area.NUMERIC),new Area(7,8,2,4,Area.NUMERIC),new Area(9,9,3,3,Area.NUMERIC)};
		boolean matchExcel = matchExcel(file1, file2, columns);
		System.out.println(matchExcel);
	}
	
}


