springboot 实现下载文件出现文件受损无法打开

黑白
  • 136

问题描述

今天在做使用模板导出pdf的过程中遇到了模板导出成功但是下载的pdf无法打开,并且文件大小还变小了
image.png

尝试的解决方案

搜索了一些解决方案,有的说是springboot resource 文件夹下的模板文件被自动压缩,直接下载就会失败

参考

按照它的方式将 模板文件放行,也同样会出现文件受损无法打开

 <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.6</version>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>jasper</nonFilteredFileExtension>
                        <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
                        <nonFilteredFileExtension>xls</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>

相关代码

通过网络 下载代码 :

 @RequestMapping(value = "/paperManagement/fileDownload/paperCover", method = RequestMethod.GET)
    public void paperCoverDownLoad(HttpServletRequest request, HttpServletResponse response) {
        String jwt = request.getHeader("jwt");

       
        List<PaperCoverTemplate> result = fileDownLoadService.packPaperCoverData(1);
        Major major = majorService.getById(1);
        String fileName = DateUtil.year(new Date()) + "_DADFP_" + major.getCode() + ".pdf";
        ClassPathResource classPathResource = new ClassPathResource("template/pdf/PaperCover.jasper");

        InputStream source = null;
        ServletOutputStream target = null;

        try {
            target = response.getOutputStream();
            source = classPathResource.getInputStream();
            /*填充报表并转换到outPutStream流中*/
            response.setContentLength(source.available());
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

            JasperRunManager.runReportToPdfStream(source, target, new HashMap<>(16),
                new JRBeanCollectionDataSource(result));
        } catch (IOException | JRException e) {
            e.printStackTrace();
            throw new GlobalException(ResultCodeEnum.FAILED.getCode(), "论文封皮下载失败");
        } finally {

            try {
                if (source != null) {
                    source.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

文件大小变小了
image.png

无法正常打开
image.png

直接在本地下载

 @Test
    public void test1() {
        try {
            Map<String, Object> parameters = new HashMap<>(16);
            FileInputStream source =
                new FileInputStream("D:\\bylw\\src\\main\\resources\\template\\pdf\\PaperCover.jasper");
            List<PaperCoverTemplate> result = fileDownLoadService.packPaperCoverData(1);
            JRBeanCollectionDataSource beanDataSource = new JRBeanCollectionDataSource(result);
            File file = new File("C:\\Users\\x1522\\Desktop\\shape\\t.pdf");
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream target = new FileOutputStream(file);
            JasperRunManager.runReportToPdfStream(source, target, parameters, beanDataSource);

        } catch (FileNotFoundException | JRException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

image.png

能够正常打开
image.png

请问为啥下载的文件被压缩了,正常在本地下载为42kb, 但是通过网络下载就变成了 24kb,同样的下载方法在本地,在本地下载的文件比通过网络的大,这是为啥,请帮我解答一下,还有一般下载后文件受损的无法打开的原因有那些?

回复
阅读 571
2 个回答

可以先从文件大小入手,正常是42K,但是你浏览器下载到的是24k,所以你要判断一下在哪里被改变大小了。
而且你在生成pdf时没有报错,是否可以先认为是生成了正确的pdf,但是在返回给前段时被压缩了成了24K,这个可以看一下返回的请求头里有没有标记压缩算法。或者你设置长度时,source.available()是否是24k?

      /*填充报表并转换到outPutStream流中*/
      response.setContentLength(source.available());

我也遇到了这个问题。排除加接口的方式我感觉好麻烦,所以直接nginx.springboot 打包的时候把文件压缩了,所以变小了,下载下来的是压缩文件,所以无法打开。

宣传栏