Comment diviser des millions de données en plusieurs feuilles et les exporter vers Excel
Exporter des millions de données vers Excel est très simple. Il vous suffit de modifier le HSSFWorkbook d'origine en SXSSFWorkbook. ok, mais s'il y a 3 millions de données, importez-les immédiatement dans une page de feuille Excel. Pensez-y, l'ouverture d'Excel prendra un certain temps. Si cela est lent, le chargement du programme peut échouer. soit le processus se terminera directement, soit il s'ouvrira. Il y a tellement de données que cela me donne mal à la tête de les regarder. J'ai vu une fois une nouvelle dans laquelle j'admire profondément la persévérance des étrangers.
Une partie du code est donnée ici à titre de référence et de recherche. La pagination a été implémentée :
@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(); } }
1. SXSSFWorkbook wb = new SXSSFWorkbook(100); // conserve 100 lignes en mémoire, les lignes excédentaires seront vidées sur le disque
2. SXSSFWorkbook wb = new SXSSFWorkbook(-1 ; >
Une valeur de -1 indique un accès illimité. Dans ce cas, tous les enregistrements qui n'ont pas été vidés par flush() sont disponibles,est utilisé pour un accès aléatoire.
L'article dit à la fin que lorsque le fichier temporaire est trop volumineux, vous pouvez utiliser la méthode setCompressTempFiles pour le compresser, Je suis gourmand. J'en ai utilisé deux ici, l'un est utilisé pour configurer des fichiers temporaires et l'autre est utilisé pour saisir des données. Les données de test sont des données de 30w. le chiffre. Cependant, j'ai toujours l'impression que cela prend trop de temps. Je ne sais pas pourquoi. Ce n'est pas qu'il y a quelque chose qui ne va pas dans l'écriture de mon programme. Amis qui savent, s'il vous plaît, laissez un message !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!