package com.zbkj.common.utils.excel;

import com.zbkj.common.annotation.Excel;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

public class ExcelPublicUtil {
	
	public static int MAXEXPORT=500000;
	public static String GET = "get";
	public static String SET = "set";
	
	/**
	 * 获取class的 包括父类的
	 * @param clazz
	 * @return
	 */
	public static Field[] getClassFields(Class<?> clazz) {
		List<Field> list = new ArrayList<Field>();
		Field[] fields;
		do{
			fields = clazz.getDeclaredFields();
			for(int i = 0;i<fields.length;i++){
				list.add(fields[i]);
			}
			clazz = clazz.getSuperclass();
		}while(clazz!= Object.class&&clazz!=null);
		return list.toArray(fields);
	}
	
	/**
	 * 判断是不是集合的实现类
	 * @param clazz
	 * @return
	 */
	public static boolean isCollection(Class<?> clazz) {
		return clazz.isAssignableFrom(List.class)||
				clazz.isAssignableFrom(Set.class)||
				clazz.isAssignableFrom(Collection.class);
	}
	
	public static boolean isNotUserExcelUserThis(Field field) {
		boolean boo = true;
		 if(boo&&field.getAnnotation(Excel.class)!=null
				&&isUseInThis(field.getAnnotation(Excel.class).exportName())){
			boo = false;
		}
		return boo;
	}
	
	private static boolean isUseInThis(String exportName) {
		return exportName.equals("") || exportName.indexOf("_") < 0;
	}
	
	/**
	 * 是不是java基础类
	 * @param field
	 * @return
	 */
	public static boolean isJavaClass(Field field) {
		Class<?> fieldType = field.getType();
		boolean isBaseClass = false;
		if(fieldType.isArray()){
			isBaseClass = false;
		}else if (fieldType.isPrimitive()||fieldType.getPackage()==null
				|| fieldType.getPackage().getName().equals("java.lang")
				|| fieldType.getPackage().getName().equals("java.math")
				|| fieldType.getPackage().getName().equals("java.util")) {
			isBaseClass =  true;
		}
		return isBaseClass;
	}
	
	public static Object createObject(Class<?> clazz) {
		Object obj = null;
		String fieldname;
		Method setMethod;
		try {
			obj = clazz.newInstance();
			Field[] fields = getClassFields(clazz);
			for(Field field:fields){
				if(isNotUserExcelUserThis(field)){continue;}
				if(!isJavaClass(field)){
					fieldname = field.getName();
					setMethod = getMethod(fieldname,clazz,field.getType() );
					setMethod.invoke(obj, createObject(field.getType()));
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj; 
		
	}
	
	/**
	 * 获取方法
	 * @param name
	 * @param pojoClass
	 * @return
	 * @throws Exception
	 */
	public static Method getMethod(String name, Class<?> pojoClass)
			throws Exception {
		StringBuffer getMethodName = new StringBuffer(GET);
		getMethodName.append(name.substring(0, 1).toUpperCase());
		getMethodName.append(name.substring(1));
		return pojoClass.getMethod(getMethodName.toString(),new Class[]{});
	}
	/**
	 * 获取方法
	 * @param name
	 * @param pojoClass
	 * @param type
	 * @return
	 * @throws Exception
	 */
	public static Method getMethod(String name, Class<?> pojoClass,Class<?> type)
			throws Exception {
		StringBuffer getMethodName = new StringBuffer(SET);
		getMethodName.append(name.substring(0, 1).toUpperCase());
		getMethodName.append(name.substring(1));
		return pojoClass.getMethod(getMethodName.toString(),new Class[]{type});
	}
	
	/**
	 * 
	 * @param photoByte
	 * @return
	 */
	public static String getFileExtendName(byte[] photoByte) {
		String strFileExtendName = "JPG";
		if ((photoByte[0] == 71) && (photoByte[1] == 73)
				&& (photoByte[2] == 70) && (photoByte[3] == 56)
				&& ((photoByte[4] == 55) || (photoByte[4] == 57))
				&& (photoByte[5] == 97)) {
			strFileExtendName = "GIF";
		} else if ((photoByte[6] == 74) && (photoByte[7] == 70)
				&& (photoByte[8] == 73) && (photoByte[9] == 70)) {
			strFileExtendName = "JPG";
		} else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
			strFileExtendName = "BMP";
		} else if ((photoByte[1] == 80) && (photoByte[2] == 78)
				&& (photoByte[3] == 71)) {
			strFileExtendName = "PNG";
		}
		return strFileExtendName;
	}
	
	/** 
     * 获取Excel2003图片 
     * @param sheet 当前sheet对象 
     * @param workbook 工作簿对象 
     * @return Map key:图片单元格索引（1_1）String，value:图片流PictureData 
     */  
    @SuppressWarnings("unchecked")
	public static Map<String, PictureData> getSheetPictrues03(HSSFSheet sheet, 
    		HSSFWorkbook workbook) {  
        Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>(); 
        List<HSSFPictureData> pictures = workbook.getAllPictures();  
        if (pictures.size() != 0) {  
            for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) {  
                HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();  
                if (shape instanceof HSSFPicture) {  
                    HSSFPicture pic = (HSSFPicture) shape;  
                    int pictureIndex = pic.getPictureIndex() - 1;  
                    HSSFPictureData picData = pictures.get(pictureIndex);  
                    String picIndex = String.valueOf(anchor.getRow1()) + "_"  
                            + String.valueOf(anchor.getCol1());  
                    sheetIndexPicMap.put(picIndex, picData);  
                }
            }  
            return sheetIndexPicMap;  
        } else {  
            return (Map<String, PictureData>) sheetIndexPicMap.put(null, null);  
        }  
    }  
  
    /** 
     * 获取Excel2007图片 
     * @param sheet 当前sheet对象
     * @param workbook 工作簿对象 
     * @return Map key:图片单元格索引（1_1）String，value:图片流PictureData 
     */  
    public static Map<String, PictureData> getSheetPictrues07(  
            XSSFSheet sheet, XSSFWorkbook workbook) {  
        Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();  
        for (POIXMLDocumentPart dr : sheet.getRelations()) {  
            if (dr instanceof XSSFDrawing) {  
                XSSFDrawing drawing = (XSSFDrawing) dr;  
                List<XSSFShape> shapes = drawing.getShapes();  
                for (XSSFShape shape : shapes) {  
                    XSSFPicture pic = (XSSFPicture) shape;  
                    XSSFClientAnchor anchor = pic.getPreferredSize();  
                    CTMarker ctMarker = anchor.getFrom();  
                    String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();  
                    sheetIndexPicMap.put(picIndex, pic.getPictureData());  
                }  
            }  
        }  
        return sheetIndexPicMap;  
    }  

}