poi导出excel数据量过大

问题:使用poi导出excel,数据量过大导致内存溢出

解决思路:1、多sheet导出

     2、生成多个excel打包下载

     3、生成csv下载

本文使用的是第二个思路,代码如下:

poiUtil工具类

package com.rratchet.scala.ms.util;

import org.apache.poi.hssf.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * poi 公用方法
 */
public class PoiUtil {


    /**
     * 导出excel
     * @param sheetName
     * @param title
     * @param values
     * @param response
     * @param fileName
     * @param charsetName
     */
    public static void exportExcel(String sheetName, String []title, String [][]values,  HttpServletResponse response, String fileName,String charsetName){

        // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
        HSSFWorkbook wb= new HSSFWorkbook();
        createContent( wb,sheetName,title,values);
        //响应到客户端
        try {
            fileName = new String(fileName.getBytes(charsetName),"ISO8859-1");
            response.setContentType("application/octet-stream;charset="+charsetName);
            response.setHeader("Content-Disposition", "attachment;filename="+  fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            OutputStream os = response.getOutputStream();
            wb.write(os);
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
          }

    }

    /**
     * 创建excel
     * @param sheetName sheet名
     * @param title 标题
     * @param values 内容
     * @param fileName 文件名
     * @param filePath 文件地址
     * @return excel保存路径
     * @throws Exception
     */
    public static String createExcel(String sheetName, String []title, String [][]values,String fileName,String filePath){
       String resultPath=filePath+"/"+fileName;
        // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
        HSSFWorkbook wb= new HSSFWorkbook();
        createContent( wb,sheetName,title,values);
        //判断是否存在目录. 不存在则创建
        isChartPathExist(filePath);
        //创建Excel文件
        isFileExist(filePath+"/"+fileName);
        try{
            FileOutputStream output=new FileOutputStream(filePath+"/"+fileName);
            wb.write(output);//写入磁盘
            output.close();
        }catch (Exception e){
            resultPath="";
            e.printStackTrace();
        }
        return resultPath;
    }

    /**
     * 创建excel内容
     * @param wb
     * @param sheetName
     * @param title
     * @param values
     */
    private static void createContent(HSSFWorkbook wb, String sheetName, String []title, String [][]values){
        // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet(sheetName);
        // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
        HSSFRow row = sheet.createRow(0);
        // 第四步,创建单元格,并设置值表头 设置表头居中
        HSSFCellStyle style = wb.createCellStyle();
        // 创建一个居中格式
        style.setAlignment(HorizontalAlignment.CENTER);
        //声明列对象
        HSSFCell cell = null;
        //创建标题
        for(int i=0;i<title.length;i++){
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }

        //创建内容
        for(int i=0;i<values.length;i++){
            row = sheet.createRow(i + 1);
            for(int j=0;j<values[i].length;j++){
                //将内容按顺序赋给对应的列对象
                row.createCell(j).setCellValue(values[i][j]);
            }
        }
    }

    /**
     * 判断文件夹是否存在,如果不存在则新建
     *
     * @param dirPath 文件夹路径
     */
    private static void isChartPathExist(String dirPath) {
        File file = new File(dirPath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    /**
     * 判断文件是否存在,不存在则创建文件
     * @param dirPath
     */
    public static void isFileExist(String dirPath){
        File file = new File(dirPath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

fileUtil工具类

    /**
     * 压缩文件(zip)
     * @param srcFiles
     * @param zippath
     * @throws Exception
     */
    public static void Zip(List<File> srcFiles , String zippath)throws Exception {
        File file=new File(zippath);
        if(!file.exists()){
            file.createNewFile();
        }
        FileOutputStream out = new FileOutputStream(file);
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[4096 * 1024];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成,耗时:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     *获取路径下所有文件(递归遍历)
     * @param fileList
     * @param path
     * @throws Exception
     */
    public static void getFiles(List<File>fileList, String path){
        try {
            File file = new File(path);
            if(file.isDirectory()){
                File []files = file.listFiles();
                for(File fileIndex:files){
                    //如果这个文件是目录,则进行递归搜索
                    if(fileIndex.isDirectory()){
                        getFiles(fileList,fileIndex.getPath());
                    }else {
                        //如果文件是普通文件,则将文件句柄放入集合中
                        fileList.add(fileIndex);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

测试方法

    public static void main(String[] args) throws IOException {
        String filePath="D:/home/"+UUID.randomUUID().toString();
        String[] titles = {"上传时间", "连接时间"};
        for(int i=0;i<5;i++){
            String time = DateUtil.getDateyyyymmddFormat(new Date());
            //excel文件名
            String fileName = "连接记录_" + i + ".xls";
            //sheet名
            String sheetName = time;
            String[][] content = new String[20][2];
            for (int j = 0; j < 20; j++) {
                content[j][0] = "20190-05-29"+"_"+j;
                content[j][1] = "s"+j;

            }
            PoiUtil.createExcel(sheetName,titles, content, fileName, filePath);
        }
        List<File> list=new ArrayList<>();
        //递归获取文件夹下所有内容
        FileUtils.getFiles(list,filePath);
        try {
            FileUtils.Zip(list,"D:/home/测试.zip");
            //删除生成的excel
            FileUtils.deleteFolderAndFile(filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

 

 



posted @ 2019-05-27 14:11  不列颠剑圣  阅读(6434)  评论(3编辑  收藏  举报