我试图在Spring Boot中创建一个休息端点,该端点从DB读取数据,生成一个excel文件(使用Apache POI),并使用HttpServletResponse返回给用户,但是当我调用此文件时,会创建excel,但不是下载。我之前有一些其他代码可以正常工作,但是我不小心删除了这些代码,但是现在我陷入了困境。任何帮助/线索都表示赞赏。
@RequestMapping(path = "/save", method = RequestMethod.GET)
public ResponseEntity<String> saveToXls(@RequestParam String id, @RequestParam String appName, HttpServletResponse response) {
AppInstance appInstance = appInstanceRepo.get(id);
List<DownloadDetail> downloadDetailList = downloadDAO.searchByInstanceId(id);
//List<DownloadDetail> downloadDetailList = appInstance.getDownloads();
System.out.print("LIST SIZE:" + downloadDetailList.size());
String fileName = appName + " report";
File myFile = new File(fileName + ".xls");
FileOutputStream fileOut;
downloadDetailList.forEach(downloadDetail -> System.out.print(downloadDetail.getSid()));
try {
try (HSSFWorkbook workbook = new HSSFWorkbook()) {
HSSFSheet sheet = workbook.createSheet("lawix10");
HSSFRow rowhead = sheet.createRow((short) 0);
rowhead.createCell((short) 0).setCellValue("SID");
rowhead.createCell((short) 1).setCellValue("Download Time");
rowhead.createCell((short) 2).setCellValue("OS Version");
int i = 0;
for (DownloadDetail downloadDetail : downloadDetailList) {
System.out.print("In loop -2");
HSSFRow row = sheet.createRow((short) i);
row.createCell((short) 0).setCellValue(downloadDetail.getSid());
row.createCell((short) 1).setCellValue(downloadDetail.getDownloadTime());
row.createCell((short) 2).setCellValue(downloadDetail.getOsVersion());
i++;
}
fileOut = new FileOutputStream(myFile);
workbook.write(fileOut);
}
fileOut.close();
byte[] buffer = new byte[10240];
response.addHeader("Content-disposition", "attachment; filename=test.xls");
response.setContentType("application/vnd.ms-excel");
try (
InputStream input = new FileInputStream(myFile);
OutputStream output = response.getOutputStream();
) {
for (int length = 0; (length = input.read(buffer)) > 0;) {
output.write(buffer, 0, length);
}
}
response.flushBuffer();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
return null;
}
编辑: 我试图用另一种方式做到这一点,如下所示:
try (InputStream is = new FileInputStream(myFile)) {
response.addHeader("Content-disposition", "attachment; filename=test.xls");
response.setContentType("application/vnd.ms-excel");
IOUtils.copy(is, response.getOutputStream());
}
response.flushBuffer();
这似乎也没有削减。
答案 0 :(得分:0)
这是我的例子。问题可能出在您如何管理OutputStream:
ServletOutputStream os = response.getOutputStream();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\""+fileName+".xls\"");
workbook = excelStrategyMap.get(strategy).export(idList, status, params);
workbook.write(os);
workbook.close();
os.flush();
response.flushBuffer();
答案 1 :(得分:0)
一旦获得工作簿文件,请设置文件名和文件类型。并添加如下所述的响应标头和内容类型。
然后将文件写入响应并刷新其缓冲区。
XSSFWorkbook file = excelUploadService.downloadDocument();
String filename = "Export.xlsx";
String filetype = "xlsx";
response.addHeader("Content-disposition", "attachment;filename=" + filename);
response.setContentType(filetype);
// Copy the stream to the response's output stream.
file.write(response.getOutputStream());
response.flushBuffer();
在客户端,从REST API获取响应,并设置响应对象接收的内容类型。使用FileSaver库将文件保存到本地文件系统中。
这是FileSaver js的文档-File saver JS Library
var type = response.headers("Content-Type");
var blob = new Blob([response.data], {type: type});
saveAs(blob, 'Export Data'+ '.xlsx');
答案 2 :(得分:0)
@GetMapping(value = "/", produces = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
@ResponseBody
public byte[] generateExcel() {
byte[] res = statisticsService.generateExcel();
return res;