[英]How to download a Spring Boot ByteArrayResource with axios?
[英]How to download excel file in JS from Java ByteArrayResource
我正在尝试在 Web 应用程序中添加一个按钮,以允许我的同事下载 excel 文件。
在后面:
public String getInvoiceList(String invoiceNumber) {
System.out.println("invoice number : " + invoiceNumber);
//Recursively list all files
List<Path> pathList = new ArrayList<>();
//The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner.
try (Stream<Path> stream = Files.walk(Paths.get(SERVER_LOCATION))) {
System.out.println("WE ARE IN");
pathList = stream.map(Path::normalize)
.filter(Files::isRegularFile) // directories, hidden files and files without extension are not included
.filter(path -> path.getFileName().toString().contains(invoiceNumber))
.filter(path -> path.getFileName().toString().endsWith(EXTENSION))
.collect(Collectors.toList());
}
catch(IOException e) {
e.printStackTrace();
}
if(pathList.isEmpty()) {
System.out.println("NO INVOICE FILE FOUND : " + invoiceNumber);
return null;
}
else {
pathList.forEach(System.out::println);
return pathList.get(0).toString();
}
}
@GetMapping(value = "/downloadInvoiceExcel")
public ResponseEntity<Resource> download(@RequestParam("invoiceNumber") String invoiceNumber) throws IOException {
String filename = getInvoiceList(invoiceNumber);
File file = new File(filename);
System.out.println("filename : " + file);
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+filename);
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
Path path = Paths.get(file.getAbsolutePath());
System.out.println("Absolute Path : " + path);
ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path));
return ResponseEntity.ok()
.headers(header)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
}
如何将 byteArrayResource 转换为 JS 中的文件?
我在前端试过这个
选择要下载的文件后,有一个按钮可以调用此功能
这是在动态页面中,js 代码用于组件。 所以不可能进口。
invoiceDownload() {
for(let i of that.table.selectionRows) { //we go through all the elements with selected
let invoice_number = i["invoice_number"]; // we get the value of the field we want
let param = {invoiceNumber: invoice_number};
getAction('/shippingInvoice/downloadInvoiceExcel', param) // goes to backend to get the file
.then(res=> {
let filename = "Invoice N°" + invoice_number + ".xlsx";
var buf = new ArrayBuffer(res.length);
var view = new Uint8Array(buf);
for (var i=0; i!=res.length; ++i) view[i] = res.charCodeAt(i) & 0xFF;
var blob = new Blob([buf], {
type: "application/octet-stream"
});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
link.click();
});
}
}
但是数据已损坏
我对 Spring 和 JS 很陌生
编辑:我在 Spring 中打印了 file.length() ,它与 JS 中的 res.length 不同,后者的值较小,可能是什么原因?
我会将ByteArrayResource
更改为FileSystemResource
,它在其构造函数中采用path
并允许将文件流式传输到响应,而不是先将其读入内存(这可能会导致服务器上出现内存问题)。
在您的客户端代码中直接链接到后端,而不是使用纯 HTML 将其下载到 JavaScript:
<a href="/shippingInvoice/downloadInvoiceExcel?invoiceNumber=...">Download Excel Invoice</a>
无需先将其缓冲到 JS 中,让浏览器和服务器负责协商下载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.