AgentScope 学习系列 - 02:ReActAgent 配置、消息与事件
2026/10/1 15:43:38
数据量上万甚至几十万时,一次性查询 + 一次性写入 excel 会导致内存溢出、系统卡死,需要「边查边写」。
核心四步:
sheetSize行后,切换到下一个 sheet。excelMaxSize直接停止,避免无限导出。关键参数:
| 参数 | 说明 | 示例值 |
|---|---|---|
pageSize | 每页查询条数 | 10000 |
sheetSize | 单个 sheet 最大行数 | 10000 ~ 100000 |
excelMaxSize | 导出总条数上限 | 1000000 |
/** * 大数据量导出:分页查询 + 分 sheet 写入 * 业务查询条件通过 params 传入,方法内只处理分页参数 * * @param params 业务查询条件 * @param response 响应 * @param formClient 数据查询客户端 */publicvoidexportExcel(JSONObjectparams,HttpServletResponseresponse,FormClientformClient){// 每次分页查询大小intpageSize=10000;// 每个 sheet 的行数intsheetSize=10000;// excel 导出最大值,防止内存溢出longexcelMaxSize=1000000L;// 已读取的数据量longtotal=0;// 当前读取到第几页数据,从 1 开始intcurrent=1;// 第一步,创建一个 workbook,对应一个 Excel 文件HSSFWorkbookhwb=newHSSFWorkbook();// 设置样式HSSFCellStylestyle=setRowStyle(hwb);try{// 缓存全部数据,再按 sheetSize 拆分写入JSONArrayjsonArray=newJSONArray();// 第二步,分页拉取数据do{params.put("pageIndex",current);params.put("pageSize",pageSize);JsonResultdkResult=formClient.queryForJson("zss_qylb_data2",JSONObject.toJSONString(params));JSONObjectdkObject=JSONObject.parseObject(dkResult.toString());JSONArraydkArray=dkObject.getJSONArray("data");if(CollectionUtils.isEmpty(dkArray)){break;}jsonArray.addAll(dkArray);total=current*pageSize+dkArray.size();// 已写入的数据已经超过最大值限制,则退出if(total>=excelMaxSize){break;}// 换下一页current++;}while(true);StringfileName="导出数据";// 第三步,按 sheetSize 拆分,写入多个 sheetif(jsonArray.size()>0){intsize=jsonArray.size()/sheetSize;for(inti=0;i<=size;i++){HSSFSheetsheet=hwb.createSheet("sheet"+(i+1));// 设置表头createRowHead(sheet,style);// 取当前 sheet 的数据区间List<Object>subList=i<size?jsonArray.subList(i*sheetSize,(i+1)*sheetSize):jsonArray.subList(i*sheetSize,jsonArray.size());setRowData(newJSONArray(subList),sheet,style);}}// 第四步,导出ExcelChangeUtil.exportExcelByDownload(hwb,response,fileName);}catch(Exceptionex){logger.error(ExceptionUtil.getExceptionMessage(ex));MessageUtil.triggerException("出错了,请重试!",null);}}// 设置样式privateHSSFCellStylesetRowStyle(HSSFWorkbookhwb){HSSFCellStylestyle=hwb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);// 左右居中style.setVerticalAlignment(style.getVerticalAlignmentEnum().CENTER);// 垂直居中style.setFillForegroundColor(IndexedColors.YELLOW.getIndex());// 背景颜色Fontfont=hwb.createFont();font.setFontHeightInPoints((short)11);font.setFontName("宋体");style.setFont(font);returnstyle;}// 创建表头(列按业务自行增删)privatevoidcreateRowHead(HSSFSheetsheet,HSSFCellStylestyle){HSSFRowrow=sheet.createRow(0);String[]heads={"序号","名称","统一社会信用代码","所属县区","行业代码","备注"};for(inti=0;i<heads.length;i++){HSSFCellcell=row.createCell(i);cell.setCellStyle(style);cell.setCellValue(heads[i]);// 部分列宽度需要加长,可单独设置sheet.setColumnWidth(i,i==1?10000:5000);}}// 封装数据(字段按业务自行替换)privatevoidsetRowData(JSONArrayarray,HSSFSheetsheet,HSSFCellStylestyle){for(inti=0;i<array.size();i++){JSONObjectdata=array.getJSONObject(i);HSSFRowrow=sheet.createRow(i+1);HSSFCellc=row.createCell(0);c.setCellStyle(style);c.setCellValue(i+1);c=row.createCell(1);c.setCellStyle(style);c.setCellValue(data.getString("qymc")!=null?data.getString("qymc"):"--");c=row.createCell(2);c.setCellStyle(style);c.setCellValue(data.getString("tyshxydm")!=null?data.getString("tyshxydm"):"--");}}@PostMapping("/exportExcel")publicvoidexportExcel(QueryDataqueryData,HttpServletResponseresponse){// 每次分页查询大小intpageSize=10000;// 每个 sheet 的大小longsheetSize=100000L;// excel 导出最大值longexcelMaxSize=1000000L;// 已读取的数据量longtotal=0;// 当前读取到第几页数据,从 1 开始intcurrent=1;QueryFilterqueryFilter=QueryFilterBuilder.createQueryFilter(queryData);handleFilter(queryFilter);// 重新设置分页控制:分页不 countIPagepage=newcom.baomidou.mybatisplus.extension.plugins.pagination.Page(current,pageSize,false);queryFilter.setPage(page);ExcelWriterexcelWriter=null;try{excelWriter=EasyExcel.write(response.getOutputStream(),Demo.class).build();// 注意:同一个 sheet 只要创建一次WriteSheetwriteSheet=EasyExcel.writerSheet("sheet1").build();do{page.setCurrent(current);getBaseService().query(queryFilter);List<Demo>list=page.getRecords();if(CollectionUtils.isEmpty(list)){break;}excelWriter.write(list,writeSheet);// 如果 sheet 满了,换下一个 sheetif(current>1&&(current*pageSize%sheetSize==0)){writeSheet=EasyExcel.writerSheet("sheet"+((current*pageSize/sheetSize)+1)).build();}total=current*pageSize+list.size();// 已写入的数据已经超过最大值限制,则退出if(total>=excelMaxSize){break;}// 换下一页current++;}while(true);}catch(Exceptionex){MessageUtil.triggerException("出错了,请重试!",null);logger.error(ExceptionUtil.getExceptionMessage(ex));}finally{if(excelWriter!=null){excelWriter.finish();}}}HSSFWorkbook(.xls)单 sheet 最多 65536 行,若sheetSize需要更大(如 10w),请改用XSSFWorkbook或 EasyExcel(.xlsx)。EasyExcel.writerSheet(...).build()。new Page(current, pageSize, false)的第三个参数为false时不执行 count 查询,导出场景能明显提速。total = current * pageSize + list.size()只是估算值(当前页不满时会偏大),仅用于上限判断,不用于精确统计。jsonArray再按 sheet 拆分;数据量特别大时建议改为边查边写,避免缓存占用过多内存。