Excel导出工具类.

Wesley13
• 阅读 684

 Excel导出工具类.--POI

import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.anhry.app.util.bean.SystemBean;
import com.anhry.app.util.excel.annoation.Excel;


/**
 * Excel导出工具类.
 */
public class ExportExcel<T> {

    public static final Logger LOG = LoggerFactory.getLogger(ExportExcel.class);
    /**
     * 
     * @param title     Sheet名字
     * @param pojoClass Excel对象Class
     * @param dataSet   Excel对象数据List
     * @param out       输出流
     */
    public void exportExcel(String title, Class<T> pojoClass,
            Collection<T> dataSet, OutputStream out) {
        // 使用userModel模式实现的,当excel文档出现10万级别的大数据文件可能导致OOM内存溢出
        exportExcelInUserModel(title, pojoClass, dataSet, out);
        // 使用eventModel实现,可以一边读一边处理,效率较高,但是实现复杂,暂时未实现
    }

    private void exportExcelInUserModel(String title, Class<T> pojoClass,
            Collection<T> dataSet, OutputStream out) {
        try {
            // 首先检查数据看是否是正确的
            if (dataSet == null || dataSet.size() == 0) {
                throw new Exception("导出数据为空!");
            }
            if (title == null || out == null || pojoClass == null) {
                throw new Exception("传入参数不能为空!");
            }
            // 声明一个工作薄
            Workbook workbook = new HSSFWorkbook();
            // 生成一个表格
            Sheet sheet = workbook.createSheet(title);

            // 标题
            List<String> exportFieldTitle = new ArrayList<String>();
            List<Integer> exportFieldWidth = new ArrayList<Integer>();
            // 拿到所有列名,以及导出的字段的get方法
            List<Method> methodObj = new ArrayList<Method>();
            Map<String, Method> convertMethod = new HashMap<String, Method>();
            // 得到所有字段
            Field fileds[] = pojoClass.getDeclaredFields();
            // 遍历整个filed
            for (int i = 0; i < fileds.length; i++) {
                Field field = fileds[i];
                Excel excel = field.getAnnotation(Excel.class);
                // 如果设置了annottion
                if (excel != null) {
                    // 添加到标题
                    exportFieldTitle.add(excel.exportName());
                    // 添加标题的列宽
                    exportFieldWidth.add(excel.exportFieldWidth());
                    // 添加到需要导出的字段的方法
                    String fieldname = field.getName();
                    // System.out.println(i+"列宽"+excel.exportName()+" "+excel.exportFieldWidth());
                    StringBuffer getMethodName = new StringBuffer("get");
                    getMethodName.append(fieldname.substring(0, 1)
                            .toUpperCase());
                    getMethodName.append(fieldname.substring(1));

                    Method getMethod = pojoClass.getMethod(getMethodName
                            .toString(), new Class[] {});

                    methodObj.add(getMethod);
                    if (excel.exportConvert() == true) {
                        StringBuffer getConvertMethodName = new StringBuffer(
                                "get");
                        getConvertMethodName.append(fieldname.substring(0, 1)
                                .toUpperCase());
                        getConvertMethodName.append(fieldname.substring(1));
                        getConvertMethodName.append("Convert");
                        Method getConvertMethod = pojoClass
                                .getMethod(getConvertMethodName.toString(),
                                        new Class[] {});
                        convertMethod.put(getMethodName.toString(),
                                getConvertMethod);
                    }
                }
            }
            int index = 0;
            // 产生表格标题行
            Row row = sheet.createRow(index);
            for (int i = 0, exportFieldTitleSize = exportFieldTitle.size(); i < exportFieldTitleSize; i++) {
                Cell cell = row.createCell(i);
                // cell.setCellStyle(style);
                RichTextString text = new HSSFRichTextString(exportFieldTitle
                        .get(i));
                cell.setCellValue(text);
            }

            // 设置每行的列宽
            for (int i = 0; i < exportFieldWidth.size(); i++) {
                // 256=65280/255
                sheet.setColumnWidth(i, 256 * exportFieldWidth.get(i));
            }
            Iterator its = dataSet.iterator();
            // 循环插入剩下的集合
            while (its.hasNext()) {
                // 从第二行开始写,第一行是标题
                index++;
                row = sheet.createRow(index);
                Object t = its.next();
                for (int k = 0, methodObjSize = methodObj.size(); k < methodObjSize; k++) {
                    Cell cell = row.createCell(k);
                    Method getMethod = methodObj.get(k);
                    Object value = null;
                    if (convertMethod.containsKey(getMethod.getName())) {
                        Method cm = convertMethod.get(getMethod.getName());
                        value = cm.invoke(t, new Object[] {});
                    } else {
                        value = getMethod.invoke(t, new Object[] {});
                    }
                    cell.setCellValue(value == null ? "" : value.toString());
                }
            }

            workbook.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    /**
     * 
     * @param title     Sheet名字
     * @param pojoClass Excel对象Class
     * @param dataSet   Excel对象数据List
     * @param out       输出流
     */
    public HSSFWorkbook  exportExcel(String title, Class<T> pojoClass,
            Collection<T> dataSet) {
        // 使用userModel模式实现的,当excel文档出现10万级别的大数据文件可能导致OOM内存溢出
        return exportExcelInUserModel2File(title, pojoClass, dataSet, null);
    }
    /**
     * 
     * @param title     Sheet名字
     * @param pojoClass Excel对象Class
     * @param dataSet   Excel对象数据List
     * @param exportFields   Excel对象选择要导出的字段 
     * @param out       输出流
     */
    public HSSFWorkbook  exportExcel(String title, Class<T> pojoClass,
            Collection<T> dataSet,List<String> exportFields) {
        // 使用userModel模式实现的,当excel文档出现10万级别的大数据文件可能导致OOM内存溢出
        return exportExcelInUserModel2File(title, pojoClass, dataSet, exportFields);
    }
    HSSFWorkbook exportExcelInUserModel2File(String title, Class<T> pojoClass,
            Collection<T> dataSet)  {
        return exportExcelInUserModel2File(title, pojoClass, dataSet, null);
    }
    private HSSFWorkbook exportExcelInUserModel2File(String title, Class<T> pojoClass,
            Collection<T> dataSet, List<String> exportFields) {
        // 声明一个工作薄
        HSSFWorkbook  workbook = null;
        try {
            // 声明一个工作薄
            workbook = new HSSFWorkbook();
            // 生成一个表格
            Sheet sheet = workbook.createSheet(title);

            // 标题
            List<String> exportFieldTitle = new ArrayList<String>();
            List<Integer> exportFieldWidth = new ArrayList<Integer>();
            // 拿到所有列名,以及导出的字段的get方法
            List<Method> methodObj = new ArrayList<Method>();
            Map<String, Method> convertMethod = new HashMap<String, Method>();
            Class superClazz = null;
            Field fileds[] = new Field[0];
            boolean flag = true;
            while (flag) {
                if(superClazz != null){
                    superClazz = superClazz.getSuperclass();
                }else{
                    superClazz = pojoClass.getSuperclass();
                }
                if(superClazz.isInstance(Object.class)){
                    flag = false;
                }else{
                    Field[] sf = superClazz.getDeclaredFields();
                    if(sf != null && sf.length >0){
                        for(int m = 0;m<sf.length;m++){
                            fileds = ArrayUtils.addAll(fileds, sf[m]);
                        }
                    }
                }
                
            }
            // 得到所有字段
            Field cfileds[] = pojoClass.getDeclaredFields();
            if(cfileds != null && cfileds.length >0){
                for(int n = 0;n<cfileds.length;n++){
                    fileds = ArrayUtils.addAll(fileds, cfileds[n]);
                }
            }
            // 遍历整个filed
            int exportFieldCount = 0; // 要导出字段的数量
            if(exportFields != null && exportFields.size() > 0) {
                exportFieldCount = exportFields.size() ; 
            }
            for (int i = 0; i < fileds.length; i++) {
                Field field = fileds[i];
                Excel excel = field.getAnnotation(Excel.class);
                // 如果设置了annottion
                if (excel != null) {
                    if(exportFieldCount > 0) {
                        for(String eField: exportFields) {
                            if(eField.equals(excel.exportName())) {
                                addExportField(exportFieldTitle, exportFieldWidth, excel, field, methodObj, pojoClass, convertMethod);
                                exportFieldCount -=1;
                                LOG.debug("exportFieldCount  --- > " + exportFieldCount);
                                break;
                            }
                        }
                        if(exportFieldCount <= 0) {
                            LOG.debug("Break Field Loop!   ------------ !@!");
                            break;
                        }
                    } else {
                        addExportField(exportFieldTitle, exportFieldWidth, excel, field, methodObj, pojoClass, convertMethod);
                    }
                    
                }
            }
            int index = 0;
            // 产生表格标题行
            Row row = sheet.createRow(index);
            row.setHeight((short)450);
            CellStyle titleStyle = getTitleStyle(workbook);
            for (int i = 0, exportFieldTitleSize = exportFieldTitle.size(); i < exportFieldTitleSize; i++) {
                Cell cell = row.createCell(i);
                // cell.setCellStyle(style);
                RichTextString text = new HSSFRichTextString(exportFieldTitle
                        .get(i));
                cell.setCellValue(text);
                cell.setCellStyle(titleStyle);
            }

            // 设置每行的列宽
            for (int i = 0; i < exportFieldWidth.size(); i++) {
                // 256=65280/255
                sheet.setColumnWidth(i, 256 * exportFieldWidth.get(i));
            }
            Iterator its = dataSet.iterator();
            // 循环插入剩下的集合
            
            HSSFCellStyle oneStyle = getOneStyle(workbook);
            HSSFCellStyle twoStyle = getTwoStyle(workbook);
            while (its.hasNext()) {
                // 从第二行开始写,第一行是标题
                index++;
                row = sheet.createRow(index);
                row.setHeight((short)350);
                Object t = its.next();
                for (int k = 0, methodObjSize = methodObj.size(); k < methodObjSize; k++) {
                    Cell cell = row.createCell(k);
                    Method getMethod = methodObj.get(k);
                    Object value = null;
                    if (convertMethod.containsKey(getMethod.getName())) {
                        Method cm = convertMethod.get(getMethod.getName());
                        value = cm.invoke(t, new Object[] {});
                    } else {
                        value = getMethod.invoke(t, new Object[] {});
                    }
                    cell.setCellValue(value==null?"":value.toString());
                    
                    if(index%2==0)
                        cell.setCellStyle(twoStyle);
                    else
                        cell.setCellStyle(oneStyle);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return workbook;
    }
    
    private void addExportField(List<String> exportFieldTitle, List<Integer> exportFieldWidth, Excel excel, 
                            Field field, List<Method> methodObj, Class<T> pojoClass, Map<String, Method> convertMethod) throws Exception{
        // 添加到标题
        exportFieldTitle.add(excel.exportName());
        // 添加标题的列宽
        exportFieldWidth.add(excel.exportFieldWidth());
        // 添加到需要导出的字段的方法
        String fieldname = field.getName();
        // System.out.println(i+"列宽"+excel.exportName()+" "+excel.exportFieldWidth());
        StringBuffer getMethodName = new StringBuffer("get");
        getMethodName.append(fieldname.substring(0, 1)
                .toUpperCase());
        getMethodName.append(fieldname.substring(1));

        Method getMethod = pojoClass.getMethod(getMethodName
                .toString(), new Class[] {});

        methodObj.add(getMethod);
        if (excel.exportConvert() == true) {
            //----------------------------------------------------------------
            //update-begin--Author:Quainty  Date:20130524 for:[8]excel导出时间问题
            // 用get/setXxxxConvert方法名的话, 由于直接使用了数据库绑定的Entity对象,注入会有冲突
            StringBuffer getConvertMethodName = new StringBuffer("convertGet");
            getConvertMethodName.append(fieldname.substring(0, 1).toUpperCase());
            getConvertMethodName.append(fieldname.substring(1));
            //getConvertMethodName.append("Convert");
            //update-end--Author:Quainty  Date:20130524 for:[8]excel导出时间问题
            //----------------------------------------------------------------
            // System.out.println("convert: "+getConvertMethodName.toString());
            Method getConvertMethod = pojoClass
                    .getMethod(getConvertMethodName.toString(),
                            new Class[] {});
            convertMethod.put(getMethodName.toString(),
                    getConvertMethod);
        }
    }
    
    /**
     * 取得一个类添加了@Excel 注解的所有属性中 该注解中的exportName
     * @param pojoClass
     * @return
     */
    public  List<SystemBean> getExportFields(Class<T> pojoClass) {
        // 标题
        List<SystemBean> exportNames = new ArrayList<SystemBean>();
        Class superClazz = null;
        Field fileds[] = new Field[0];
        boolean flag = true;
        while (flag) {
            if(superClazz != null){
                superClazz = superClazz.getSuperclass();
            }else{
                superClazz = pojoClass.getSuperclass();
            }
            if(superClazz.isInstance(Object.class)){
                flag = false;
            }else{
                Field[] sf = superClazz.getDeclaredFields();
                if(sf != null && sf.length >0){
                    for(int m = 0;m<sf.length;m++){
                        fileds = ArrayUtils.addAll(fileds, sf[m]);
                        System.out.println(sf[m].getName());
                    }
                }
            }
            
        }
        // 得到所有字段
        Field cfileds[] = pojoClass.getDeclaredFields();
        if(cfileds != null && cfileds.length >0){
            for(int n = 0;n<cfileds.length;n++){
                fileds = ArrayUtils.addAll(fileds, cfileds[n]);
            }
        }
        // 遍历整个filed
        for (int i = 0; i < fileds.length; i++) {
            Field field = fileds[i];
            Excel excel = field.getAnnotation(Excel.class);
            // 如果设置了annottion
            if (excel != null) {
                SystemBean sb = new SystemBean();
                sb.setId(excel.exportName());
                sb.setName(excel.exportName());
                // 添加到标题
                exportNames.add(sb);
            }
        }
        return exportNames;
    }
        
        
    /**
     * 导出excel的样式
     * @param workbook
     * @return
     */
    public static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook){
        // 产生Excel表头
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        titleStyle.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);    //设置边框样式
        titleStyle.setBorderLeft((short)2);     //左边框
        titleStyle.setBorderRight((short)2);    //右边框
        titleStyle.setBorderTop((short)2);     //左边框
        titleStyle.setBorderBottom((short)2);    //右边框
        titleStyle.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);    //顶边框
        titleStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);    //填充的背景颜色
        titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        
        titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);    //填充图案
         
        return titleStyle;
    }
    
