excel百万级导出工具类

package com.jd.las.secondhand.portal.util;

import com.jd.fastjson.JSON;
import com.jd.las.secondhand.annotation.Excel;
import com.jd.las.secondhand.annotation.ExcelEnum;


import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description: 导出工具类
 * @Author: lizhihua16
 * @Email: [email protected]
 * @Create: 2018-04-18 15:54
 */
public class ExcelUtilPro {

    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    //标题名
    private String title;
    //sheet名数组
    private String sheetNames;
    //列名数组
    private String[] columnNames;
    //列对应实体名数组
    private String[] entityNames;
    //数据
    private int sum = 0;
    private SXSSFWorkbook workbook;
    private CellStyle columnTopStyle;
    private CellStyle style;
    private Sheet sheet;

    private static final ConcurrentHashMap<String, Method> methodCache = new ConcurrentHashMap();
    private static final ConcurrentHashMap<String, Field> fieldCache = new ConcurrentHashMap();
    private static final LinkedHashMap<String, String> excelEunmCache = new LinkedHashMap();
    private ExcelUtilPro(LinkedHashMap<String, String> map, String title){
        workbook = new SXSSFWorkbook(100);

        this.sheetNames = title;
        this.title = title;
        this.columnTopStyle = this.getColumnTopStyle(workbook);  // 列头样式对象
        this.style = this.getStyle(workbook);  //单元格样式对象
        this.sheet = workbook.createSheet(sheetNames);
        int column = 0;

        columnNames = new String[map.size()];
        entityNames = new String[map.size()];
        for(Iterator var6 = map.keySet().iterator(); var6.hasNext(); ++column) {
            String key = (String)var6.next();
            columnNames[column] = map.get(key);
            entityNames[column] = key;
        }
    }

    /**
     * 获取导出工具类实例对象
     * @param type
     * @param title
     * @return
     */
    public static ExcelUtilPro newInstance(Class type, String title){
        String className = type.getName();
        Field[] fields = type.getDeclaredFields();
        LinkedHashMap<String, String> map = new LinkedHashMap();
        Field[] var5 = fields;
        int var6 = fields.length;

        for(int var7 = 0; var7 < var6; ++var7) {
            Field field = var5[var7];
            if (field.isAnnotationPresent(Excel.class)) {
                Excel excel = field.getAnnotation(Excel.class);
                map.put(field.getName(),excel.columnName());
            }
            if(field.isAnnotationPresent(ExcelEnum.class)){
                ExcelEnum excelEnum = field.getAnnotation(ExcelEnum.class);
                String[] codes = excelEnum.code();
                String[] names = excelEnum.name();
                if (codes != null) {
                    for (int i = 0; i < codes.length; i++) {
                        String key = className + field.getName()+codes[i];
                        excelEunmCache.put(key,names[i]);
                    }
                }
            }
        }
        return new ExcelUtilPro(map,title);
    }

    /**
     * 分批添加元素
     * @param list
     */
    public void addList(List list){
        List<Object[]> datas = new ArrayList<Object[]>();
        if(null == list){
            list = new ArrayList();
        }
        for (Object t : list) {
            datas.add(beanToArray(t, entityNames));
        }
        createWorkBook(datas,sum);
        sum += datas.size();
    }

