我目前正致力于通过Apache POI创建Excel的后端Spring REST服务,并且需要响应Angular Front-end。 Angular前端需要打开一个新窗口来显示/下载电子表格。
这是目前的后端方法:
@GetMapping(value = "/api/path/{testValue}")
public ResponseEntity<Object> downloadTestFile(@PathVariable(required = false, value = "testValue") int testValue) throws IOException {
try {
List<TestObject> testObjectList = testService.getObjectListList(testValue);
Workbook responseExcel = testService.createExcel(testObjectList);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
responseExcel.write(outStream);
ByteArrayResource resource = new ByteArrayResource(outStream.toByteArray());
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", "1.xls"));
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
ResponseEntity<Object> responseEntity = ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
return responseEntity;
} catch (Exception e) {
return new ResponseEntity<>("error occurred", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
我的测试前端Angular方法:
var app = angular.module('testApp', []);
app.controller('testCtrl', function($scope, $http) {
$http.get("/api/path/12345")
.then(function onSuccess(response) {
var data = response.data;
var blob = new Blob([data], {type: "application/vnd.ms-excel"});
var objectUrl = URL.createObjectURL(blob);
window.open(objectUrl);
}, function onError(response) {
//upload failed
console.log('Error');
});
});
出于某种原因,Excel因错误的名称而损坏,并且无法打开。我尝试了各种MIME类型。我还尝试从Excel手动保存电子表格并将其拉入InputStreamResource,但我得到的结果与通过Apache POI方法生成的结果相同。
知道什么是错的吗?
答案 0 :(得分:0)
您可以尝试以下代码。
@GET
@Produces("application/vnd.ms-excel")
public Response getExcelFile(HttpServletRequest httpServletRequest) {
List<TestObject> testObjectList = testService.getObjectListList(testValue);
//list all columns
String[] columns = {"col1", "col2"};
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
// Create a Row
Row hr = sheet.createRow(0);
for (int c = 0; c < columns.length; c++) {
Cell cell = hr.createCell(c);
cell.setCellValue(columns[c]);
}
// Create Other rows and cells with data
int rowNum = 1;
for(TestObject obj : testObjectList){
Row row = sheet.createRow(rowNum++);
row.createCell(1).setCellValue(obj.getCol1());
row.createCell(2).setCellValue(obj.getCol2());
}
// Resize all columns to fit the content size
for (int i = 0; i < columns.length; i++) {
sheet.autoSizeColumn(i);
}
// Now finally build response and send
StreamingOutput streamOutput = new StreamingOutput() {
@Override
public void write(OutputStream out) throws IOException,
WebApplicationException {
wb.write(out);
}
};
javax.ws.rs.core.Response.ResponseBuilder response = Response.ok(streamOutput,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.header("content-disposition", "attachment; filename=\"sample_download_file\".xlsx");
return response.build();
}