繁体   English   中英

如何从 Java ByteArrayResource 下载 JS 中的 excel 文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM