poi导出数据到excel(支持大量数据导出)

简单记录一下导出几百万数据的过程,

 

导出的话可以,但是你要一次性查出百万数据估计肯定会内存溢出,所以处理查询的需要自己去写

我们的业务需求是,

要求查出一年的设备报警数据,一年大概是20-30亿条数据

所以我经过多次实验,感觉按月查比较快,筛选出一个月内达到要求的报警数据,差不多一次筛选出五六万条

用时10分钟左右。筛选出以后调用下面的方法。由于我筛选以后数据量并不大,最大的差不多也在20万一下,所以我

用一个sheet存一万条数据,当然也可以存十万。百万最好不好存,会卡。

 

核心工具类,用于导出数据的处理

new SXSSFWorkbook(1000); //大于1000行时会把之前的行写入硬盘,解决内存溢出

    private static Integer count = 0;//计数,看是否满足创建一个sheet的条件,因为一个sheet只能              存100万条
    private static Integer countRow = 0;

 /**
     * 导出excel
     * @param list				数据列表 List<E> 实体类列表
     * @param headers			列标题,以英文逗号分割,必传
     * @param includes		属性,以英文逗号分割,必传
     * @param filePath			导出文件全路径
     * @param sheetName			sheet名称:sheet1
     * @param dataPattern		日期格式:yyyy-MM-dd HH:mm:ss
     * @throws Exception		另一个程序正在使用此文件,进程无法访问
     */
    public static <E> void exportListEntity(List<E> list, String headers, String includes, String filePath, String sheetName, String dataPattern) throws Exception{
        count = 0;
        //工作簿
        Workbook wb;

        // 创建模板工作表
        if (filePath.endsWith(".xls")) {
            wb = new HSSFWorkbook();
        } else {
            //templatewb = new XSSFWorkbook(new FileInputStream(filePath));
            //wb = new XSSFWorkbook();
            wb = new SXSSFWorkbook(1000); //大于1000行时会把之前的行写入硬盘,解决内存溢出
        }

        String[] headerArr = headers.split(",");
        String[] sheetNames = sheetName.split(",");
        //String[] includeArr = includes.split(",");
        //List<String> includeList = Arrays.asList(includeArr);;

        //字体
        Font font = wb.createFont();
        //font.setFontHeightInPoints((short)14);
        //font.setColor(IndexedColors.DARK_BLUE.getIndex());
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);

        //样式
        CellStyle styleBOLD = createBorderedStyle(wb);
        styleBOLD.setFont(font);
        styleBOLD.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        styleBOLD.setWrapText(false); //自动换行

        //样式
        CellStyle styleWrap = createBorderedStyle(wb);
        styleWrap.setWrapText(false);
        styleWrap.setVerticalAlignment(CellStyle.VERTICAL_TOP);

        System.out.println("开始:"+new Date());
        Sheet sheet;
        for (int q = 0,num = sheetNames.length;q<num;q++){//循环sheet

            //表
            sheet = wb.createSheet(sheetNames[q]);
            //列宽
            //sheet.autoSizeColumn(( short ) 0 ); // 调整第一列宽度
            //sheet.SetColumnWidth(1, 50 * 256);  //设置列宽,50个字符宽度。宽度参数为1/256,故乘以256,中文的要再乘以2
//        sheet.setColumnWidth(0, 3000);
            countRow = 0;
            //行
            Row row = sheet.createRow(0);
            //单元格
            Cell cell;
            //写入标题行
            for(int i=0; i<headerArr.length; i++){
                cell = row.createCell(i);
                cell.setCellValue(headerArr[i]);
                cell.setCellStyle(styleBOLD);
            }

            //写入数据
            E e;			//实体类
            Field[] fields;	//属性数组
            Field field;	//属性
            Object value;	//属性值
            DateFormat dtf = new SimpleDateFormat(dataPattern); //yyyy-MM-dd HH:mm:ss
            rows:for(int i=count; i<list.size(); i++){


                row = sheet.createRow(countRow+1);
                countRow++;
                e = list.get(i);
                // 利用反射,获取属性数组
                fields = e.getClass().getDeclaredFields();
                for(int f=0,c=0; f<fields.length; f++){
                    field = fields[f];
                    //System.out.println(field.getName());
                    if(includes.contains(field.getName())){
                        cell = row.createCell(c);
                        cell.setCellStyle(styleWrap);
                        //cell.setCellType(Cell.CELL_TYPE_STRING);
                        //field.getName();
                        //field.getType();
                        field.setAccessible(true);	//设置些属性是可以访问的
                        value = field.get(e);		//得到此属性的值
                        //Byte,Short,Int,Long,Float,Double,Boolean,Char, String,Date,BigDecimal,byte[]
                        //cell.setCellValue: boolean,Calendar,Date,double,RichTextString,String
                        if(value==null){

                        } else if (value instanceof Date){
                            cell.setCellValue(dtf.format((Date)value));
                        } else {
                            cell.setCellValue(value.toString());
                        }
                        c++;
                    }
                }
                count++;
                //当满一万条数据新建一个sheet
                if(count%10000==0){
                    break rows;
                }
            }
        }


        //写入文件
        FileOutputStream fOut = new FileOutputStream(filePath);
        wb.write(fOut);
        //fOut.close();
        System.out.println("结束:"+new Date());

    }

 

方法的调用

public static void main(String[] args){

        List<outentity> outentities = new ArrayList<>();

        outentity outentity = new outentity();
        outentity.setId(1);
        outentity.setPassword("123");
        outentity.setUsername("123");
        outentity outentity2 = new outentity();
        outentity2.setId(2);
        outentity2.setPassword("123");
        outentity2.setUsername("123");
        outentity outentity3 = new outentity();
        outentity3.setId(3);
        outentity3.setPassword("123");
        outentity3.setUsername("123");

        outentity outentity4 = new outentity();
        outentity4.setId(4);
        outentity4.setPassword("123");
        outentity4.setUsername("123");
        outentity outentity5 = new outentity();
        outentity5.setId(5);
        outentity5.setPassword("123");
        outentity5.setUsername("123");
        outentity outentity6 = new outentity();
        outentity6.setId(6);
        outentity6.setPassword("123");
        outentity6.setUsername("123");

        outentities.add(outentity);
        outentities.add(outentity2);
        outentities.add(outentity3);
        outentities.add(outentity4);
        outentities.add(outentity5);
        outentities.add(outentity6);

        String ll = "private int com.poi.out.poiout.entity.outentity.id,private java.lang.String com.poi.out.poiout.entity.outentity.username,private java.lang.String com.poi.out.poiout.entity.outentity.password";

        try {
            exportListEntity(outentities,"id,username,password",ll,"D:\\excellogs\\test.xlsx","sheet1,sheet2,sheet3","yyyy-MM-dd HH:mm:ss");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

实体类

public class outentity {

    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

有不足的地方还请大佬告知。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值