我正在尝试使用POI下载Excel文件。正在下载excel文件作为响应的附件。我提到了Stack Overflow上的其他问题,其中的答案主要是尝试不同的内容类型,我尝试了所有提到的不同内容类型,但仍然下载的Excel文件已损坏。
另外,当我尝试使用相同的代码在文件系统上编写Excel时(仅将更改写入文件系统而不是作为附件返回),正确创建了文件系统上生成的excel并没有腐败。只有当我尝试使用HTTP响应返回它时,excel文件才会被破坏。
以下是我用于excel下载的代码:
MainController.java
if (downloadFlag) {
response = reportsService.initializeXLSContent(response, "Tests_By_Day", fromDate, toDate);
List<String> columnNames = new ArrayList<>();
columnNames.add("Day");
columnNames.add("Tests Count");
populateAndDispatch(response, result, columnNames);
return null;
}
initializeXLSContent方法
public HttpServletResponse initializeXLSContent(HttpServletResponse response, String fileName, Date startDate,
Date endDate) {
response.setContentType("application/force-download");
StringBuilder reportName = new StringBuilder(fileName);
Calendar calendar = Calendar.getInstance();
if (null != startDate) {
calendar.setTime(startDate);
reportName = reportName.append("_" + calendar.get(Calendar.YEAR) + "_" + (calendar.get(Calendar.MONTH) + 1)
+ "_" + calendar.get(Calendar.DAY_OF_MONTH));
}
if (null != endDate) {
calendar.setTime(endDate);
reportName = reportName.append("_" + calendar.get(Calendar.YEAR) + "_" + (calendar.get(Calendar.MONTH) + 1)
+ "_" + calendar.get(Calendar.DAY_OF_MONTH));
}
reportName.append(".xlsx");
response.setHeader("Content-Disposition", "attachment;filename=" + reportName.toString());
response.setHeader("Content-Transfer-Encoding", "binary");
return response;
}
populateAndDispatch方法
private void populateAndDispatch(HttpServletResponse response, List<ChartData> chartData,
List<String> columnNames) {
List<ArrayList<String>> reportData = new ArrayList<>();
switch (columnNames.size()) {
case 2:
twoColumnPopulate(chartData, reportData);
break;
case 3:
threeColumnPopulate(chartData, reportData);
break;
}
XSSFWorkbook workbook = reportsService.generateContentXLS(reportData, columnNames);
response = reportsService.dispatchXLSContent(response, workbook);
twoColumnPopulate方法
private void twoColumnPopulate(List<ChartData> chartData, List<ArrayList<String>> reportData) {
for (ChartData rowData : chartData) {
ArrayList<String> tempRowData = new ArrayList<>();
tempRowData.add(rowData.getxData());
tempRowData.add(rowData.getyData());
reportData.add(tempRowData);
}
}
generateXLSContent方法
public XSSFWorkbook generateContentXLS(final List<ArrayList<String>> sheetData, List<String> columnNames) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
XSSFRow headerRow = sheet.createRow(0);
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 14);
font.setBoldweight(Font.BOLDWEIGHT_BOLD);
style.setFont(font);
int i = 0; // i is used to iterate over rows
for (String columnName : columnNames) {
Cell cell = headerRow.createCell(i++);
cell.setCellValue(columnName);
cell.setCellStyle(style);
}
int j;
int k = 1; // j is used to iterate over columns and k is used to count
// no.of rows
for (ArrayList<String> rowData : sheetData) {
XSSFRow row = sheet.createRow(k++);
for (j = 0; j < i; j++) {
row.createCell(j).setCellValue(rowData.get(j));
}
}
return workbook;
}
dispatchXLSContent方法
public HttpServletResponse dispatchXLSContent(HttpServletResponse response, XSSFWorkbook workbook) {
try {
workbook.write(response.getOutputStream());
response.getOutputStream().flush();
workbook.close();
} catch (IOException ie) {
LOGGER.error("IOException occurred in dispatchXLSContent: ", ie);
}
return response;
}
我发现有一件有趣的事情是,我创建了一个示例API来测试这个excel下载功能,并且它在相同的设置下运行良好,但在我的这个特定API中没有。以下是该示例API的代码。
public void testDownload(HttpServletResponse response) throws IOException {
List<String> test = new ArrayList<>();
test.add("A");
test.add("B");
test.add("C");
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
XSSFRow headerRow = sheet.createRow(0);
Cell cell1 = headerRow.createCell(0);
cell1.setCellValue("Header 1");
Cell cell2 = headerRow.createCell(1);
cell2.setCellValue("Header 2");
XSSFRow row = sheet.createRow(0);
row.createCell(0).setCellValue("Cell 1");
row.createCell(1).setCellValue("Cell 2");
row = sheet.createRow(1);
row.createCell(0).setCellValue("Cell 1");
row.createCell(1).setCellValue("Cell 2");
response.setHeader("Content-Disposition", "attachment;filename=hello.xlsx");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setContentType("application/force-download");
workbook.write(response.getOutputStream());
response.getOutputStream().flush();
workbook.close();
}
在这种情况下,Excel不会被破坏并正在正确下载。