百万Excel的数据导出

1.使用 poi提供的  SXSSFWorkbook对象 

    基于XSSFWork导出Excel报表,是通过将所有单元格对象保存到内存中,当所有的Excel单元格全部创建完成之后

  一次性写入到Excel并导出。当百万数据级别的Excel导出时,随着表格的不断创建,内存中对象越来越多,直至内
  存溢出。Apache Poi提供了SXSSFWork对象,专门用于处理大数据量Excel报表导出。

2 原理

    在实例化SXSSFWork这个对象时,可以指定在内存中所产生的POI导出相关对象的数量(默认100),一旦内存中
  的对象的个数达到这个指定值时,就将内存中的这些对象的内容写入到磁盘中(XML的文件格式),就可以将这些
  对象从内存中销毁,以后只要达到这个值,就会以类似的处理方式处理,直至Excel导出完成。

3 代码实现

  在原有代码的基础上替换之前的XSSFWorkbook,使用SXSSFWorkbook完成创建过程即可
  
 /**
     * Excel 报表导出
     * SXSSFWorkbook 导出 支持百万导出的 工作簿 类
     * 不支持模板打印
     */
    @GetMapping("sXSSFExport")
    public void  sXSSFExport(HttpServletResponse response) throws IOException {
        //1.创建workbook工作簿   1000 阈值 也就是每1000 行就服务器的硬盘上存一次,默认 100
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);
        //2.创建表单Sheet
        Sheet sheet = wb.createSheet("百万导出");
        String[] title="序号,名字,密码".split(","); //怎么创建数组都行
        //3.创建行对象,从0开始 ,创建标题
        Row row = sheet.createRow(0);
        //4.创建单元格,从0开始
        Cell cell = null;
        //标题
        /**   标题的第二种实现
         *    for (int i = 0; i < title.length; i++) {
         *             //4.创建单元格,从0开始
         *             row.createCell(i);
         *             //5.单元格写入数据
         *             cell.setCellValue(title[i]);
         *         }
         */
        int indexTitle=0;
        for (String s : title) {
            //4.创建单元格,从0开始
            cell = row.createCell(indexTitle++);
            //5.单元格写入数据
            cell.setCellValue(s);
        }

        //人为构造的数据,实际是要从数据库中查的
        List<User> users=new ArrayList<>();
        User user= new User();
        for (int i = 0; i <1 ; i++) {
            user.setName("洪真英");
            user.setPassword(123456);
            users.add(user);
        }

        int indexContext=1;
        int index=1;
        //内容
        for (int j=0;j<1048575;j++) {
            for (User user1 : users) {
                //创建每一行,同excel的第二行开始
                row = sheet.createRow(indexContext++);
                //第一列
                cell = row.createCell(0);
                //写入数据 序号
                cell.setCellValue(index++);
                //第2列
                cell = row.createCell(1);
                cell.setCellValue(user1.getName());
                //第2列
                cell = row.createCell(2);
                cell.setCellValue(user1.getPassword());
            }
        }
        ByteArrayOutputStream os=new ByteArrayOutputStream();
        wb.write(os);
        new DownloadUtils().download(os,response,"百万数据导出.xlsx");

    }
View Code

4.下载工具

package com.zhao.common.util;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * 用于 Excel下载的工具类
 */
public class DownloadUtils {
    /**
     *
     * @param byteArrayOutputStream 输出字节流
     * @param response
     * @param returnName 输出到客户端的文件名
     * @throws IOException
     */
    public   void download(ByteArrayOutputStream byteArrayOutputStream, HttpServletResponse response, String returnName) throws IOException {
        response.setContentType("application/octet-stream");
        returnName = response.encodeURL(new String(returnName.getBytes(),"iso8859-1"));            //保存的文件名,必须和页面编码一致,否则乱码
//        response.addHeader("Content-Disposition","attachment;filename=total.xls");
        response.addHeader("Content-Disposition","attachment;filename="+returnName);
        response.setContentLength(byteArrayOutputStream.size());
        response.addHeader("Content-Length", "" + byteArrayOutputStream.size());
        ServletOutputStream outputStream = response.getOutputStream();    //取得输出流
        byteArrayOutputStream.writeTo(outputStream);                    //写到输出流
        byteArrayOutputStream.close();                                    //关闭
        outputStream.flush();                                            //刷数据
    }
}
View Code

 如果是windows系统 SXSSFWorkbook产生的临时xml文件保存在 %temp% 中 只需要 win+r 键 在输入框中输入  %temp% 即可

posted @ 2020-02-01 19:59  Angry-rookie  阅读(607)  评论(0)    收藏  举报