java 导出Excel 大数据量

出处: http://lyjilu.iteye.com/

分析导出实现代码,XLSX支持:

/**
     * 生成<span style="white-space: normal; background-color: #ffffff;">XLSX</span>,2007版本的excel,每个sheet无6.5W的行数限制,但是到了一定数量,可能内存溢出,
     * 次方法适合在预计10W以下的数据导出时使用,本机测试,14W可以导出。列数量在8列左右
     *
     * @param fileOut
     *            输出流
     * @param sheetMap
     *            要设置的数据信息
     * @throws SQLException
     */
    public static void createXSLXByResultSet(OutputStream fileOut, WriteXLSBean... beans)
            throws SQLException {
        try {
            //重点 Workbook
            Workbook wb = new XSSFWorkbook();
            for (int i = 0, len = beans.length; i < len; i++) {
                WriteXLSBean xlsBean = beans[i];
                Sheet sheet = wb.createSheet(xlsBean.getSheetName());
                ResultSet rs = xlsBean.getRs();
                ResultSetMetaData rsmd = rs.getMetaData();
                TypeHandlerRegistry tr = BeanContext.tr;
                Map<String, String> th = xlsBean.getTh();
                int index = 0;
                while (rs.next()) {
                    long t1 = System.currentTimeMillis();
                    org.apache.poi.ss.usermodel.Row row = sheet
                            .createRow(index);
                    for (int j = 0, numberOfColumns = rsmd.getColumnCount(); j < numberOfColumns; j++) {
                        String key = rsmd.getColumnLabel(j + 1).toLowerCase();
                        if (th.containsKey(key)) {
                            TypeHandler<?> type = tr.getTypeHandler(JdbcType
                                    .forCode(rsmd.getColumnType(j + 1)));
                            Object obj = type.getResult(rs, key);
                            row.createCell(j).setCellValue(obj == null ? ""
                                    : obj.toString());
                        }
                    }
                    System.out.println(index + " :"
                            + (System.currentTimeMillis() - t1));
                    index++;
                }
            }
            //重点 Workbook
            wb.write(fileOut);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceRunTimeException("生产xls文档错误", e);
        } finally {

        }
    }

在上面 标注了重点的两处,分别是:

1.构建一个Excel对象

2.将该对象写入一个OutPutStream

而在构建过程中,没有地方写入OutPutSteam ,也就是说必须在内存中构建整个 Excel,才能进行写出操作,在大数据量情况下,这样将导致所有数据加载到内存中,而不能输出,导致最后 内存溢出。

根据运行环境不用,可能内存溢出的 情况不同

根据情况,如果数据量达到10W以上,建议使用

1、多个Excel,每个Excel一个Sheet,因为所有Sheet都是Workbook的组成部分。如果不分多个Excel,即使分Sheet也没用,

2、每个Excel中列数适中,比如: 5W行每个Excel档,实现分多次导出和分页查询原理一样

3、对多个Excel导出到一个临时目录,并通过程序压缩,然后提供给客户下载

2003版通过数据库结果存到List中,然后进行生产:Table 就是List Row 是Map

/**
     * 生产xls,2003版本的excel,每个sheet有6.5W的行数限制
     *
     * @param fileOut
     *            输出流,未关闭
     * @param sheetMap
     *            要导出的数据信息
     */
    public static void createXSLByMap(OutputStream fileOut, Map<String, Table<Row<String, Object>>> sheetMap) {
        try {
            HSSFWorkbook wb = new HSSFWorkbook();
            Set<String> keys = sheetMap.keySet();
            for (Iterator<String> iterator = keys.iterator(); iterator
                    .hasNext();) {
                String SheetKey = iterator.next();
                Sheet sheet = wb.createSheet(SheetKey);
                List<Row<String, Object>> sheetRows = sheetMap.get(SheetKey);
                for (int i = 0, len = sheetRows.size(); i < len; i++) {
                    Map<String, Object> cellMap = sheetRows.get(i);
                    Set<String> cellSet = cellMap.keySet();
                    org.apache.poi.ss.usermodel.Row row = sheet.createRow(i);
                    int j = 0;
                    for (Iterator<String> iterCell = cellSet.iterator(); iterCell
                            .hasNext(); j++) {
                        String cellKey = iterCell.next();
                        Object obj = cellMap.get(cellKey);
                        row.createCell(j).setCellValue(obj == null ? ""
                                : obj.toString());
                    }
                }
            }
            wb.write(fileOut);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceRunTimeException("生产xls文档错误", e);
        } finally {
        }
    }

新版本 POI+office 2007版本excel可以导出几十万条而不内存溢出,详细见:

导出大量数据到 excel 的 xlsx文件

