springboot使用文件流下载resource文件夹下的文件

目录结构如下:

springboot使用文件流下载resource文件夹下的文件_第1张图片
后端方法
FileEntity 内容为文件的一些相关信息,例如文件名等。
说明:模板文件为xlsx文件,因此设置response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");如果是其他类型的文件,需要更换为相关内容

   @PostMapping("/importTemplate")
    public void importTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody FileEntity fileEntity) throws Exception {

        String path="fileTemplates/"+fileEntity.getFileName();

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            ClassPathResource classPathResource = new ClassPathResource(path);
            if (!classPathResource.exists()) {
                throw new Exception("模板不存在");
            }
            File file = classPathResource.getFile();
            //获取路径
            String path1 = classPathResource.getPath();
            System.out.println("path:" + path1);
            System.out.println("file:" + file.length());
            //读取要下载的文件,保存到文件输入流
            inputStream = classPathResource.getInputStream();
            outputStream = response.getOutputStream();
//            response.setContentType("application/octet-stream");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");;
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" +fileEntity.getFileName().substring(0,fileEntity.getFileName().indexOf("."))+ ".xlsx");

            byte[] buff = new byte[2048];
            int i = 0;
            while ((i = inputStream.read(buff)) != -1) {
                outputStream.write(buff, 0, i);
                outputStream.flush();
            }
        } catch (Exception e) {
            throw new Exception("模板下载失败");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                throw new Exception("模板下载失败");
            }
        }


    }

通常情况下,到这一步已经可以完成模板文件的下载。
但是,本人的情况是虽然可以下载,但是下载后的文件无法打开。
以下是原因以及解决方案:
排除了一下原因,发现下载后 的模板文件大小与源文件不一致。
原因是打包后的target下的模板文件有问题,无法打开,并且文件大小与源文件不一致。
也就是说maven打包的过程中,只是将src/main/resources/目录下的文件变大了。因为我们在pom中开启了资源过滤。
解决办法:打包到classpath下,但是不进行资源过滤

<resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>*.xlsx</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>*.xlsx</include>
                </includes>
            </resource>
        </resources>

至此,问题解决~

vue前端内容:
请求内容注意使用responseType为 “blob”,


// 模板下载
export function importTemplate(data) {
  return request({
    url: '/ccr/project/file/importTemplate',
    method: 'post',
    responseType: "blob",
    data: data
  })
}

页面调用:

 let param={
        fileName  :"自挣卡损失兑现汇总模板.xlsx"
      }

      importTemplate(param).then(res => {
        const _exportFileUrl = window.URL.createObjectURL(
          new Blob([res], {
            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,charset=utf-8'
          })
        )
        const _link = document.createElement('a')
        const _curDate = moment(new Date()).format('YYYYMMDD')
        _link.download = `模板名称_${_curDate}`
        _link.href = _exportFileUrl
        _link.click()
        window.URL.revokeObjectURL(_exportFileUrl)

      })

你可能感兴趣的:(spring,boot,java,后端,vue)