百万数据excel导出打包下载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012796085/article/details/82147037

前端框架easyUI,后端java,使用poi导出数据暂存到服务器,然后打包下载。
用于解决大数据一次性导出到一个excel内存溢出问题和请求超时504问题

1,前端请求js

$$.openProcessingDialog();  //打开等待动画
    $.ajax({
        type: "POST",dataType: "JSON",
        url:exportUrl,
        data: {search_condition:JSON.stringify(params)},
        success: function(data){
            $$.closeProcessingDialog();//关闭等待动画
            if(data.errorCode==0){
                //执行下载
                $(formSearchTemplate).form('submit', {
                    url : "/kywdop/actions/tool/download.do?actionId=tool_downloadFile",
                    onSubmit : function(param) {
                        param.FileName = data.msg;
                    }
                })
            }else{
                alert(data.msg);
            }
        }
    });

2,打包请求

与业务相关操作,数据是模拟的假数据,可以通过改变循环变量测试大数据的导出\
区分数据量导出不同格式数据,\
如果totnum<100w条,导出一个excel文件\
如果totnum>100w条,每10w条导出到一个excel,打成压缩包下载

@RequestMapping(value="/exportShiperrdtl")
    public CIPResponseMsg testExport(CIPReqParameter parameter,HttpServletRequest request,HttpServletResponse response){
        CIPResponseMsg res = new CIPResponseMsg();
        //模拟数据总数
        int totnum = 2200000;
        //每个excel最大行数
        int maxrow = 1000000;
        long start = System.currentTimeMillis();
        //页数,每页一个单独的excel文件
        int page = totnum%maxrow==0?totnum/maxrow:totnum/maxrow+1;
        /** 1.创建临时文件夹  */
        //String rootPath = request.getSession().getServletContext().getRealPath("/");
        String rootPath = "D:\\u02\\real_file\\kywdop\\";
        if(page>1){
            File temDir = new File(rootPath  + UUID.randomUUID().toString().replaceAll("-", ""));
            if(!temDir.exists()){
                temDir.mkdirs();
            }
            String filepath = temDir.getPath();

            /** 2.生成需要下载的文件,存放在临时文件夹内 */
            List<File> srcfile = new ArrayList<File>();
            //填充数据行
            for(int i=1;i<=page;i++){
                SXSSFWorkbook wb = new SXSSFWorkbook();
                //新建sheet页
                Sheet sheet = wb.createSheet();
                //设置表头
                Row row = sheet.createRow(0);
                CellStyle style = wb.createCellStyle();
                style.setAlignment(CellStyle.ALIGN_CENTER);

                Cell cell = row.createCell((short) 0);
                cell.setCellValue("姓名");
                cell.setCellStyle(style);
                cell = row.createCell((short) 1);
                cell.setCellValue("单位");
                cell.setCellStyle(style);
                cell = row.createCell((short) 2);
                cell.setCellValue("科室");
                cell.setCellStyle(style);
                cell = row.createCell((short) 3);
                cell.setCellValue("注册日期");
                cell.setCellStyle(style);
                //模拟数据
                for (int p = 1; p< maxrow; p++) {
                    row = sheet.createRow(p);
                    row.createCell((short) 0).setCellValue("大名"+p);
                    row.createCell((short) 1).setCellValue("单位"+p);
                    row.createCell((short) 2).setCellValue("科室"+p);
                    row.createCell((short) 3).setCellValue((new Date()).toString());
                }
                String fileName = "\\用户信息" + i+".xls";
                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream(filepath+fileName);
                    wb.write(fos);
                    fos.flush();
                    fos.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    res.msg="服务器错误";
                    res.errorCode=1;
                    return res;
                } catch (IOException e) {
                    e.printStackTrace();
                    res.msg="服务器错误";
                    res.errorCode=1;
                    return res;
                }
                srcfile.add(new File(filepath+fileName));
            }
            /** 3.调用工具类,生成zip压缩包 */
            String zipfilepath = rootPath+"excel.zip"; //压缩包文件路径
            try {
                FileOutputStream fos2 = new FileOutputStream(new File(zipfilepath));
                ZipUtils.toZip(srcfile, fos2);
            } catch (IOException e) {
                e.printStackTrace();
            }

            /** 4.删除临时文件和文件夹 */
            File[] listFiles = temDir.listFiles();
            for (int i = 0; i < listFiles.length; i++) {
                listFiles[i].delete();
            }
            temDir.delete();
            res.msg=zipfilepath;
        }else{
            SXSSFWorkbook wb = new SXSSFWorkbook();
            //新建sheet页
            Sheet sheet = wb.createSheet();
            //设置表头
            Row row = sheet.createRow(0);
            CellStyle style = wb.createCellStyle();
            style.setAlignment(CellStyle.ALIGN_CENTER);

            Cell cell = row.createCell((short) 0);
            cell.setCellValue("姓名");
            cell.setCellStyle(style);
            cell = row.createCell((short) 1);
            cell.setCellValue("单位");
            cell.setCellStyle(style);
            cell = row.createCell((short) 2);
            cell.setCellValue("科室");
            cell.setCellStyle(style);
            cell = row.createCell((short) 3);
            cell.setCellValue("注册日期");
            cell.setCellStyle(style);
            //模拟数据
            for (int p = 1; p< maxrow; p++) {
                row = sheet.createRow(p);
                row.createCell((short) 0).setCellValue("大名"+p);
                row.createCell((short) 1).setCellValue("单位"+p);
                row.createCell((short) 2).setCellValue("科室"+p);
                row.createCell((short) 3).setCellValue((new Date()).toString());
            }
            String fileName = "用户信息.xls";
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(rootPath+fileName);
                wb.write(fos);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                res.msg="服务器错误";
                res.errorCode=1;
                return res;
            } catch (IOException e) {
                e.printStackTrace();
                res.msg="服务器错误";
                res.errorCode=1;
                return res;
            }
            res.msg=rootPath+fileName;
        }
        long end = System.currentTimeMillis();
        log.info("导出耗时:"+(end-start)+" ms");
        res.errorCode=0;
        return res;
    }

这里写图片描述
百万数据每个excel导出多少条可以根据自己业务数据调试,每个excel导出越少,分的excel个数越多。

以上代码我替换为真实数据后的测试
性能测试
70w数据 每页10w –> 174977ms

70w数据 每页20w –> 154977ms

70w数据 每页30w –> 163430ms

70w数据 每页40w –> 141162ms

70w数据 每页50w –> 180974ms

3,下载通用controller

通用的文件下载只需要传入服务器的文件全路径即可下载,不区分文件是压缩包还是excel

/**
     * 文件下载
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value="/download")
    public void templateDownload(HttpServletRequest request, HttpServletResponse response) throws IOException{

        String path = request.getParameter("FileName");
        File file = new File(path);
        String fileName = StringUtils.substringAfterLast(path,"\\");
        if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {  //IE浏览器
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {  //非IE浏览器
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;fileName="+fileName);
        //输入流写入输出流
        InputStream inputStream = new FileInputStream(file);
        OutputStream ouputStream = response.getOutputStream();
        byte b[] = new byte[1024];
        int n ;
        //循环读取 !=-1读取完毕
        while((n = inputStream.read(b)) != -1){
            //写入到输出流 从0读取到n
            ouputStream.write(b,0,n);
        }
        //关闭流、释放资源
        ouputStream.close();
        inputStream.close();
    }

4,压缩文件工具类

下载地址

猜你喜欢

转载自blog.csdn.net/u012796085/article/details/82147037