首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Java Spring/React下载XLSX文件?

如何用Java Spring/React下载XLSX文件?
EN

Stack Overflow用户
提问于 2019-11-27 07:33:53
回答 1查看 1.3K关注 0票数 0

我正在尝试生成.XLSX文件并下载它。我使用Apache POI生成excel文件,并使用Swagger UI测试端点。我已经找了几个小时了,但一无所获。我用来生成Excel文件的代码是:

代码语言:javascript
复制
@GetMapping(path = "/download")
public ResponseEntity<ByteArrayResource> download(@RequestParam(name = "ids") long [] ids) {
    // ... other code ...
    XSSFWorkbook workbook = createWorkbook(reports);

    LocalDate date = LocalDate.now();

    String filename = "MYC " + date.getYear() + "." + date.getMonthValue();

    try {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        HttpHeaders header = new HttpHeaders();
        header.setContentType(new MediaType("application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        header.set(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s.xlsx", filename));
        workbook.write(stream);
        workbook.close();
        return new ResponseEntity<>(new ByteArrayResource(stream.toByteArray()), header, HttpStatus.CREATED);
    } catch (Exception e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

在使用Swagger UI进行测试时,我进行调用并得到以下结果:

我在上找到的一个答案建议使用force-download而不是vnd.openxmlformats-officedocument.spreadsheetml.sheet,所以我继续尝试。这一次,Swagger UI实际上生成了一个Download file链接。我可以点击它,文件就可以很好地下载了。但是使用force-download真的是一种合适的方法吗?

现在,我尝试在我的前端下载,无论我使用的是force-download还是vnd.openxmlformats-officedocument.spreadsheetml.sheet,我都只能得到一个“损坏”的.xlsx文件。

我在写自己的文章的时候发现了this的问题,这个人似乎也收到了同样类型的回复。他通过将他的二进制数据转换为字符串来修复它。我不确定这是否也是我应该做的,以及我将如何去做。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-03 07:35:23

好的,所以我通过从多个谷歌搜索中收集信息来解决这个问题。对于我的后端,我将byte array编码为Base64,然后将其作为String返回。

代码语言:javascript
复制
@GetMapping(path = "/download")
public ResponseEntity<String> download(@RequestParam(name = "ids") long[] ids) {
    // ... other code ...
    XSSFWorkbook workbook = createWorkbook(reports);

    try {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType("text", "plain");
        workbook.write(outputStream);
        workbook.close();
        return new ResponseEntity<>(Base64.getEncoder().encodeToString(outputStream.toByteArray(), headers, HttpStatus.OK);
    } catch (IOException e) {
        return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

在前端,我使用atob()解码了String,然后将其解码为ArrayBuffer

代码语言:javascript
复制
// ... other code ...
actions.getSpreadsheet(ids)
    .then(result => {
        var date = new Date();
        var filename = "JSC " +
            date.getFullYear() +
            "." +
            (date.getMonth() + 1);

        var url = window.URL.createObjectURL(new Blob([this.s2ab(atob(result.data))], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' }));
        var a = document.createElement('a');
        a.href = url;
        a.download = filename + '.xlsx';
        document.body.appendChild(a);
        a.click();
        a.remove();
    }).catch(error => {
        alert('Error retrieving report: ' + error);
    })

s2ab = s => {
    var buf = new ArrayBuffer(s.length);
    var view = new Unit8Array(buf);
    for (var i = 0; i != s.length; i++) {
        view[i] = s.charCodeAt(i) & 0xFF;
    }
    return buf;
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59060936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档