Java导出大量数据到Excel解决方案

常见的场景优化方案:导出Excel大批量数据的优化过程 团队目前在做一个用户数据看板(下面简称看板),基本覆盖用户的所有行为数据,并生成分析报表,用户行为由多个数据来源组成(餐饮、生活日用、充值消费、交通出行、通讯物流、交通出行、医疗保健、住房物业、运动健康...),看看标红的代码,这个生成Excel的方式是对Excel中的每一个cell进行渲染,逐行的进行数据填充,效率太慢了,根据日志分析发现:基本时间都耗费在数据生成Excel上。目前遇到的主要问题是,随着行为能力逐渐的完善闭环,用户数据沉淀的也越来越多了,同时业务量的也在不断扩大。 阅读详情

ResultHandler流式查询导出Excel数据

// 导出Excel头部名称
List<String> headerArray = Arrays.asList("编码","姓名");
// 数据库对应字段
List<String> fieldArray = Arrays.asList("id", "name");
// 定义Excel文件名,不带“xlsx”后缀。
String fileName = getToday()+"导出数据-共计("+count+")"+"条";
//每次导出New 一个 handler 对象。将headerArray,fieldArray,fileName 传入参数。
ExcelResultHandler<查询对象> handler = new ExcelResultHandler<查询对象>(headerArray,fieldArray,fileName) {
            public void tryFetchDataAndWriteToExcel() {
                // this 指的是 New 对象,可添加查询 条件参数。
        		// mapper的方法需要是void返回,并且参数中含ResultHandler(流式查询遍历的条件),可以加条件参数,
                // fetchSize参数必填。
                //见下图
                //<select id="export" parameterType="" resultType="" fetchSize="-2147483648">
                ***Mapper.export(this);
            }
        };
//开始调用方法。原理:调用开始后,表头写入Excel,遍历结果集,一条一条数据写入Excel,最后关闭资源。
handler.startExportExcel();

源码会判断方法返回值是否void,是否含有ResultHandler
在这里插入图片描述

ExcelResultHandler工具类:

按需修改

public abstract class ExcelResultHandler<T> implements ResultHandler<T>{
   
   private final Logger logger = LoggerFactory.getLogger(this.getClass());
   private AtomicInteger currentRowNumber = new AtomicInteger(0);
   private Sheet sheet = null;
   private List<String> headerArray ;
   private List<String> fieldArray ;
   private int totalCellNumber;
   private boolean isExportZip = true;
   private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   private String exportFileName = UUID.randomUUID().toString().replace("-", "");
   public ExcelResultHandler(List<String> headerArray,List<String> fieldArray){
      this.headerArray = headerArray;
      this.fieldArray = fieldArray;
      this.totalCellNumber = headerArray.size();
   }
   public ExcelResultHandler(List<String> headerArray,List<String> fieldArray,boolean isExportZip){
      this(headerArray,fieldArray);
      this.isExportZip = isExportZip;

   }
   public ExcelResultHandler(List<String> headerArray,List<String> fieldArray,String exportFileName){
      this(headerArray,fieldArray);
      this.exportFileName = exportFileName;
   }
   public ExcelResultHandler(List<String> headerArray,List<String> fieldArray,String exportFileName,boolean isExportZip){
      this(headerArray,fieldArray,exportFileName);
      this.isExportZip = isExportZip;
   }
   public abstract void tryFetchDataAndWriteToExcel();
   public void handleResult(ResultContext<? extends T> resultContext) {
      Object aRowData = resultContext.getResultObject();
      callBackWriteRowdataToExcel(aRowData);
      
   }
   public void startExportExcel() {
      HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
      ZipOutputStream zos = null;
      OutputStream os = null;
      try {
         logger.info("--------->>>>写入Excel开始.." );
         //写入文件
         response.setContentType("application/octet-stream");
         response.setHeader("Content-Disposition", "attachment;filename=" + new String((exportFileName+".zip").replaceAll(" ", "").getBytes("utf-8"),"iso8859-1"));
         os = new BufferedOutputStream(response.getOutputStream());
         if(isExportZip){
            zos = new ZipOutputStream(os);
            ZipEntry zipEntry = new ZipEntry(new String((exportFileName+".xlsx").replaceAll(" ", "")));
            zos.putNextEntry(zipEntry);
         }
         SXSSFWorkbook wb = new SXSSFWorkbook();
         wb.setCompressTempFiles(false);
            sheet = wb.createSheet("Sheet 1");
           Row row = sheet.createRow(0);
           for (int cellNumber = 0; cellNumber < totalCellNumber; cellNumber++) {
              Cell cell = row.createCell(cellNumber);
                cell.setCellValue(headerArray.get(cellNumber));
           }
           tryFetchDataAndWriteToExcel();
         logger.info("--------->>>> write to excel size now is {}", currentRowNumber.get() );
         if(isExportZip){
            wb.write(zos);
         }else{
            wb.write(os);
         }
           if (wb != null) {
               wb.dispose();// 删除临时文件,很重要,否则磁盘可能会被写满
            }
           wb.close();
         logger.info("--------->>>>全部数据写入Excel完成.." );
      } catch (Exception e) {
         logger.error("系统异常,请联系管理员",e);
      } finally {
         logger.info("--------->>>>关闭流系统.." );
         if(isExportZip){
            try {if(zos!=null) zos.close();} catch (IOException e1) {logger.error("关闭流系统异常,请联系管理员",e1);    }
         }else{
            try {if(os!=null) os.close();} catch (IOException e1) {logger.error("关闭流系统异常,请联系管理员",e1);  }
         }
            
      }
   }
   @SuppressWarnings("rawtypes")
   public void callBackWriteRowdataToExcel(Object aRowData) {
      MethodAccessor methodAccessor = Reflector.getMethodAccessor(aRowData.getClass());
      currentRowNumber.incrementAndGet();
      Row row = sheet.createRow(currentRowNumber.get());
      for (int cellNumber = 0; cellNumber < totalCellNumber; cellNumber++) {
         Object value = null;
         if(aRowData instanceof Map){
            value = ((Map)aRowData).get(fieldArray.get(cellNumber));
         }else {
            value = methodAccessor.getFieldValue(aRowData, fieldArray.get(cellNumber));
         }
         Cell cell = row.createCell(cellNumber);
            if (value!=null && value instanceof Date){
               cell.setCellValue(sdf.format(value));//
            }else {
               cell.setCellValue(value==null?"":value.toString());//写入数据
            }
      }
      if(currentRowNumber.get() % 5000 == 0 ){
         logger.info("--------->>>> write to excel size now is {}", currentRowNumber.get() );
      }
   }

}

