EasyExcel导出数据量大导致内存溢出

 一次性读入过多数据,如果内存不够大就会导致内存溢出,所以将数据分批处理,最后在EasyExcel导出的时候再汇总导出。至于接口耗时问题,就需要根据实际调整批次的最大数量。

/**
	 * 全量导出工艺工时
	 *
	 * @param response 请求信息
	 */
	@Override
	public void exportEngineeringStandardWorkTime(HttpServletResponse response) {
		

		//分批获取导出数据
		List<List<MoonStandardWorkTimeExportVO>> batchedData = splitIntoBatches();

		//导出数据
		try {
			String fileName = "设备工艺工时信息" + LocalDate.now();
			fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
			response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

			WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
			contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

			EasyExcel.write(response.getOutputStream(), MoonStandardWorkTimeExportVO.class)
				.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
				.registerWriteHandler(new HorizontalCellStyleStrategy(new WriteCellStyle(), contentWriteCellStyle))
				.sheet("设备工艺工时信息")
				.doWrite(batchedData.stream().flatMap(List::stream).collect(Collectors.toList()));
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 分批查询
	 *
	 * @return 分批后的数据列表
	 */
	private List<List<MoonStandardWorkTimeExportVO>> splitIntoBatches() {

		List<List<MoonStandardWorkTimeExportVO>> batches = new ArrayList<>();
		// 分批写入数据
		int current = 0;
		int batchSize = 100000;

		while (true) {
			Page page = new Page<>();
			current = current + 1;
			page.setCurrent(offset);
			page.setSize(batchSize);
			List<MoonStandardWorkTimeExportVO> batch = this.baseMapper.selectEngineeringStandardWorkTime(page).getRecords();
			if (ObjectUtil.isNotEmpty(batch)) {
				batches.add(batch);
			} else {
				break;
			}
            // 检查内存使用情况,如果内存使用过高,可以考虑定期清理数据
		    long freeMemory = runtime.freeMemory();
		    long totalMemory = runtime.totalMemory();
		    // 如果剩余内存小于总内存的20%
		    if (freeMemory < totalMemory * 0.2) { 
			    System.gc(); // 请求垃圾回收
		    	runtime.gc(); // 再次请求垃圾回收
		    }
		}
        
		return batches;
	}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值