SpringBoot打成jar包部署运行,Excel模板下载文件异常解决方案

问题一. 读取resource 目录下文件时出现路径找不到

在本机测试都很顺利,当打包jar文件放到服务器上测试的时候发现了类似下面的异常信息:

java.nio.file.NoSuchFileException: file:/app.jar!/BOOT-INF/classes!/xxx.xlsx

原因:SpringBoot 将项目打包为jar,使用 java - jar 包名 在服务器上运行。此时文件为打包文件,所以不能通过路径获取到文件。类似不能读取压缩包中的文件,必须先解压缩。结论:SpringBoot 中的文件只能通过流来进行读取

可以通过以下方法进行流的读取。

InputStream in = this.getClass().getClassLoader().getResourceAsStream("xxx.xlsx");

 

 

问题二. Excel模板下载文件损坏

在本机测试都很顺利,当打包jar文件放到服务器上时下载完文件提示文件损坏。

方案一:使用spring boot 静态资源下载的方式;这种方式下不需定义接口,权限等问题不可控;

将资源文件放到resource/static 目录下,启动服务,使用IP:端口/文件路径  下载即可;这种方案下,需要将pom文件下的resource.filtering要设置为false,打成jar之后,也是正常可用的;

 <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
                <filtering>false</filtering>    
            </resource>
            <resource>
                <directory>src/main/webapp</directory>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
            
        </resources>
    </build>

 

方案二:定义接口,使用文件输出流的方式下载,接口实现过程,使用POI的Workbook输出流;

毕竟POI是专业的,对于Excel文件处理有从根本上的理解;Excel模板文件根据.xls跟.xlsx类型,分别指定一下,使用XSSFWorkbook跟HSSFWorkbook即可,这里以XSSFWorkbook为例,其中资源文件放到resource目录下即可,非必须static目录:

@ApiOperation("下载学生信息导入模板")
    @GetMapping("/downloadTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        InputStream fis = null;
        try {
            fis = FileUtils.getResourcesFileInputStream("addStudentTemplate.xlsx");
            XSSFWorkbook workbook = new XSSFWorkbook(fis);

            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            String fileName = java.net.URLEncoder.encode("addStudentTemplate", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            ServletOutputStream out = null;
            out = response.getOutputStream();
            workbook.write(out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭文件输出流
            if(Objects.nonNull(fis)){
                try {
                    fis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return;
    }

 

前端使用 VUE+Axios的代码:

export function downloadAddStuTemplate() {
  return request({
    responseType: 'blob',
    method: 'get',
    url: '/student/downloadTemplate'
  })
}

 

downloadTemplate() {
      downloadAddStuTemplate().then(resp => {
        // 这里resp.data是返回的blob对象
        const blob = new Blob([resp.data],
          { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' })
        // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet这里表示xlsx类型
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob) // 创建下载的链接
        downloadElement.href = href
        downloadElement.download = '导入学生信息模板.xlsx' // 下载后文件名
        document.body.appendChild(downloadElement)
        downloadElement.click() // 点击下载
        document.body.removeChild(downloadElement) // 下载完成移除元素
        window.URL.revokeObjectURL(href) // 释放掉blob对象
      }).catch((r) => {
        console.log(r)
        this.$message.error('文件导出异常!')
      })
    },

 

前端VUE + Element UI 导入Excel数据代码:

<el-upload
          style="display: inline-block"
          class="upload-demo"
          action="http://haibao.imyjs.cn/api/student/uploadExcel"
          :headers="header"
          :on-success="uploadSuccess"
          :on-error="uploadError"
        >
          <el-tooltip effect="dark" content="只能上传.xlsx文件,且不超过15Mb" placement="top-start">
            <el-button type="danger" plain size="mini" round>导入Excel</el-button>
          </el-tooltip>
        </el-upload>

 

部分内容参考自:SpringBoot打成jar包部署

微信关注

                       编程那点事儿

 

阅读剩余
THE END