因为无返回值,前端如何知道是否下载完成?

前端用下载监听器。

var index = layer.load(3, {
    shade: [0.1, '#fff'],
    content: '<span class="loadtip">下载中</span>',
    success: function (layer) {
        layer.find('.layui-layer-content').css({
            'padding-top': '30px',
            'width': '100px',
        });
        layer.find('.loadtip').css({
            'font-size':'18px',
            'margin-left':'5px'
        });
    }
});
const xhr = new XMLHttpRequest();
xhr.open('GET', '下载接口');
xhr.send(null);
// 设置服务端的响应类型
xhr.responseType = "blob";
// 监听下载
xhr.addEventListener('progress', event => {
    // 计算出百分比
    const percent  = ((event.loaded / event.total) * 100).toFixed(2);
    console.log(`下载进度:${percent}`);
}, false);
xhr.onreadystatechange = event => {
    if (xhr.readyState == 4) {
        if (xhr.status == 200) {
            // 获取ContentType
            const contentType = xhr.getResponseHeader('Content-Type');
            // 文件名称 如果想和后端一样,需要处理编码
            const fileName = "名称.zip";
            // 创建一个a标签用于下载
            const donwLoadLink = document.createElement('a');
            donwLoadLink.download = fileName;
            donwLoadLink.href = URL.createObjectURL(xhr.response);
            // 触发下载事件,IO到磁盘
            donwLoadLink.click();
            // 释放内存中的资源
            URL.revokeObjectURL(donwLoadLink.href);
            // 关闭加载动画
            layer.close(index);
        } else if (response.status == 404) {
            alert(`文件:${file} 不存在`);
        } else if (response.status == 500) {
            alert('系统异常');
        }
    }
}

java实战:实现百万级数据导出 本文将介绍如何使用Java实现百万级数据导出,同时考虑内存、CPU等性能指标。我们将探讨数据导出的基本流程,并展示一个简单的Java代码示例,该示例使用JDBC和数据库连接池来高效地处理大规模数据导出,并采用分页查询和资源管理等策略来优化性能。通过本文,可以了解到如何在Java应用程序中实现高效的数据导出,并确保系统资源的合理使用。 阅读详情

相关推荐

Java百万级别数据Excel导出

在项目开发中往往需要使用到数据的导入和导出,导入就是从Excel中导入到DB中,而导出就是从DB中查询数据然后使用POI写到Excel上。

逸轩 1379

JAVA大量数据导出excel

背景:因项目需要导出3万行+,90列+的数据到excel,使用传统的apache poi 直接导出,导致504连接超时无法导出。然后改造方法,异步导出。

caijigskg的博客 3734

Java·Excel导出百万级数据