    /**
     * 每次获取一个SXSSFWorkbook 这里不会清理磁盘上的文件,请调用dispose()方法进行清理
     * @param list
     * @return
     */
    public SXSSFWorkbook addListAddGetSXSSFWorkbook(List list){
        List<Object[]> datas = new ArrayList<Object[]>();
        for (Object t : list) {
            datas.add(beanToArray(t, entityNames));
        }
        createWorkBook(datas,0);
        SXSSFWorkbook sxssfWorkbook = workbook;
        workbook = new SXSSFWorkbook(100);
        return sxssfWorkbook;
    }
    /**
     * 获取导出数据
     * @return
     */
    public byte[] exportExcel(){
        byte[] bytes = null;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        try {
            workbook.write(out);
            //清理磁盘文件
            workbook.dispose();
            bytes = out.toByteArray();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return bytes;
    }

    /**
     * 写入流
     * @param out
     */
    public void write(OutputStream out){
        try {
            workbook.write(out);
            //清理磁盘文件
            workbook.dispose();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
    /**
     * 组装excel
     * @param datas
     * @param begin
     */
    private void createWorkBook(List<Object[]> datas,int begin) {

        int colunmSize = columnNames.length;

        if(begin==0) {
            //设置标题
            Row titleRow = sheet.createRow(0);
            Cell titleRowCell = titleRow.createCell(0, Cell.CELL_TYPE_STRING);

            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, colunmSize - 1));
            titleRowCell.setCellStyle(columnTopStyle);
            titleRowCell.setCellValue(title);

            //设置列名
            Row columnRow = sheet.createRow(1);
            for (int i = begin; i < colunmSize; i++) {
                Cell columnRowCell = columnRow.createCell(i, Cell.CELL_TYPE_STRING);
                HSSFRichTextString text = new HSSFRichTextString(columnNames[i]);
                columnRowCell.setCellValue(columnNames[i]);
                columnRowCell.setCellStyle(columnTopStyle);
                sheet.setColumnWidth(i, text.length() * 1000);
            }
        }
        //设置数据
        for (int i = 0; i < datas.size(); i++) {
            Object[] obj = datas.get(i);
            Row dataRow = sheet.createRow(i + 2 + begin);
            for (int j = 0; j < obj.length; j++) {
                Cell dataRowCell = dataRow.createCell(j, Cell.CELL_TYPE_STRING);
                if (null != obj[j] && obj[j].toString()!=null && !"".equals(obj[j].toString())) {
                    dataRowCell.setCellValue(obj[j].toString());
                } else {
                    dataRowCell.setCellValue("");
                }
                dataRowCell.setCellStyle(style);
            }
        }

    }

    /**
     * javaBean转为Object[]
     */
    private Object[] beanToArray(Object t, String[] entityNames) {
        String className = t.getClass().getName();
        Object[] objArray = new Object[entityNames.length];
        try {
            for (int i = 0; i < entityNames.length; i++) {
                String name = "get"+entityNames[i].substring(0, 1).toUpperCase() + entityNames[i].substring(1);
                String key = className+entityNames[i];
                Method m = methodCache.get(key);
                if(null == m){
                    m = t.getClass().getMethod(name);
                    methodCache.put(key,m);
                }

                Field field = fieldCache.get(key);
                if(field == null){
                    field = t.getClass().getDeclaredField(entityNames[i]);
                    fieldCache.put(key,field);
                }

                Object object = m.invoke(t);

                if(field.isAnnotationPresent(ExcelEnum.class)){
                    objArray[i] = excelEunmCache.get(key + object);
                }else if(object!=null && object instanceof Date){
                    objArray[i] = SIMPLE_DATE_FORMAT.format(object);
                }else{
                    objArray[i] =object;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("类型转换失败,参数:" + JSON.toJSONString(t) + ","
                    + JSON.toJSONString(entityNames), e);

        }
        return objArray;
    }
    /**
     * 列头单元格样式
     */
    private CellStyle getColumnTopStyle(Workbook workbook) {

        //设置字体
        Font font = workbook.createFont();
        //设置字体大小
        font.setFontHeightInPoints((short) 11);
        //字体加粗
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);
        //设置字体名字
        font.setFontName("Courier New");
        //设置样式;
        CellStyle style = workbook.createCellStyle();
        //设置底边框;
        style.setBorderBottom(CellStyle.BORDER_THIN);
        //设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //设置左边框;
        style.setBorderLeft(CellStyle.BORDER_THIN);
        //设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //设置右边框;
        style.setBorderRight(CellStyle.BORDER_THIN);
        //设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //设置顶边框;
        style.setBorderTop(CellStyle.BORDER_THIN);
        //设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(CellStyle.ALIGN_CENTER);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);

        return style;
    }

    /**
     * 列数据信息单元格样式
     */
    private CellStyle getStyle(Workbook workbook) {
        //设置字体
        Font font = workbook.createFont();
        //设置字体名字
        font.setFontName("Courier New");
        //设置样式;
        CellStyle style = workbook.createCellStyle();
        //设置底边框;
        style.setBorderBottom(CellStyle.BORDER_THIN);
        //设置底边框颜色;
        style.setBottomBorderColor(HSSFColor.BLACK.index);
        //设置左边框;
        style.setBorderLeft(CellStyle.BORDER_THIN);
        //设置左边框颜色;
        style.setLeftBorderColor(HSSFColor.BLACK.index);
        //设置右边框;
        style.setBorderRight(CellStyle.BORDER_THIN);
        //设置右边框颜色;
        style.setRightBorderColor(HSSFColor.BLACK.index);
        //设置顶边框;
        style.setBorderTop(CellStyle.BORDER_THIN);
        //设置顶边框颜色;
        style.setTopBorderColor(HSSFColor.BLACK.index);
        //在样式用应用设置的字体;
        style.setFont(font);
        //设置自动换行;
        style.setWrapText(false);
        //设置水平对齐的样式为居中对齐;
        style.setAlignment(CellStyle.ALIGN_CENTER);
        //设置垂直对齐的样式为居中对齐;
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);

        return style;
    }

}

/**
 * @Description: TODO
 * @Author: lizhihua16
 * @Email: [email protected]
 * @Create: 2018-03-06 15:11
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Excel {
    String columnName();
}
/**
 * @Description: 导出工具类枚举
 * 使用方法:@ExcelEnum(code = {"0","1"},name={"",""})
 * @Author: lizhihua16
 * @Email: [email protected]
 * @Create: 2018-04-19 10:08
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ExcelEnum {
    String[] code();
    String[] name();
}


猜你喜欢

转载自blog.csdn.net/rock93/article/details/80059966