【问题标题】:Excel file corrupted when downloaded using ReactJs jQuery ajax post request使用 ReactJs jQuery ajax 发布请求下载时 Excel 文件损坏
【发布时间】:2019-10-25 03:02:24
【问题描述】:

我正在尝试使用来自 ReactJs 的 jQuery ajax 发布请求下载文件。我有中间层的快速路由器,它使用请求 api 将请求发送到 Spring Boot 休息 api。 ajax => express post route => Spring Boot api。文件正在下载,但内容一直损坏。

我已经尝试了互联网上提供的所有解决方案,但没有一个适合我。

// ajax calling express post route
$.ajax({
            url: "/downloadReport",
            contentType: 'application/json',
            data:JSON.stringify({"data1":"value1"}),
            type:'POST',
            cache: true,
            responseType: 'arraybuffer',
            success: function(response) {
                console.log(response);
                var fileName=response.headers['content-disposition'].split('filename=')[1];
                var blob = new Blob([response.data], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
                const blobURL = window.URL.createObjectURL(blob);
                const tempLink = document.createElement('a');
                tempLink.style.display = 'none';
                tempLink.href = blobURL;
                tempLink.setAttribute('download', fileName);
                tempLink.click();

            }.bind(this),
            error: function(xhr, status, err) {
                console.log(err)
                console.log(status)
                console.log(xhr)
            }.bind(this)
        })

// express route.
router.post("/downloadReport", (req, response, next) => {
    request(
        {
            url: '/springbootapi/downloadCustomerReport',
            method: "POST",
            body: JSON.stringify(req.body),
            headers: {
                'Content-Type':'application/json'
            },
        }, function (error, res, body) {
            if(error){
                console.log(error);
                response.status(500).send(error);
            }else{
                try {
                    response.send({headers: res.headers, data: res.body})
                }catch(err){
                    response.status(500).send(err)
                }
            }
        }
    )
});
// in springboot rest api
@RequestMapping(value = "/downloadCustomerReport", method = RequestMethod.POST)
    public ResponseEntity<byte[]> downloadCustomerReport(@RequestBody SamplesDataRequestHolderVO samplesDataRequestVO){
byte[] resource = null;
try(Workbook workbook = new XSSFWorkbook();
                ByteArrayOutputStream out = new ByteArrayOutputStream();){
// I have create and attached worksheet
workbook.write(out);
writeToFile(new ByteArrayInputStream(out.toByteArray()));
resource = out.toByteArray();
}


HttpHeaders headers = new HttpHeaders(); 
       headers.setContentType(MediaType.valueOf("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=CR Final.xlsx");

        return ResponseEntity.ok()
                .headers(headers)
                .body(resource);


}

我从 Spring Boot 中保存了文件,没关系。我尝试从 Postman 下载响应。它也很好,文件没有问题。但是当我尝试反应时,它总是被破坏。我在 ajax 中获取数据为

'PK.[.N[Content_Types].xml.TIn1'。

我比较了 ajax 和 Postman 中的响应数据,它们是相同的。如何调试?

【问题讨论】:

    标签: jquery reactjs spring-boot express request


    【解决方案1】:

    我通过在 Springboot 控制器中使用 Base64 编码字节数组并将响应正文作为编码字符串发送来使其工作。

    @RequestMapping(value = "/downloadCustomerReport", method = RequestMethod.POST)
        public ResponseEntity<String> downloadCustomerReport(@RequestBody SamplesDataRequestHolderVO samplesDataRequestVO) throws IOException {
            byte[] resource = null;
    try(Workbook workbook = new XSSFWorkbook();
                    ByteArrayOutputStream out = new ByteArrayOutputStream();){
    // I have create and attached worksheet
    workbook.write(out);
    writeToFile(new ByteArrayInputStream(out.toByteArray()));
    resource = out.toByteArray();
    }
            HttpHeaders headers = new HttpHeaders(); 
           headers.setContentType(MediaType.valueOf("application/octet-stream"));
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=CR Final.xlsx");
    String s = Base64.getEncoder().encodeToString(resource); // encoded my bytearray here
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(s);
        }
    

    然后在前端,我使用了 blob-util 库中的 base64StringToBlob 函数并将类型更改为 application/xlsx:

    var blob = base64StringToBlob(response.data, 'application/xlsx');
    

    【讨论】:

      【解决方案2】:

      尝试在您的请求中将 responseType 添加为“blob”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-03
        • 2011-10-16
        • 2017-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多