poi1.6 若使用SXSSFWorkbook 执行 workbook.write(outputStream); 会导致每100个row进行一次flush导致Stream流关闭如何解决
时间: 2024-03-18 18:40:54 浏览: 51
可以通过设置缓存窗口大小来解决这个问题。默认情况下,SXSSFWorkbook的缓存窗口大小为100,达到100行时会自动将缓存写入输出流并清空缓存。如果你不希望在100行时自动刷新,可以使用setCompressTempFiles()方法来设置缓存窗口大小。例如,你可以这样设置缓存窗口大小为1000:
```
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
workbook.setCompressTempFiles(false);
```
这样设置后,缓存窗口大小为1000,每1000行时会自动将缓存写入输出流并清空缓存。同时,设置setCompressTempFiles(false)可以避免在缓存写入输出流时关闭输出流。
相关问题
poi1.6 执行 workbook.write(outputStream); 会导致每100个row进行一次flush导致Stream流关闭如何解决
在 `SXSSFWorkbook` 中,数据的写入是通过缓存来实现的,缓存的默认大小是 100,当达到缓存大小时,`SXSSFWorkbook` 会自动将缓存中的数据写入到磁盘中的临时文件。当写入临时文件的数据量达到指定的内存阈值时,`SXSSFWorkbook` 会将临时文件中的数据写入到输出流中。因此,在使用 `SXSSFWorkbook` 写入数据时,需要注意以下两点:
1. 当临时文件中的数据量达到指定的内存阈值时,`SXSSFWorkbook` 会将临时文件中的数据写入到输出流中,如果此时输出流已经关闭,则会抛出异常。因此,在写入数据时需要保证输出流没有被关闭。
2. 当缓存中的数据量达到指定的大小时,`SXSSFWorkbook` 会将缓存中的数据写入到临时文件中,并清空缓存。因此,如果想要避免在写入临时文件时关闭输出流,可以通过设置缓存大小来实现。例如,可以将缓存大小设置为 1000,这样可以减少写入临时文件的次数,提高性能,同时也可以避免在写入临时文件时关闭输出流。具体示例如下:
```
SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
workbook.setCompressTempFiles(false);
```
这样设置后,缓存大小为 1000,每当写入 1000 行数据时,`SXSSFWorkbook` 会将缓存中的数据写入到临时文件中,并清空缓存。同时,禁用临时文件的压缩可以避免在写入临时文件时关闭输出流。
@RequestMapping(value = "export", method = RequestMethod.GET) public void exportToExcel(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException { System.out.println("111"); List<Attendance> attendanceList = (List<Attendance>) session.getAttribute("list"); // 创建 Excel 文档 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("Attendance"); // 创建表头 Row headerRow = sheet.createRow(0); String[] headers = {"考勤ID", "用户ID", "用户名", "考勤时间", "考勤类型"}; for (int i = 0; i < headers.length; i++) { Cell cell = headerRow.createCell(i); cell.setCellValue(headers[i]); } // 填充数据 int rowIndex = 1; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for (Attendance attendance : attendanceList) { Row dataRow = sheet.createRow(rowIndex); dataRow.createCell(0).setCellValue(attendance.getAttendanceid()); dataRow.createCell(1).setCellValue(attendance.getUserid()); dataRow.createCell(2).setCellValue(attendance.getUsername()); dataRow.createCell(3).setCellValue(sdf.format(attendance.getDate())); dataRow.createCell(4).setCellValue(attendance.getType()); rowIndex++; } // 设置响应头 response.setHeader("content-type", "application/octet-stream"); response.setContentType("application/force-download"); response.addHeader("Content-Disposition", "attachment; filename=attendance.xlsx"); // 将 Excel 数据写入响应输出流 OutputStream outputStream = response.getOutputStream(); workbook.write(outputStream); workbook.close(); outputStream.flush(); outputStream.close(); }
这段代码是一个 Spring MVC 的控制器方法,用于将考勤记录导出为 Excel 文件。当用户访问 /export 路径时,该方法会被调用。该方法的参数包括 HttpServletRequest、HttpServletResponse 和 HttpSession。在方法体中,首先输出 "111",然后从 HttpSession 中获取名为 "list" 的属性,该属性的类型为 List<Attendance>。
接下来,通过 Apache POI 库创建了一个名为 workbook 的 XSSFWorkbook 对象,然后创建了名为 "Attendance" 的 Sheet 对象。在 Sheet 对象中,先创建了一个表头 Row 对象,然后将表头的内容写入到这个 Row 对象中。接着,通过遍历 attendanceList,将考勤记录的数据写入 Sheet 对象中的每一行 Row 中。
最后,设置响应头,将 Excel 数据写入 HttpServletResponse 的输出流中,并关闭 workbook 和输出流。通过这些步骤,控制器方法将考勤记录导出为 Excel 文件,并将其作为响应返回给客户端。
阅读全文