基于POI封装Excel导出,支持百万数据集

public class ExportExcel {

    /**
     * 导出Excel
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcel(String[] fields, T t, List<T> list, String excelName, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }


    /**
     * 导出excel包含单位
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param unit      单位名称
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithUnit(String[] fields, T t, List<T> list, String excelName, String unit, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setUnit("单位:亩");
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }

    /**
     * 导出excel包含字典
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param map       字典集合
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithDic(String[] fields, T t, List<T> list, String excelName, Map<String, Map<Object, Object>> map, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setDicMap(map);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }


    /**
     * 导出excel包含单位和字典
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param unit      单位名称
     * @param map       字典集合
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithUnitAndDic(String[] fields, T t, List<T> list, String excelName, String unit, Map<String, Map<Object, Object>> map, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setUnit(unit);
        createExcel.setDicMap(map);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }


    /**
     * 导出双表头Excel
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param queue2    合并表头
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithCoupleTitle(String[] fields, T t, List<T> list, String excelName, Queue<ThreeTuple<Integer, Integer, String>> queue2, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setQueue2(queue2);
        createExcel.setExcelTitleEnum(CreateExcel.ExcelTitleEnum.TWO);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }

    /**
     * 导出双表头excel包含单位
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param unit      单位名称
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithCoupleTitleAndUnit(String[] fields, T t, List<T> list, String excelName, Queue<ThreeTuple<Integer, Integer, String>> queue2, String unit, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setQueue2(queue2);
        createExcel.setExcelTitleEnum(CreateExcel.ExcelTitleEnum.TWO);
        createExcel.setUnit(unit);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }


    /**
     * 导出三表头Excel
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param queue2    合并第二列表头
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithThreeTitle(String[] fields, T t, List<T> list, String excelName, Queue<ThreeTuple<Integer, Integer, String>> queue2, Queue<ThreeTuple<Integer, Integer, String>> queue3, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setQueue2(queue2);
        createExcel.setQueue3(queue3);
        createExcel.setExcelTitleEnum(CreateExcel.ExcelTitleEnum.TWO);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }

    /**
     * 导出三表头excel包含单位
     *
     * @param fields    要导出的字段
     * @param t         实例化空的T对象
     * @param list      要导出数据的集合
     * @param excelName 导出excel名称
     * @param unit      单位名称
     * @param response  导出excel序列化到Response中
     * @param <T>       导出Excel的T对象
     */
    public <T> void exportExcelWithThreeTitleAndUnit(String[] fields, T t, List<T> list, String excelName, Queue<ThreeTuple<Integer, Integer, String>> queue2, Queue<ThreeTuple<Integer, Integer, String>> queue3, String unit, HttpServletResponse response) {
        CreateExcel createExcel = new CreateExcel().newInstance(t, list, fields, excelName);
        createExcel.setQueue2(queue2);
        createExcel.setQueue3(queue3);
        createExcel.setExcelTitleEnum(CreateExcel.ExcelTitleEnum.TWO);
        createExcel.setUnit(unit);
        createExcel.drawExcel();
        createExcel.saveAsResponse(response);
    }


}

public class CreateExcel<T> {

    /**
     * Excel title enum
     */
    public enum ExcelTitleEnum {
        ONE, TWO, THREE
    }


    /**
     * 创建一个excel
     */
    private HSSFWorkbook wb;

    /**
     * 创建单个sheet
     */
    private HSSFSheet sheet;

    private HSSFCellStyle normalStyle;
    private HSSFCellStyle doubleCellStyle;
    private HSSFCellStyle dateCellStyle;
    private HSSFCellStyle fontCellStyle;

    private boolean bTitleVis = true;

    /**
     * excel title num. default one
     */
    private ExcelTitleEnum excelTitleEnum = ExcelTitleEnum.ONE;

    /**
     * 绘制表头
     */
    private T t;

    /**
     * 填写表内容
     */
    private List<T> arrays;