static String src="abcdefafslfelgtryjukjhgfdadertjDSFGHJKJGHFERTUIOabcdefafslfelgtryjukjhgfdadertjDSFGHJKdertjDSFGHJKJGHFERTUIOabcdefafslfelgtryjukjhgfdadertjDSFGHJKJGHFERTUIO";
    public static void main(String[] args) throws Throwable {
        SXSSFWorkbook wb = new SXSSFWorkbook(100); // 这里100是在内存中的数量,如果大于此数量时,会写到硬盘,以避免在内存导致内存溢出
        Sheet sh = wb.createSheet();
        for (int rownum = 0; rownum < 1000000; rownum++) {
            Row row = sh.createRow(rownum);
            for (int cellnum = 0; cellnum < 10; cellnum++) {
                Cell cell = row.createCell(cellnum);
                String address = new CellReference(cell).formatAsString();
                cell.setCellValue(address+src.substring(rownum%10*10+1, (rownum%10+1)*10));
            }
        }
        File file = new File("F:/aa.xlsx");
        file.createNewFile();
        FileOutputStream out = new FileOutputStream(file);
        wb.write(out);
        out.close();
    }

内存使用情况:

时间: 2024-08-11 03:37:51

java 导出Excel 大数据量的相关文章

ASP.NET MVC导出excel(数据量大,非常耗时的,异步导出)

要在ASP.NET MVC站点上做excel导出功能,但是要导出的excel文件比较大,有几十M,所以导出比较费时,为了不影响对界面的其它操作,我就采用异步的方式,后台开辟一个线程将excel导出到指定目录,然后提供下载. 效果如下: 选中了多行,会导出多个工作簿sheet,一个汇总的,其他的就是明细数据. 这里我使用了NPOI组件来进行excel导出,下面是要几个封装好的类,从网上找的,然后修改了一下. GenerateSheet.cs using NPOI.SS.UserModel; usi

java 导出excel表格数据

本篇文章基于java把数据库中的数据以Excel的方式导出,欢迎各位大神吐槽: 1.基于maven jar包引入如下: 1 <dependency> 2 <groupId>net.sourceforge.jexcelapi</groupId> 3 <artifactId>jxl</artifactId> 4 <version>2.6.12</version> 5 </dependency> 2.首先创建数据库对

NPOI大数据量多个sheet导出源码(原)

#region  NPOI大数据量多个sheet导出 /// <summary>        /// 大数据量多个sheet导出        /// </summary>        /// <typeparam name="T">数据源实体类</typeparam>        /// <param name="objList">数据源</param>        /// <p

POI读写大数据量EXCEL

大数据量的excel一般都是.xlsx格式的,网上使用POI读写的例子比较多,但是很少提到读写非常大数据量的excel的例子,POI官网上提到XSSF有三种读写excel,POI地址:http://poi.apache.org/spreadsheet/index.html.官网的图片: 可以看到有三种模式: 1.eventmodel方式,基于事件驱动,SAX的方式解析excel(.xlsx是基于OOXML的),CPU和内存消耗非常低,但是只能读不能写 2.usermodel,就是我们一般使用的方

Java读取操作大数据excel

工作需要,读取大数据量的excel.用Apache poi的普通模式读取,会抛内存溢出.查询文档得知有另外一种模式--用户模式.该模式不会一下子整个文件load进来放在内存里,而是一行一行的读取,这样就能避免内存溢出了. 上码: package com.ism.excel.pkg07; import java.io.InputStream; import java.sql.SQLException; import java.util.ArrayList; import java.util.Ite

导出查询数据(大数据量)

1.右击数据库,"任务"--"导出数据" 2.向导页点击"下一步",然后录入登陆信息,再点击"下一步" 3.选择导出类型及路径,然后点击"下一步"(如:Excel文档) 4.选择数据源,直接从表或试图中导出,或者通过sql语句查询导出,然后"下一步".(此处sql查询为例) 5.录入查询语句,然后"下一步"(可分析sql语句是否有效) 6.之后的步骤就是一路"

POI读写大数据量excel,解决超过几万行而导致内存溢出的问题

1. Excel2003与Excel2007 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是256列,2007版及以后的版本最大行数是1048576行,最大列数是16384列. excel2003是以二进制的方式存储,这种格式不易被其他软件读取使用:而excel2007采用了基于XML的ooxml开放文档标准,ooxml使用XML和ZIP技术结合进行文件存储,XML是一个基于文本的格式,而且ZIP容器支持内容的压缩,所以其一大优势是可以大大减小文件的尺寸. 2. 大批

一个坑poi大数据量导入时的java.lang.IllegalStateException: Zip File is closed

本帖子没有答案,只是说一下坑,余下的自己决定. Caused by: java.lang.IllegalStateException: Zip File is closed at org.apache.poi3.openxml4j.util.ZipFileZipEntrySource.getEntries(ZipFileZipEntrySource.java:45) at org.apache.poi3.openxml4j.opc.ZipPackage.getPartsImpl(ZipPacka

大数据量查询优化——数据库设计、SQL语句、JAVA编码

数据库设计方面: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描.             如: select id from t where num is null              可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0 3