java实现异步导出数据

问题概述:

使用java作为后台语言,用poi导出数据时无法异步导出,当数据量稍微大点,就会出现页面傻瓜式等待 (点击导出后,页面无任何反应和提示,还以为此功能无效。然则几秒后浏览器才响应。)这样体验非常 不好。

解决办法:

很简单,将下载数据分离为一个单独方法。在触发导出后,先获取并封装数据(数据量大的话这个过程正好给页面做一个等待框,提示正在下载数据),完成后给前台返回一个状态,当前台收到返回正确返回状态后再关闭等待框并调用下载方法。

demo:

1、获取并封装数据

@RequestMapping("exportExcel") //用户数据导出
 public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
 Map<String,Object> map = new HashMap<String,Object>();
 try{
  EquipmentAccident search=(EquipmentAccident)
  request.getSession().getAttribute("equipmentAccident1"); //获取保存在session中的查询条件
  if(search !=null ){
  if(Str.isNotNull(search.getName())){ //名称
  map.put("name", search.getName());
  }
  if(Str.isNotNull(search.getRemark())){ //备注
  map.put("remark", search.getRemark());
  }
  }

  List<User> list=userService.selectExcel(map); //查询数据

  XSSFWorkbook wb = new XSSFWorkbook(); // 声明一个工作薄
   XSSFSheet sheet = wb.createSheet("用户信息"); // 生成一个表格

   Integer columnIndex = 0;
   sheet.setColumnWidth(columnIndex++, 3 * 512); // 设置表格第一列宽度为3个字节
   sheet.setColumnWidth(columnIndex++, 10 * 512); //名称
   sheet.setColumnWidth(columnIndex++, 10 * 512); //年龄
   sheet.setColumnWidth(columnIndex++, 10 * 512); //备注

   // 生成一个样式
   XSSFCellStyle style1 = wb.createCellStyle();
   // 设置这些样式
   style1.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());

   // 生成一个字体
   XSSFFont font1 = wb.createFont();
   font1.setFontHeightInPoints((short) 11);
   font1.setFontName("黑体"); // 字体
   // 把字体应用到当前的样式
   style1.setFont(font1); 

   //在sheet里增加合并单元格
   CellRangeAddress cra = new CellRangeAddress(0, 0, 0, 7);
   sheet.addMergedRegion(cra);

   int rowInt = 0; //列号
   XSSFRow row = sheet.createRow(rowInt++);

   XSSFCell cell = row.createCell(0);
   cell.setCellStyle(style1);
   cell.setCellValue("用户信息");

   int cellInt = 0;
   row = sheet.createRow(rowInt++);

   cell = row.createCell(cellInt++);
   cell.setCellStyle(style1);
   cell.setCellValue("序号");

   cell = row.createCell(cellInt++);
   cell.setCellStyle(style1);
   cell.setCellValue("名称");

   cell = row.createCell(cellInt++);
   cell.setCellStyle(style1);
   cell.setCellValue("年龄");

   cell = row.createCell(cellInt++);
   cell.setCellStyle(style1);
   cell.setCellValue("备注");

   int index = 0;
   if(list!=null && !list.isEmpty()){
    for(User obj:list){
    index++;
    cellInt = 0;
     row = sheet.createRow(rowInt++);

     cell = row.createCell(cellInt++);
     cell.setCellValue(index);

     cell = row.createCell(cellInt++);
     cell.setCellValue(obj.getName());

     cell = row.createCell(cellInt++);
     cell.setCellValue(obj.getAge());

     cell = row.createCell(cellInt++);
     cell.setCellValue(obj.getRemark());
    }
   }
   //反馈给前台状态
  response.getWriter().append("ok");
  //XSSFWorkbook对象保持到session里,供下载使用
  request.getSession().setAttribute("XSSFWorkbook",wb);
 } catch (Exception e) {
  e.printStackTrace();
 }
}