    /**
     * excel的名称,用于画表头,sheet名称,输出文件名称
     */
    private String excelName;

    private String unit;

    private String[] fields;


    /**
     * 两行表头
     */
    private Queue<ThreeTuple<Integer, Integer, String>> queue2;

    /**
     * 三行表头
     */
    private Queue<ThreeTuple<Integer, Integer, String>> queue3;

    private int index = 0;

    private Map<String, Map<Object, Object>> dicMap = new HashedMap();


    public void setbTitleVis(boolean bTitleVis) {
        this.bTitleVis = bTitleVis;
    }

    public HSSFWorkbook getWb() {
        return wb;
    }

    public void setDicMap(Map<String, Map<Object, Object>> dicMap) {
        this.dicMap = dicMap;
    }


    public void setExcelTitleEnum(ExcelTitleEnum excelTitleEnum) {
        this.excelTitleEnum = excelTitleEnum;
    }

    public void setQueue2(Queue<ThreeTuple<Integer, Integer, String>> queue2) {
        this.queue2 = queue2;
    }

    public void setQueue3(Queue<ThreeTuple<Integer, Integer, String>> queue3) {
        this.queue3 = queue3;
    }


    /**
     * 实例化一个excel
     *
     * @return
     */
    public CreateExcel newInstance(T t, List<T> arrays, String[] fields, String excelName) {

        this.t = t;
        this.arrays = arrays;
        this.excelName = excelName;
        this.fields = fields;
        return this;
    }
    
    public void drawExcel(String title[],String []end) {
        createSheet(); //创建表格
        createTitle();  //绘制表格头部
        createUnit(title);   // 绘制单位
        createTableTitle();  // 绘制表格表头
        createTableContent();   //填充表格内容
        index=index+2;
        createUnit(end);  //绘制表格尾部
    }
    
    public void drawExcel() {
        createSheet(); //创建表格
        createTitle();  //绘制表格头部
        createUnit();   // 绘制单位
        createTableTitle();  // 绘制表格表头
        createTableContent();   //填充表格内容
    }


    /**
     * 将excel数据缓存到response中
     *
     * @param response
     */
    public void saveAsResponse(HttpServletResponse response) {
        try {
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(this.excelName, "utf-8") + ".xls");
            OutputStream out = response.getOutputStream();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            wb.write(stream);
            byte[] bytes = stream.toByteArray();
            out.write(bytes);
            out.close();
        } catch (
                UnsupportedEncodingException e)

        {
            e.printStackTrace();
        } catch (
                IOException e)

