package com.zcloud.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.zcloud.entity.system.Text;
import com.zcloud.entity.system.User;

/**
 * @Author gjx
 * @email 13450753745@163.com
 * @description excel导出工具类
 * @Date 2019/7/10
 */
public class Exclupload {

    /**
     *功能描述 excel工具类，可导出带图片或不带图片的数据
     * @author gjx
     * @date 2019/7/10
     * @param [titles, rows, maps, uploadPath]
     *         titles[]:第一行的标题列；
     *         rows:数据行量
     *         maps：装载导出数据的封装了map的list数据集合，注意：此中的map尽量用本类中的方法
     *                 javaBean2Map直接生成，或自己拼接；但需与参数titles[]的标题相关数据对应上
     *         uploadPath: 导出到本地的文件路径和文件名。
     * @return java.lang.String  导出结果。
     */
    public static java.lang.String excelOut(java.lang.String[] titles, int rows,List<Map<java.lang.String,Object>> maps,java.lang.String uploadPath){

        FileOutputStream fileOut = null;
        BufferedImage bufferImg = null;
        HSSFWorkbook wb = null;

        try{
            ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
            //创建工作sheet
            wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("sheet1");
            //设置单元格内容水平垂直居中
            HSSFCellStyle style = wb.createCellStyle();
//            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

            //画图的顶级管理器，一个sheet只能获取一个（一定要注意这点）
            HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
            HSSFRow row0 = sheet.createRow(0);
            row0.setHeightInPoints(25);
            if (titles.length == 0){
                return "error";
            }
            HSSFCell cell = null;
            //第一行、标题行列
            for (int i=0;i<titles.length;i++){
                cell = row0.createCell(i);     //第一个单元格
                cell.setCellValue(titles[i]);         //设定值
                cell.setCellStyle(style);
                sheet.setColumnWidth(i,6000);
            }

            HSSFRow row = null;
            HSSFCell cellRow = null;
            HSSFClientAnchor anchor = null;

            for (int i=1;i<=rows;i++){
                int cellColumn = 0;
                //创建行
                row = sheet.createRow(i);
                //设置默认行高
                row.setHeightInPoints(25);
                //行数据处理
                Map<java.lang.String, Object> stringObjectMap = maps.get(i - 1);
                for(Object value : stringObjectMap.keySet()){
                    //行单元格
                    cellRow = row.createCell(cellColumn);
                    cellRow.setCellStyle(style);
                    //如果行数据中有图片时候的处理
                    if (value.equals("file")){
                        File[] file = (File[]) stringObjectMap.get(value);
                        if (file == null || file.length == 0){
                            cellRow.setCellValue("");
                            continue;
                        }else{
                            row.setHeightInPoints(150);

                            for (int x=0;x<file.length;x++){
                                if (x>0){
                                    cellRow = row.createCell(cellColumn);
                                    cellRow.setCellStyle(style);
                                }
                                sheet.setColumnWidth(cellColumn,9100);
                                bufferImg = ImageIO.read(file[x]);
                                ImageIO.write(bufferImg, "jpg", byteArrayOut);
                                anchor = new HSSFClientAnchor(0, 0, 1023, 255,(short) cellColumn, i, (short) cellColumn, i);
                               // anchor.setAnchorType(3);
                                patriarch.createPicture(anchor, wb.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
                                cellColumn++;
                            }
                            continue;
                        }
                    }
                    cellRow.setCellValue(stringObjectMap.get(value).toString());
                    cellColumn ++;
                }

            }

            fileOut = new FileOutputStream(uploadPath);
            // 写入excel文件
            wb.write(fileOut);

        }catch (Exception e){
            System.out.println(e.fillInStackTrace());
        }finally {
            if(fileOut != null){
                try {
                    fileOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return "success";
    }


    /**
     *功能描述 将java类对象属性-值转换成map的键值对
     *           去除getClass方法属性，以及自定义的file属性放置最后。
     * @author gjx
     * @date 2019/7/10
     * @param [javaBean]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    public static Map<java.lang.String, Object> javaBean2Map(Object javaBean) throws Exception {
        Map<java.lang.String, Object> map = new LinkedHashMap<>();
        //反射的实现方式:第一种
        /*Class<Student> studentClass = Student.class;
        studentClass.getClass();*/
        //第二种实现方式
        Method[] methods = javaBean.getClass().getMethods(); // 获取所有方法
        //第三种实现方式
        /*Class.forName("类路径");*/
        java.lang.String fileName = null;
        File[] files = null;
        for (Method method : methods) {
            if (method.getName().startsWith("get")) {
                java.lang.String field = method.getName(); // 拼接属性名
                if (field.contains("getClass")){
                    continue;
                }
                field = field.substring(field.indexOf("get") + 3);
                field = field.toLowerCase().charAt(0) + field.substring(1);
                Object value = method.invoke(javaBean, (Object[]) null); // 执行方法
                if (field.equals("file")){
                    fileName = field;
                    files = (File[]) value;
                    continue;
                }
                map.put(field, value);
            }
        }
        if (fileName != null){
            map.put(fileName,files);
        }
        return map;
    }

    /**
     *功能描述 递归调用让字符串对中调换
     * @author gjx
     * @date 2019/7/14
     * @param [originStr]
     * @return java.lang.String
     */
    public static java.lang.String reverse(java.lang.String originStr) {
        if(originStr == null || originStr.length() <= 1)
            return originStr;
        java.lang.String substring = originStr.substring(1);
        java.lang.String s = reverse(substring) + originStr.charAt(0);
        return s;
    }
    
    public Map<java.lang.String, java.lang.String> getMap(){

		Map<java.lang.String, java.lang.String> map = new HashMap<>();
		map.put("name","姓名");
		map.put("age","年龄");
		map.put("email","邮箱");
		map.put("id","唯一标识");
		map.put("file","图片");

		return map;

	}
    public void testModuleExcel() throws Exception {
    	List<Map<java.lang.String,Object>> list = new ArrayList<>();
    	File[] files = new File[2];
    	File[] files1 = new File[0];
    	files[0] = new File("C:\\sm.jpg");
    	files[1] = new File("C:\\sm.jpg");
    	Text user1 = new Text();
    	user1.setId(1L);
    	user1.setName("gjx");
    	user1.setEmail("1345@163.com");
    	user1.setAge(23);
    	user1.setFile(files);
    	Text user2 = new Text();
    	user2.setId(2L);
    	user2.setName("gjy");
    	user2.setEmail("3745@163.com");
    	user2.setAge(25);
    	user2.setFile(files1);

    	Map<java.lang.String, Object> stringObjectMap = Exclupload.javaBean2Map(user1);
    	Map<java.lang.String, Object> stringObjectMap1 = Exclupload.javaBean2Map(user2);
    	list.add(stringObjectMap);
    	list.add(stringObjectMap1);

    	Object[] objects = stringObjectMap.keySet().toArray();
    	java.lang.String[] titles = new java.lang.String[objects.length];
    	Map<java.lang.String, java.lang.String> map = getMap();
    	for(int i=0;i<titles.length;i++){
    		java.lang.String s1 = objects[i].toString();
    		java.lang.String s = map.get(s1);
    		titles[i] = s;
    	}

    	Exclupload.excelOut(titles,list.size(),list,"");
    }
}