2、分离出来的下载方法

 /**
 * @param fileName 下载文件名称
 * @param request 请求对象
 * @param response 响应对象
 * 2020-11-10 新增
*/
 @RequestMapping("downloadExcel")
 public void downloadExcel(String fileName,HttpServletRequest request,HttpServletResponse response) {
 if(Str.isNotNull(fileName)){
 User loginUser = (User) request.getSession().getAttribute("loginUser");
 //检验下载路径并返回url
 String url = FileTool.getdownLoadUrl(loginUser, fileName, request);
 //从url里截取出文件全名
 fileName = url.substring(url.lastIndexOf("/")+1);
 //创建文件输出流
 FileOutputStream fileOut = null;
 try {
  fileOut = new FileOutputStream(url);
  //获取保存在session中的待下载数据
  XSSFWorkbook wb = (XSSFWorkbook) request.getSession().getAttribute("XSSFWorkbook");
  wb.write(fileOut);
 } catch (FileNotFoundException e) {
  e.printStackTrace();
 }catch (IOException e) {
  e.printStackTrace();
 }

 finally{
    if(fileOut != null){
     try {
      fileOut.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
   } 

 try {
   System.out.println("------------开始下载文件---------------");
   File file = new File(url);
    // 以流的形式下载文件。
    InputStream fis = new BufferedInputStream(new FileInputStream(url));
    byte[] buffer = new byte[fis.available()];
    fis.read(buffer);
    fis.close();
    // 清空response
    response.reset();
    // 设置response的Header
    response.addHeader("Content-Disposition", "attachment;filename=" + new
    String(fileName.getBytes("UTF-8"),
    "ISO8859-1"));
    response.addHeader("Content-Length", "" + file.length());
    OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
    response.setContentType("application/octet-stream");
    toClient.write(buffer);
    toClient.flush();
    toClient.close();
    //清除session里的数据
    request.getSession().removeAttribute("XSSFWorkbook");
   } catch (IOException ex) {
    ex.printStackTrace();
   }
 }
}

3、前台调用导出数据

 //导出请求
 function exportExcel(){
 var load = saveLoad("导出中,请稍后...",1); //打开一个等待框
 $.ajax({
   type: "post",
   url: "exportExcel",
   dataType:"text",
   error: function(request) {
    closeSaveLoad(load,1);
    return false;
   },
   success: function(msg) {
    if(msg=='ok'){
    closeSaveLoad(load,1); //关闭等待框
    //下载请求地址
    window.location.href="downloadExcel?fileName=用户信息" rel="external nofollow" ;
    }else{
    closeSaveLoad(load,1); //关闭等待框
    layer.msg("导出失败,刷新页面重试",{icon:2});
    return false;
    }
   }
  });
 }

效果如下:

总结:

以前是将封装数据和下载数据放一个方法里面,导致下载需要等待很久,而等待的时候,无法提示用户后台正在处理数据。将数据和下载分开后就可以达到等待时提示,加载完下载。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java实现Excel导入导出数据库的方法示例

    本文实例讲述了Java实现Excel导入导出数据库的方法.分享给大家供大家参考,具体如下: 由于公司需求,想通过Excel导入数据添加到数据库中,而导入的Excel的字段是不固定的,使用得通过动态创建数据表,每个Excel对应一张数据表,怎么动态创建数据表,可以参考前面一篇<java使用JDBC动态创建数据表及SQL预处理的方法>. 下面主要讲讲怎么将Excel导入到数据库中,直接上代码:干货走起~~ ExcellToObjectUtil 类 主要功能是讲Excel中的数据导入到数据库中,有几

  • java从mysql导出数据的具体实例

    复制代码 代码如下: import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement; import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOExce

  • java导出数据库中Excel表格数据的方法

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

  • java导出数据库的全部表到excel

    本文实例为大家分享了java将某个数据库的表全部导出到excel中的方法,供大家参考,具体内容如下 第一步:如何用POI操作Excel @Test public void createXls() throws Exception{ //声明一个工作薄 HSSFWorkbook wb = new HSSFWorkbook(); //声明表 HSSFSheet sheet = wb.createSheet("第一个表"); //声明行 HSSFRow row = sheet.createR

  • java实现异步导出数据

    问题概述: 使用java作为后台语言,用poi导出数据时无法异步导出,当数据量稍微大点,就会出现页面傻瓜式等待 (点击导出后,页面无任何反应和提示,还以为此功能无效.然则几秒后浏览器才响应.)这样体验非常 不好. 解决办法: 很简单,将下载数据分离为一个单独方法.在触发导出后,先获取并封装数据(数据量大的话这个过程正好给页面做一个等待框,提示正在下载数据),完成后给前台返回一个状态,当前台收到返回正确返回状态后再关闭等待框并调用下载方法. demo: 1.获取并封装数据 @RequestMapp

  • 详解Java如何实现百万数据excel导出功能

    目录 前言 1.异步处理 1.1 使用job 1.2 使用mq 2.使用easyexcel 3.分页查询 4.多个sheet 5.计算limit的起始位置 6.文件上传到OSS 7.通过WebSocket推送通知 8.总条数可配置 9.order by商品编号 总结 前言 最近我做过一个MySQL百万级别数据的excel导出功能,已经正常上线使用了. 这个功能挺有意思的,里面需要注意的细节还真不少,现在拿出来跟大家分享一下,希望对你会有所帮助. 原始需求:用户在UI界面上点击全部导出按钮,就能导

  • Java使用POI导出大数据量Excel的方法

    今天需要写一个导出的Excel的功能,但是发现当数据量到3万条时,列数在23列时,内存溢出,CPU使用100%,测试环境直接炸掉.在本地测试时发现,导出3000条左右的数据的时候,堆内存瞬间升高500M左右.然后发现了 SXSSFWorkbook 这个类. 简介 SXSSFWorkbook 需要 poi-ooxml 包 3.8 及以上开始支持,我这边适使用的是 3.9 版本,本质是一个 XSSFWorkbook 类( Excel2007 ),它使用的方式是采用 硬盘空间 来大幅降低 堆内存 的占

  • Java使用easyExcel导出excel数据案例

    easyExcel简介: Java领域解析.生成Excel比较有名的框架有Apache poi.jxl等.但他们都存在一个严重的问题就是非常的耗内存.如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc. easyExcel是阿里巴巴开源的一个excel处理框架,以使用简单.节省内存著称. easyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理 easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据

  • Java实现批量导出导入数据及附件文件zip包

    目录 前言-应用场景 一.导出ZIP包 1. 列表数据导出到本地excel文件 2. 下载附件信息 3. 生成压缩文件(浏览器下载) 4. 删除临时目录 二.导入ZIP包 1. 上传zip包,解压到临时目录 2. 读取附件信息上传到文件服务器 3. 读取Excel文件存入数据库 4. 删除临时文件 前言-应用场景 某系统在不同单位使用时存在两套生产环境,他们的数据不是互通的,所以这些单位的上一级领导部门在统计数据的时候希望将A系统的数据和附件信息导出到一个压缩包里,然后把这个压缩包一键导入到B系

  • Java实现将导出带格式的Excel数据到Word表格

    在Word中制作报表时,我们经常需要将Excel中的数据复制粘贴到Word中,这样则可以直接在Word文档中查看数据而无需打开另一个Excel文件.但是如果表格比较长,内容就会存在一定程度的丢失,无法完整显示数据.并且当工作量到达一定程度时,整个过程会非常费时,降低工作效率.那么如何轻松地将带格式的 Excel 数据导出到 Word 表格呢?不用担心,本文将通过Java应用程序详细介绍如何把带格式的Excel数据导入Word表格.希望这篇文章能对大家有所帮助. 使用工具:Free Spire.O

  • java webApp异步上传图片实现代码

    如何实现java webApp异步上传图片,先了解以下几个问题: 1.图片上传: 2.图片上传预览: 3.上传图片更改地址异步添加到数据库: 主要内容 本示例主要采用纯HTML前端和JavaScript代码作工具,查询有关demo其实现图片上传的代码范例如下: (1)点击上传图片的div代码: <div id="div1" class="photo"> <input type="file" id="choose&quo

  • Java根据模板导出Excel报表并复制模板生成多个Sheet页

    因为最近用报表导出比较多,所有就提成了一个工具类,本工具类使用的场景为  根据提供的模板来导出Excel报表 并且可根据提供的模板Sheet页进行复制 从而实现多个Sheet页的需求, 使用本工具类时,如果需求是每个Sheet页中的数据都不一致,但是表格样式和模板都一样 那么只需要在实际情况中根据 sql 来查询要添加的数据源 (只需更改数据源即可) 采用的技术为 POI 导出,因为类的缘故,目前只支持2003版本的Excel. 使用前请先下载相应jar包! 后期有时间的话会进行进一步完善,初次

  • JSP实现从数据库导出数据到Excel下载的方法

    本文实例讲述了JSP实现从数据库导出数据到Excel下载的方法.分享给大家供大家参考,具体如下: 关键代码: <%@ page contentType="application/msexcel" %> <% //response.setHeader("Content-disposition","inline; filename=videos.xls"); response.setHeader("Content-disp

随机推荐