Java·Excel导出百万级数据POI依赖介绍CSV格式介绍JXL依赖介绍使用依赖上下文配置Excel2003格式导出Excel2007格式CSV文本格式使用JXL依赖导出Excel POI依赖介绍 excel对行列的限制 | excel2003 | 65536 | 256| | excel2007 | 1048576 | 16384 | 1. Excel2003格式(java对象使用HSSFWorkbook) Excel2003支持每个工作表中最多有 65536 行和 256列。对于工作表能够支持的最大

qq_43308318的博客 6013

java实现百万级别数据导出excel(JPA,hibernate,mybatis三种方式)

java实现百万级别数据导出excel,提供了JPA,hibernate,mybatis三种不同的方式来实现

hgq0916的博客 1万+

Stm32L0 STM32CUBE中UART和使用LPUART1以及串口不进中断问题解决

/* 开启串口1中断 */ LL_USART_EnableIT_RXNE(LPUART1); /* 开启串口2中断 */ LL_USART_EnableIT_RXNE(USART2);

シ❤゛甜虾的个人博客 7687

SGLang HiCache实战:手把手教你配置KV Cache Offload,让大模型推理成本直降84%

本文详细介绍了SGLang HiCache在KV Cache Offload配置与调优中的实战应用,通过多级存储架构和智能卸载策略,显著降低大模型推理成本达84%。文章涵盖HiCache架构优势、环境配置、高级调优策略及生产环境最佳实践,帮助开发者优化GPU显存使用,提升并发处理能力。

weixin_29044713的博客 463

POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)...

说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M 我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出。由于Excel 一个sheet允许的最大行数是65536这时我们想到分sheet进行导出;但是这种情况也不能解决内存溢出的问题。毕竟数据还是一次性在内存中进行保存的。这时我们想是不是可以导出多个excel...

aa18038600931的博客 257

智能汽车域控制器FOTA升级方案探讨

上文提到的Entry属性,包括Active 属性, Bootable 属性, Successful 属性, Retrycnt 属性 ,Active 属性用于标志槽的优先级,bootloader优先选择Active 属性=1的槽启动,Bootable 属性标志槽可否可启动,Successful 属性标志槽是否成功启动过,Retrycnt 属性标志槽可尝试启动的次数。芯片启动后,首先进入Bootloader阶段,此阶段将读取存储系统的分区属性,根据属性值进行逻辑判断,并确定进入哪个分区,详见流程图。

huibian1234的博客 1570

eye alpha java_POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)...

说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出。由于Excel 一个sheet允许的最大行数是65536这时我们想到分sheet进行导出;但是这种情况也不能解决内存溢出的问题。毕竟数据还是一次性在内存中进行保存的。这时我们想是不是可以导出多个excel呢?下面我就尝...

weixin_28730549的博客 131

计算机组成原理实验:手把手教你用模拟程序实现中断机制(附完整代码)

本文通过一个计算机组成原理模拟实验,手把手教你从零实现一个可工作的中断系统。实验详细演示了如何配置中断控制器、编写主程序与中断服务程序,并观察中断响应、现场保护和恢复的全过程,深入解析了中断原理的核心机制。

473

安装anaconda3时出现错误:Failed to link extracted packages to D:\anaconda!...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1483

java中poi导出excel问题总结

java中poi导出excel问题总结

weixin_49897607的博客 5973

全志A527 T527 android13支持usb摄像头

我们发现usb摄像头在A527 android13上面并不能正常使用,需要支持相关的摄像头。

zhutoubenben的专栏 964

Java POI导出百万级别Excel数据的工具类

为了更方便快捷地实现Excel导出数据,之前利用Kendo UI地Excel导出grid数据,非常方便快捷,但是却发现无法导出大量数据,所以需要导出百万级别地数据时只能后台java代码实现。通过查询资料得知,java导出excel的一般使用jxl或POI来实现,但jxl已经不更新,且无法支持Excel 2007版本(sheet的最大行数是1048576),现在一般使用POI导出。网上有很多关于使用...

qq_28830129的博客 749

【系统架构设计师】2026年上半年真题论文:论高并发系统的设计与实践

本文围绕高并发系统架构设计展开,重点论述了电商秒杀系统的实战经验。文章采用"痛点-解决方案-效果"的逻辑结构,从缓存设计、异步处理、限流降级、数据库优化等6个维度详细阐述了应对高并发的技术策略。其中,重点介绍了多级缓存体系、基于消息队列的异步处理机制和微服务拆分实践,并辅以实际案例说明如何解决超卖、缓存雪崩等典型问题。全文强调高并发设计需要系统性思维,通过空间换时间、异步换吞吐、横向换能力等原则,最终实现系统吞吐量从500TPS提升至20000TPS的性能突破。

数据知道的博客 1160

SwinTransformer 改进:SSPCAB模块(2024最新改进方法)

