从S3下载时Excel文件损坏

维巴夫

目标:从UI(角度)服务上的S3存储桶下载文件

public byte[] downloadFileFromS3(String dfileName) {
        byte[] buffer = "Empty".getBytes();
        try {
            S3Object s3object = conn.getObject(bucketName, dfileName);
            S3ObjectInputStream inputStream = s3object.getObjectContent();
            buffer = new byte[(int) s3object.getObjectMetadata().getContentLength()];
            while (inputStream.read(buffer) > 0) {
                inputStream.read();
            }
        } catch (Exception e) {
            LOG.error("Exception occurred when accessing {} from S3 {}", dfileName, e.getMessage());
        }
        return buffer;
    }


控制者

@GetMapping("/download")
    public ResponseEntity<Resource> getFilefromS3(@RequestParam(name = "fileName") String fileName) {
        byte[] file = awsStorageHelper.downloadFileFromS3(fileName);
        return ResponseEntity.ok().header("Content-Type", MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
                .body(new ByteArrayResource(file));
    }

实现: spring应用程序部署在可以访问S3的EC2实例上。该应用程序将读取所需的文件,并将字节数组传递给angular应用程序。
问题:下载.docx或.txt之类的文件时,文件将按预期方式下载,但是如果下载.xlsx或.xls文件,则文件已损坏。如果压缩文件,则当.zip文件的内容为.docx或.txt时,下载.zip文件不会出现问题,但是如果.zip文件包含.xlsx或.xls文件,则.zip文件也会损坏。
这里到底出了什么问题,有没有更好的方法从S3下载文件?

维巴夫

解决方案:无需在控制器中将“输入流”转换为“字节数组作为资源”。
传递从S3服务方法接收的相同“输入流”,并在控制器中传递为“输入流作为资源”。
服务:

public InputStream downloadFileFromS3(String dfileName) {
        LOG.info("Downloading File {} ", dfileName);
        try {
            S3Object s3object = conn.getObject(bucketName, dfileName);
            return s3object.getObjectContent();
        } catch (Exception e) {
            throw new AeCoreException("Exception Occured Accessing File " + dfileName,
                    HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

控制器:

@GetMapping("/download")
    public ResponseEntity<InputStreamResource> getFilefromS3(@RequestParam(name = "fileName") String fileName) {
        InputStream file = awsStorageHelper.downloadFileFromS3(fileName);
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
                .body(new InputStreamResource(file));
    }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章