代码之家  ›  专栏  ›  技术社区  ›  ankur bansal

使用Java/JavaScript和Apache POI在导出.xLS文件时获取损坏的文件

  •  1
  • ankur bansal  · 技术社区  · 7 年前

    我正在尝试从Web应用程序下载浏览器中的.xls文件。下面是相同的代码。

    try(FileInputStream inputStream = new FileInputStream("C:\\Users\\Desktop\\Book1.xls")){
                response.setContentType("application/vnd.ms-excel");
                //response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                response.setHeader("Content-Disposition", "attachment; filename=Book1.xls");
                outputStream = response.getOutputStream();
                byte[] buffer = new byte[BUFFERSIZE];
                int bytesRead = -1;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
    

    下面是用于下载文件内容的javascript代码。

    success: function(response, status, xhr) {
    
                    let type = xhr.getResponseHeader('Content-Type');
                    let blob = new Blob([response], { type: type });
    
                    if (typeof window.navigator.msSaveBlob !== 'undefined') {
                        // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created.
                        //These URLs will no longer resolve as the data backing the URL has been freed."
                        window.navigator.msSaveBlob(blob, filename);
                    } else {
                        let URL = window.URL || window.webkitURL;
                        let downloadUrl = URL.createObjectURL(blob);
                        if (filename) {
                            // use HTML5 a[download] attribute to specify filename
                            let a = document.createElement("a");
                            // safari doesn't support this yet
                            if (typeof a.download === 'undefined') {
                                window.location = downloadUrl;
                            } else {
                                a.href = downloadUrl;
                                a.download = filename;
                                document.body.appendChild(a);
                                a.click();
                            }
                        } else {
                            window.location = downloadUrl;
                        }
                        setTimeout(function () {
                            URL.revokeObjectURL(downloadUrl);
                        }, 100); // cleanup
                    }
                }
    

    我可以下载文件,但下载的文件内容不是可读格式。如果是csv文件,我可以看到我的javascript响应对象中的内容,.xls文件javascript响应对象包含不可读的格式化数据。

    有人能帮我吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   ankur bansal    7 年前

    发布这个解决方案如果其他人也面临同样的问题,我通过base64将字节数组编码为字符串来解决这个问题,如下所示。

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
     workbook.write(outputStream);
     String res = Base64.getEncoder().encodeToString(outputStream.toByteArray());
    

    在javascript中,我使用base64toblob方法从下面的链接解码了该字符串

    https://stackoverflow.com/a/20151856/2011294

    function base64toBlob(base64Data, contentType) {
        contentType = contentType || '';
        var sliceSize = 1024;
        var byteCharacters = atob(base64Data);
        var bytesLength = byteCharacters.length;
        var slicesCount = Math.ceil(bytesLength / sliceSize);
        var byteArrays = new Array(slicesCount);
    
        for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
            var begin = sliceIndex * sliceSize;
            var end = Math.min(begin + sliceSize, bytesLength);
    
            var bytes = new Array(end - begin);
            for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
                bytes[i] = byteCharacters[offset].charCodeAt(0);
            }
            byteArrays[sliceIndex] = new Uint8Array(bytes);
        }
        return new Blob(byteArrays, { type: contentType });
    }
    
    推荐文章