SSPCAB(Spatial Pyramid Pooling with Channel Attention Block)是2024年提出的一种新型神经网络架构改进方法,专注于在保持高精度的同时显著降低计算复杂度和参数量。该方法通过创新的空间金字塔池化与通道注意力机制的结合,实现了网络结构的紧凑化和运算效率的大幅提升。核心创新点1. 混合空间金字塔池化(Hybrid Spatial Pyramid Pooling, HSPP)多尺度动态核池化:根据输入特征图尺寸动态调整池化核大小和步长交叉级联结构。

Henry的博客 1312

【代码】10W+ 数据导出excel,根据表头动态导出单个excel,多个excel到处压缩包

【代码】10W+ 数据导出excel,根据表头动态导出单个excel,多个excel到处压缩包

迷茫,是因为才华配不上梦想... 202

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

大量数据生成excel时候造成jvm内存泄漏问题的解决与测 (转)

一、从数据库中取大量数据(10万行左右)的时候,用jxl工具写excel,由于jxl是将每一个单元格生都成一个Cell对象,每一个对象都要消耗一定的内存空间,所以很容易导致内存溢出: sheet0.addCell(new Label(colnum++,rownum,rs.getString("aname"),stuformat))// tomcat报异常为: java.la...

frank1998819 451

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

java 分批导出_Java poi Excel导出文件,Java poi 分批次导出大批量数据

================================©Copyright蕃薯耀 2020-01-07一、问题描述:1、当使用WorkbookFactory.create 创建Excel时,其实创建的文档为Excel2003版的,最大容纳65536行数据,超出这个行数就是发生溢出。WorkbookFactory.create(...);2、当数据量大时,直接从数据库查询出来,内存不够也...

weixin_36297610的博客 782

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Java poi Excel导出文件,Java poi 分批次导出大批量数据

蕃薯耀的博客 4464

导出excel功能(解决大数据量问题)

  目前我们做的系统,导出excel功能都存在一个问题,如果数据量一大(比如上万条以上的记录),如果用传统的方式导出excel速度都很慢,甚至最终导致内存益出,最终死机;(请大伙最好都确认一下各自负责的系统存在的问题) 例如:三明移动公司的积分系统,因需求所需,客户如果要导出20多万条记录的话,系统速度都很慢,最终导致内存益出死机;原本以为是频繁把数据放在集合的原因,可是我又有分页觉得不是主要原...

进击30K的专栏 1万+

Poi导入导出百万Excel java

前言 项目中做报表,导入导出Excel,是常见也是不可或缺的功能,本文讲解导入多 Excel的写法,以及导出百万的优化方案 图解代码思路 导出多Excel工具类 package com.XXX.XXX.utils; import.XXX.ExportExcelBase; import lombok.extern.slf4j.Slf4j; import org.apache.poi.xssf.usermodel.*; import org.springframework.core.env

WindwirdBird的博客 683

mysql只能导出65535条_导出Excel超过65535条限制解决方案

使用poi导出excel的时候如果数据过多,超过65535条会报错,因为excel2003一个sheet表最多导出65535条,excel2007是10万4000多条限制。因此遇到这种excel导出数据量比较大的时候,可以考虑如果数量超过一定数量,比如50000或者60000,新建一个sheet重新插入数据。实例代码://创建HSSFWorkbook对象(excel的文档对象)HSSFWorkbo...

weixin_39850152的博客 3567

前端传大量数据到后台进行导出

各位小伙伴有没有遇到过这种需求,前端有大量的数据需要传到后台,在将这些数据导出成excel。 常用的导出都是前端通过超链接的请求方式,但因为超链接是get请求,无法传大量的数据。如果你想到了用ajax,那么很抱歉,因为ajax不支持流形式的导出,所以是无法导出excel的。 下面写出我的解决方案,通过form表单的形式进行导出。 HTML代码:通过提交表单,将数据传到后台,注意要使用ifra...

qq_28406419的博客 3802

poi导出excel

JavaPOI导出Excel有三种形式,他们分别是 1.HSSFWorkbook 2.XSSFWorkbook 3.SXSSFWorkbook。 HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls; XSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx; SXSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx; 第一种:HSSFWorkbook poi导出excel最常用的方式;但是此种方式的局限

mettle_heng的博客 9512

POI如何高效导出百万级Excel数据?

阅读原文:POI如何高效导出百万级Excel数据?在一个具有统计功能的系统中,导出excel功能几乎是一定的,如何导出excel?导出的数据有多少?如何高效的导出?Excel简介什么是excel就不用介绍了,这里主要说明不同版本下每个sheet下的行列限制。由上面可知 Excel 2003及以下是无法实现单sheet百万级的数据。Apache POI简介Apache POI 是用Java编写的免费...

weixin_34319374的博客 1400
上一篇: String_equals_和_Object_equals_有何区别?
下一篇: 【在浏览器输入网址后,都发生了什么?一张图带你了解】
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值