簡體   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