        {
            e.printStackTrace();
        }
    }

    public void saveAsFile(String filePath) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                file.createNewFile();
            }
            //保存excel
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            wb.write(fileOutputStream);
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void createSheet() {

        // 第一步,创建一个webbook,对应一个Excel文件
        this.wb = new HSSFWorkbook();
        // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
        this.sheet = wb.createSheet(excelName);

        // 设置样式
        this.normalStyle = setNormalStyle(wb.createCellStyle());
        this.dateCellStyle = setDateStyle(wb.createCellStyle());
        this.doubleCellStyle = setDoubleStyle(wb.createCellStyle());
        this.fontCellStyle = setFontStyle(wb.createCellStyle());
    }


    /**
     * 绘制表的title
     */
    private void createTitle() {
        if (!StrUtil.isNullOrEmpty(this.excelName) && true == bTitleVis) {
            HSSFRow row = sheet.createRow(index++);
            row.setHeight((short) (30 * 20));
            //setCellBorder(row); //设置边框

            HSSFCell cell = row.createCell(0);
            cell.setCellValue(excelName);
            cell.setCellStyle(this.fontCellStyle);
            
            sheet.addMergedRegion(new CellRangeAddress(index - 1, index - 1, 0, fields.length - 1));
            
        }
    }
    
    /**
     * 添加单位
     */
    private void createUnit(String [] title) {
    	HSSFRow row = sheet.createRow(index++);
    	if(title.length>0){
    		 //setCellBorder(row); //设置边框
    		int length = title.length;
    		for(int i=0;i<length;i++){
    			int num =i*4;
    			HSSFCell cell = row.createCell(num);
                cell.setCellValue(title[i]);
    		}
    	}
            
    }

    /**
     * 添加单位
     */
    private void createUnit() {
        if (!StrUtil.isNullOrEmpty(unit)) {
            HSSFRow row = sheet.createRow(index++);

            //setCellBorder(row); //设置边框

            HSSFCell cell = row.createCell(0);
            cell.setCellValue(unit);
        }
    }
    
    /**
     * 是否存在属性
     * @param clz
     * @param fieldName
     * @return
     */
    public static boolean existsField(Class clz,String fieldName){
    	if(null!=clz){
    		Field[] fields = clz.getDeclaredFields();
        	for(Field f : fields) {
        		if(fieldName.equals(f.getName())){
        			return true;
        		}
        	}
    	}
        return false;
    }
   
    /**
     * 根据@ExcelTitle注解获取表头定义文字
     * @param clz
     * @param fieldName
     * @return
     */
    public ExcelTitle getExcelTitle(Class<?> clz,String fieldName){
    	ExcelTitle excelTitle =null;
    	try {
    		//Class<?> clazzChild =t.getClass();
        	Class<?> clazz=clz.getSuperclass(); 
        	if(null!=clazz){
        		if(existsField(clazz,fieldName)){
        			excelTitle = clazz.getDeclaredField(fieldName).getAnnotation(ExcelTitle.class);
        		}else{
            		if(existsField(clz,fieldName)){
            			excelTitle = clz.getDeclaredField(fieldName).getAnnotation(ExcelTitle.class);
            		}
        		}
        	}else{
        		if(existsField(clz,fieldName)){
        			excelTitle = clz.getDeclaredField(fieldName).getAnnotation(ExcelTitle.class);
        		}
        	}
		} catch (Exception e) {
			return null;
		}
    	return excelTitle;
    }
    
    
    /**
     * 绘制表头
     */
    private void createTableTitle() {

        if (excelTitleEnum == ExcelTitleEnum.ONE) {
            //绘制一级表头

            HSSFRow row = sheet.createRow(index++);
            setCellBorder(row);

            for (int i = 0; i < fields.length; i++) {
                HSSFCell cell = row.getCell(i);

                try {
                	ExcelTitle excelTitle =getExcelTitle(t.getClass(),fields[i]);
                    //ExcelTitle excelTitle = t.getClass().getDeclaredField(fields[i]).getAnnotation(ExcelTitle.class);
                    if (null != excelTitle) {
                        cell.setCellValue(excelTitle.value());
                    } else {
                        cell.setCellValue("");
                    }
                } catch (Exception e) {
                    cell.setCellValue("");
                }

                this.sheet.setColumnWidth(i, 15 * 256);
            }
        } else if (excelTitleEnum == ExcelTitleEnum.TWO) {
            // 绘制二级表头
            int titleIndex = index;
            HSSFRow row1 = sheet.createRow(index++);
            setCellBorder(row1);

            HSSFRow row2 = sheet.createRow(index++);
            setCellBorder(row2);

            boolean queueStart = false;
            ThreeTuple<Integer, Integer, String> tuple = null;
            for (int i = 0; i < fields.length; i++) {
                HSSFCell cell1 = row1.getCell(i);
                HSSFCell cell2 = row2.getCell(i);

                try {
                    //ExcelTitle excelTitle = t.getClass().getDeclaredField(fields[i]).getAnnotation(ExcelTitle.class);
                	ExcelTitle excelTitle =getExcelTitle(t.getClass(),fields[i]);
                    if (!queueStart && queue2.size() > 0) {
                        tuple = queue2.poll();
                        queueStart = true;
                    }

                    if (i >= tuple.first && i <= tuple.second) {
                        //合并的表头
                        if (i == tuple.first) {
                            sheet.addMergedRegion(new CellRangeAddress(titleIndex, titleIndex, tuple.first, tuple.second));
                            cell1.setCellValue(tuple.third);
                        }

                        if (null != excelTitle) {
                            cell2.setCellValue(excelTitle.value());
                        } else {
                            cell2.setCellValue("");
                        }

                        if (i == tuple.second) {
                            queueStart = false;
                        }
                    } else {

                        sheet.addMergedRegion(new CellRangeAddress(titleIndex, titleIndex + 1, i, i));
                        if (null != excelTitle) {
                            cell1.setCellValue(excelTitle.value());
                        } else {
                            cell1.setCellValue("");
                        }
                    }
                } catch (Exception e) {
                    cell1.setCellValue("");
                    cell2.setCellValue("");
                }

                this.sheet.setColumnWidth(i, 15 * 256);
            }
        } else if (excelTitleEnum == ExcelTitleEnum.THREE) {

            // 绘制二级表头
            int titleIndex = index;
            HSSFRow row1 = sheet.createRow(index++);
            setCellBorder(row1);

            HSSFRow row2 = sheet.createRow(index++);
            setCellBorder(row2);

            HSSFRow row3 = sheet.createRow(index++);
            setCellBorder(row3);

            boolean queueTwoStart = false;
            boolean queueThreeStart = false;
            ThreeTuple<Integer, Integer, String> tupleTwo = null;
            ThreeTuple<Integer, Integer, String> tupleThree = null;
            for (int i = 0; i < fields.length; i++) {
                HSSFCell cell1 = row1.getCell(i);
                HSSFCell cell2 = row2.getCell(i);
                HSSFCell cell3 = row3.getCell(i);

                try {
                   // ExcelTitle excelTitle = t.getClass().getDeclaredField(fields[i]).getAnnotation(ExcelTitle.class);
                	ExcelTitle excelTitle =getExcelTitle(t.getClass(),fields[i]);
                    if (!queueTwoStart && queue2.size() > 0) {
                        tupleTwo = queue2.poll();
                        queueTwoStart = true;
                    }

                    if (!queueThreeStart && queue3.size() > 0) {
                        tupleThree = queue3.poll();
                        queueThreeStart = true;
                    }

                    if (i >= tupleTwo.first && i <= tupleTwo.second) {
                        if (i == tupleTwo.first) {
                            sheet.addMergedRegion(new CellRangeAddress(titleIndex, titleIndex, tupleTwo.first, tupleTwo.second));
                            cell1.setCellValue(tupleTwo.third);
                        }

                        if (i == tupleThree.first) {
                            sheet.addMergedRegion(new CellRangeAddress(titleIndex + 1, titleIndex + 1, tupleThree.first, tupleThree.second));
                            cell2.setCellValue(tupleThree.third);
                        }

                        if (i == tupleThree.second) {
                            queueThreeStart = false;
                        }

                        if (null != excelTitle) {
                            cell3.setCellValue(excelTitle.value());
                        } else {
                            cell3.setCellValue("");
                        }

                    } else {
                        if (i == tupleTwo.second) {
                            queueTwoStart = false;
                        }

                        sheet.addMergedRegion(new CellRangeAddress(titleIndex, titleIndex + 2, i, i));
                        if (null != excelTitle) {
                            cell1.setCellValue(excelTitle.value());
                        } else {
                            cell1.setCellValue("");
                        }
                    }
                } catch (Exception e) {
                    cell1.setCellValue("");
                    cell2.setCellValue("");
                    cell3.setCellValue("");
                }

                this.sheet.setColumnWidth(i, 15 * 256);
            }
        }
    }



    /**
     * 绘制表的内容
     */
    private void createTableContent() {
        if (0 != arrays.size()) {
            for (int i = 0; i < arrays.size(); i++) {
                HSSFRow row = sheet.createRow(index++);
                setCellBorder(row);
                Class<?> clazzChild =arrays.get(i).getClass();
            	Class<?> clazz=clazzChild.getSuperclass(); 
                for (int j = 0; j < fields.length; j++) {
                    Object value = null;
                    Field field = null;

                    try {
                    	if(null!=clazz){
                    		if(existsField(clazz,fields[j])){
                    			field = clazz.getDeclaredField(fields[j]);
                    		}else{
                        		if(existsField(clazzChild,fields[j])){
                        			field = clazzChild.getDeclaredField(fields[j]);
                        		}
                    		}
                    	}else{
                    		if(existsField(clazzChild,fields[j])){
                    			field = clazzChild.getDeclaredField(fields[j]);
                    		}
                    	}
                        
                        //field = arrays.get(i).getClass().getDeclaredField(fields[j]);
                        field.setAccessible(true);
                        value = field.get(arrays.get(i));

                        if (null != value && null != dicMap && 0 != dicMap.size()) {  //将字典转换为实际值
                            if (null != dicMap.get(fields[j])) {
                                value = dicMap.get(fields[j]).get(value);
                            }
                        }


                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    setCellValue(row, j, value);
                }
            }
        }
    }


    private void setCellValue(HSSFRow row, int colIndex, Object value) {

        HSSFCell hssfCell = row.createCell(colIndex);
        hssfCell.setCellStyle(this.normalStyle);
        if (null == value) {
            hssfCell.setCellValue("");
        } else if (value instanceof Integer) {
            hssfCell.setCellValue((Integer) value);
        } else if (value instanceof Short) {
            hssfCell.setCellValue((Short) value);
        } else if (value instanceof Double) {
            hssfCell.setCellValue((Double) value);
            hssfCell.setCellStyle(this.doubleCellStyle);
        } else if (value instanceof Boolean) {
            hssfCell.setCellValue((Boolean) value);
        } else if (value instanceof Short) {
            hssfCell.setCellValue((Short) value);
        } else if (value instanceof Date) {
            hssfCell.setCellValue((Date) value);
            hssfCell.setCellStyle(this.dateCellStyle);
        } else if (value instanceof Long) {
            hssfCell.setCellValue((Long) value);
        } else if (value instanceof BigDecimal) {
            hssfCell.setCellValue(((BigDecimal) value).doubleValue());
            hssfCell.setCellStyle(this.doubleCellStyle);
        } else {
            hssfCell.setCellValue((String) value);
        }

    }


    /**
     * 公共样式
     *
     * @param style
     * @return
     */
    private HSSFCellStyle setNormalStyle(HSSFCellStyle style) {
        style.setAlignment(HSSFCellStyle.VERTICAL_CENTER);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框
        style.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框
        style.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
        style.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框

        return style;
    }

    private HSSFCellStyle setFontStyle(HSSFCellStyle style) {
        //设置字体
        HSSFFont font = this.wb.createFont();
        font.setFontHeightInPoints((short) 18);//.setFontHeight();

        style.setFont(font);
        style.setAlignment(HSSFCellStyle.VERTICAL_CENTER);
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        return style;
    }

    /**
     * 设置double类型格式数据
     *
     * @param style
     * @return
     */
    private HSSFCellStyle setDoubleStyle(HSSFCellStyle style) {
        setNormalStyle(style);
        style.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
        return style;
    }

    /**
     * 设置日期类型格式数据
     *
     * @param style
     * @return
     */
    private HSSFCellStyle setDateStyle(HSSFCellStyle style) {
        setNormalStyle(style);
        HSSFDataFormat format = wb.createDataFormat();
        style.setDataFormat(format.getFormat("yyyy年m月d日"));
        return style;
    }

    private void setCellBorder(HSSFRow row) {
        for (int i = 0; i < fields.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(normalStyle);
        }

    }

    public void setUnit(String unit) {
        this.unit = unit;
    }
}

猜你喜欢

转载自blog.csdn.net/chunchunaiheliu/article/details/80613849