    public static HSSFCellStyle getTwoStyle(HSSFWorkbook workbook){
        // 产生Excel表头
        // 产生Excel表头
         HSSFCellStyle style = workbook.createCellStyle(); 
         style.setBorderLeft((short)1);     //左边框
         style.setBorderRight((short)1);    //右边框
         style.setBorderBottom((short)1);
         style.setBorderTop((short)1);
         style.setFillForegroundColor(HSSFColor.LIGHT_TURQUOISE.index);    //填充的背景颜色
         style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);    //填充图案
        return style;
    }
    
    public static HSSFCellStyle getOneStyle(HSSFWorkbook workbook){
        // 产生Excel表头
        // 产生Excel表头
         HSSFCellStyle style = workbook.createCellStyle(); 
         style.setBorderLeft((short)1);     //左边框
         style.setBorderRight((short)1);    //右边框
         style.setBorderBottom((short)1);
         style.setBorderTop((short)1); 
        return style;
    }
    
}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
3年前
vue iview 导入excel文件(upload)
<Uploadref"upload"action"/api/book/excel/import"name"excelfile":sho
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
PHP导入导出EXCELl,CSV
PHP导入导出Excel,CSVHTML<formaction"{:U('Admin/Unit/importcsv')}"method"post"name"myform"id"myform"enctype"multipart/formdata"<input
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这