数百万のデータを複数のシートに分割して Excel にエクスポートする方法
数百万のデータを Excel にエクスポートするのは非常に簡単です。ただし、データが 300 万個ある場合は、元の HSSFWorkbook を SXSSFWorkbook に変更するだけです。 Excel シート ページを一度にインポートします。Excel を開くのに時間がかかると、プログラムの読み込みに失敗したり、プロセスが直接終了したりする可能性があります。データを見ているだけで頭が痛くなります。あるニュースを見て、ここにいる外国人の忍耐力にとても感心しました。
コードの一部は、参照と調査のためにここに提供されています:
@SuppressWarnings({ "deprecation", "unchecked" }) @RequestMapping("export-TrainHistoryRecord") @ResponseBodyprotected void buildExcelDocument(EmployeeTrainHistoryQuery query,ModelMap model, SXSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {try { response.reset();// 获得国际化语言RequestContext requestContext = new RequestContext(request); String CourseCompany = requestContext .getMessage("manage-student-trainRecods"); response.setContentType("APPLICATION/vnd.ms-excel;charset=UTF-8");// 注意,如果去掉下面一行代码中的attachment; 那么也会使IE自动打开文件。 response.setHeader("Content-Disposition","attachment; filename=" + java.net.URLEncoder.encode( DateUtil.getExportDate() + ".xlsx", "UTF-8"));//Excel 扩展名指定为xlsx SXSSFWorkbook对象只支持xlsx格式OutputStream os = response.getOutputStream(); CellStyle style = workbook.createCellStyle();// 设置样式style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);//设置单元格着色style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); //设置单元格填充样式style.setBorderBottom(HSSFCellStyle.BORDER_THIN);//设置下边框style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//设置左边框style.setBorderRight(HSSFCellStyle.BORDER_THIN);//设置右边框style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中//获取国际化文件String employeeCode = requestContext.getMessage("employeeCode"); String employeeName = requestContext.getMessage("employeeName"); String orgName = requestContext.getMessage("orgName"); String startDate = requestContext.getMessage("start.date"); String endDate = requestContext.getMessage("end.date"); String courseCode = requestContext.getMessage("courseCode"); String courseName = requestContext.getMessage("courseName"); String sessionName = requestContext.getMessage("sessionName"); List<EmployeeTrainHistoryModel> list = null;try {//查询数据库中共有多少条数据 query.setTotalItem(employeeTrainHistoryService.fetchCountEmployeeTrainHistoryByQuery(query)); int page_size = 100000;// 定义每页数据数量int list_count =query.getTotalItem();//总数量除以每页显示条数等于页数int export_times = list_count % page_size > 0 ? list_count / page_size+ 1 : list_count / page_size; //循环获取产生每页数据for (int m = 0; m < export_times; m++) { query.setNeedQueryAll(false); query.setPageSize(100000);//每页显示多少条数据query.setCurrentPage(m+1);//设置第几页 list=employeeTrainHistoryService.getEmployeeTrainHistoryByQuery(query);//新建sheet Sheet sheet = null; sheet = workbook.createSheet(System.currentTimeMillis()+ CourseCompany+m);// 创建属于上面Sheet的Row,参数0可以是0~65535之间的任何一个,Row header = sheet.createRow(0); // 第0行// 产生标题列,每个sheet页产生一个标题 Cell cell; String[] headerArr = new String[] { employeeCode, employeeName, orgName, startDate, endDate, courseCode, courseName, sessionName, hoursNunber };for (int j = 0; j < headerArr.length; j++) { cell = header.createCell((short) j); cell.setCellStyle(style); cell.setCellValue(headerArr[j]); }// 迭代数据 if (list != null && list.size() > 0) { int rowNum = 1; for (int i = 0; i < list.size(); i++) { EmployeeTrainHistoryModel history=list.get(i); sheet.setDefaultColumnWidth((short) 17); Row row = sheet.createRow(rowNum++); row.createCell((short) 0).setCellValue( history.getEmployeeCode()); row.createCell((short) 1).setCellValue( history.getEmployeeName()); row.createCell((short) 2) .setCellValue(history.getOrgName()); if (history.getTrainBeginTime() != null) { row.createCell((short) 3).setCellValue( DateUtil.toString(history.getTrainBeginTime())); } else { row.createCell((short) 3).setCellValue(""); } if (history.getTrainEndTime() != null) { row.createCell((short) 4).setCellValue( DateUtil.toString(history.getTrainEndTime())); } else { row.createCell((short) 4).setCellValue(""); } row.createCell((short) 5).setCellValue( history.getCourseCode()); row.createCell((short) 6).setCellValue( history.getCourseName()); row.createCell((short) 7).setCellValue( history.getSessionName()); if (history.getHoursNumber() != null) row.createCell((short) 8).setCellValue( history.getHoursNumber().toString()); } } list.clear(); } } catch (Exception e) { e.printStackTrace(); }try { workbook.write(os); os.close(); } catch (Exception e) {// TODO Auto-generated catch block e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } }
大量のデータをエクスポートする場合、効率の問題を考慮する必要があります。どうすれば時間を捻出できるでしょうか? Apache POI は Excel をエクスポートする方法を提供しているので、公式ドキュメントを確認してください。確かに、ドキュメントを見ると、おそらく大きなスプレッドシートを生成する必要がある場合に SXSSF が使用されることになります。ヒープ領域は限られています 公式では 2 つのメソッドが提供されています:
1. SXSSFWorkbook wb = new SXSSFWorkbook(100) // 100 行をメモリに保持し、超過した行はディスクにフラッシュされます
2. -1); // 自動フラッシュをオフにし、すべての行をメモリに蓄積します
値 100 メモリに 100 行を保持し、余分な行はディスクにフラッシュされます
値 -1 は無制限のアクセスを意味します。 この場合、ランダム アクセス用に、flush() の呼び出しによってフラッシュされたレコードはすべて使用できません。 記事の最後に、一時ファイルが大きすぎる場合は setCompressTempFiles メソッドを使用して圧縮できるとありました
ここでは欲張って 2 つを使用しました。テストデータは図の通りですが、何か問題があるのかわかりません。私のプログラムの作成について知っている場合は、メッセージを残してください。以上が数百万のデータを複数のシートに分割するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。