springboot读取resources目录下文件

2023-10-26

前言

最近的工作中遇到了复杂的excel报表导出业务,采用的是用excel模板来实现该业务(可以规避大量勾画excel格式的代码),将excel的模板放在项目的resources目录,遇到相关的一些问题及解决方案。

1.问题过程

resources目录下模板的位置:
在这里插入图片描述

在本地调试时直接用相对路径(templates/xxx.xlsx)就可以获取到对应的模板信息,调试自测过程都非常easy并愉快。
程序打包发到测试环境上,导出excel都是空模板没有任何数据,查看日志发现是在读取resources目录下的模板报错空指针,关键报错日志如下:

java.io.FileNotFoundException: class path resource [templates/scenery.xlsx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/xxx.jar!/BOOT-INF/classes!/templates/xxx.xlsx

从报错信息可以看出来打包(jar)模板的位置和打包之前位置已经不一样了,jar里面也是没有src这个目录,则相对路径去读取模板当然是拿不到的。

2. 解决方案

2.1 文件上传

将resources目录的文件上传到服务器上,不从resources目录下读取模板,有2种方式:

  1. 将文件上传到文件服务(如阿里云OSS),并获取到文件地址,通过流方式读取文件。这种方式需要额外的成本(文件服务器)。
  2. 在jar运行的服务器上创建目录并存放文件,然后程序里读取相对路径。这种方式不太推荐,不可控因素太多(如被误删、服务搬迁等)。

2.2 ClassPathResource

用ClassPathResource读取到resources目录下文件的流,具体代码如下:

            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                    <include>**/*.yml</include>
                </includes>
                <!--是否替换资源中的属性-->
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
                <!--是否替换资源中的属性-->
                <filtering>false</filtering>
            </resource>
            ClassPathResource resource = new ClassPathResource("templates/xxx.xlsx");
            InputStream inputStream = resource.getInputStream();

但是我excel导出是用的easyPOI,模板导出不支持流,必须得是文件的路径,具体实现的代码如下:

/**
     * 模板报表导出
     * @param type http
     * @param data 报表信息
     */
    public static void templateExcelExport(Map<String, Object> data, String type, HttpServletResponse httpServletResponse) throws IOException {
        //获取模板的位置
        ReportExcelEnum reportExcelEnum = ReportExcelEnum.valueOf(type);
        //获取项目的根目录
        String rootPath = System.getProperty("user.dir");
        //创建临时的模板存放文件
        String path = rootPath +"/" + reportExcelEnum.getValue();
        log.info("存放模板目录及模板文件::"+path);
        //判断模板是否已存放在文件中
        File file = new File(path);
        if(!file.exists()){
            log.info("不存在则创建文件:"+path);
            ClassPathResource resource = new ClassPathResource(reportExcelEnum.getValue());
            InputStream inputStream = resource.getInputStream();
            saveTempFile(inputStream,file);
            log.info("模板创建成功!");
        }
        //获取模板
        TemplateExportParams params = new TemplateExportParams(path);
        //获取到 Workbook
        Workbook workbook = ExcelExportUtil.exportExcel(params, data);
        //文件名
        String fileName = reportExcelEnum.getName() + DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDateTime.now()) + ".xlsx";
        //导出报表
        export(httpServletResponse, workbook, fileName);
    }


    private static void saveTempFile(InputStream inputStream, File tempFile) throws IOException {
        //如果文件的目录不存在
        if(!tempFile.getParentFile().exists()){
            //创建父目录
            tempFile.getParentFile().mkdirs();
        }
        OutputStream os = new FileOutputStream(tempFile);
        byte[] b = new byte[2048];
        int length;
        while ((length = inputStream.read(b)) > 0) {
            os.write(b, 0, length);
        }
        os.flush();
        os.close();
        inputStream.close();
    }

总结

本篇记录一下读取resources目录下文件问题和解决方案,希望能帮到你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot读取resources目录下文件 的相关文章

随机推荐

  • 【matlab】:matlab中如何三维画球?

    首先介绍一个函数ellipsoid 这个函数是在三维立体空间画椭圆用的 这个函数参数如下 ellipsoid x y z x1 y1 z1 x y z代表了椭球的中心 x1 y1 z1代表了x y z方向的分量 然后如果是要画球的话 把这三
  • HTML5+CSS3小实例:简单又好看的加载动画效果

    HTML5 CSS3做一个简单又好看的加载动画效果 一个三色圆环转动 再加圆环内部文字转动 效果虽然简单 但第一次看到还是很惊艳的 最主要一点 代码真的超简单的 效果 源码
  • 曲线拟合

    问题解决 给你一个二维的序列 你如何用多项式进行曲线拟合 一阶直线拟合 二阶抛物线拟合 并非阶次越高越好 看拟合情况而定 曲线拟合 clear clc syms s 声明一个符号变量 详细参考 https jingyan baidu com
  • PicoDet代码学习记录

    推理步骤 picodet s 320 coco yml Infer py main gt run Trainer py init self model create cfg architecture Picodet py from conf
  • Ubuntu20.04 中已经安装 Pytorch 但 Import 报错 - 解决记录

    01 问题描述 笔者使用的是 Ubuntu 20 04 3 LTS 在使用 PyTorch 训练模型的时候 torch 模块引用失败 报错信息是 OSError home wang local lib python3 8 site pack
  • CUDA学习笔记——cudaDeviceSynchronize()的理解

    内核是操作系统提供软件对计算机硬件进行访问的软件 内核启动是异步的 这意味着在内核完成执行之前 他将在启动gpu进程后立即将控制权返回给cpu线程 而cpu线程的下一步是应用程序的退出 在应用程序退出时 其将输出发送到标准输出的功能由操作系
  • 会议论文和期刊论文在写作上有什么区别?有什么侧重点?

    作为一名科研工作者 无论你是初入圈内的 小萌新 还是久经沙场的 老将 写论文都是我们的必经之路 而要想论文投中 就需要我们的积极努力啦 其中 杂志社以及很多大型学术会议的征稿就是很好的一个途径哦 不过这两者的论文要求是否一致呢 又是否匹配我
  • cocos2d之Box2D详解 鼠标关节实现

    cocos2d之Box2D详解 鼠标关节实现 DionysosLai2014 5 7 我们经常要移动物理世界中的某个物体 比方说石头 木块等 如果我们直接改变这些物体的位置 让这些物体跟随我们手指移动 即使这样是可行的 却违反了物理世界的基
  • Ubuntu16.04下安装Android机顶盒(Android4.4.2)NDK交叉编译环境

    Ubuntu16 04下安装Android机顶盒 Android4 4 2 NDK交叉编译环境 文章目录 Ubuntu16 04下安装Android机顶盒 Android4 4 2 NDK交叉编译环境 一 前言 二 ndk下载 三 ndk安
  • 拦截器响应头中配置“Access-Control-Expose-Headers”实现跨域请求暴露token

    问题场景 和前端同事联调接口中 前端同事反映说在跨域请求的情况下无法获取token的值 后来找到解决办法 解决 1 在登录拦截器处理类中的响应对象 把token对象暴露出来即可 2 关键代码 response setHeader Acces
  • Java设计模式之单例模式_Demo

    单例模式 初识 单例模式 Singleton Pattern 是 Java 中最简单的设计模式之一 这种类型的设计模式属于创建型模式 它提供了一种创建对象的最佳方式 这种模式涉及到一个单一的类 该类负责创建自己的对象 同时确保只有单个对象被
  • LaTeX学习笔记

    在编辑公式的时候 可能会用到这个命令 begin array lcl end array 其中 lcl 表示左对齐 如果将 lcl 替换为 c 即 begin array c end array 则表示居中对齐 科研文献中常常需要使用eps
  • 文心一言更大的故事是在云计算

    3月16日 百度发布新一代大语言模型 生成式AI产品文心一言 展示了文心一言在文学创作 商业文案创作 数理推算 中文理解 多模态生成五大场景中的综合能力 生成式AI为科技创新带来无限想象 文心一言依托 百度AI大底座 而落地 由百度智能云对
  • ubutu下ros2实现小车仿真建模与目标检测

    1 安装ros2 这里使用小鱼的一键安装 根据自己的喜好安装 博主用的是ros2的foxy版本 wget http fishros com install O fishros fishros 2 下载代码 这里使用的是古月居的代码 http
  • 用Requests和正则表达式爬取豆瓣图书TOP250

    思路和上文大同小异 import requests from requests exceptions import RequestException import re import json headers User Agent Mozi
  • vue props设置默认值的基本方式

    vue官方文档解释 为该 prop 指定一个默认值 如果该 prop 没有被传入 则换做用这个值 对象或数组的默认值必须从一个工厂函数返回 默认值为字符串 props fieldString type String default 默认值为
  • Python如何绘制误差直方图?曲线的阴影图?shade range graph

    问题抽象 Python如何绘制曲线的阴影图 建议的方案 flights sns load dataset flights flights head sns lineplot data flights x year y passengers
  • 基于stm32蓝牙接收信息并显示在OLED上

    两个单片机基于蓝牙连接通信 可以使能串口 把蓝牙当作串口来使用 例如 蓝牙通过串口发送信息 蓝牙通过串口接收信息 这样就可以使两个单片机进行通信 下面代码是基于STM32蓝牙接收另外一块单片机蓝牙发送过来的温湿度信息 并显示在OLED上 主
  • Squid代理的用户认证(基本认证、集成Windows域认证)

    Squid代理的用户认证 基本认证 集成Windows域认证 2012 07 02 TsengYia 126 com 关于Squid代理服务的用户验证 本文简要介绍了两种方法的实现 basic基本认证 ntlm域认证 basic认证采用账户
  • springboot读取resources目录下文件

    文章目录 前言 1 问题过程 2 解决方案 2 1 文件上传 2 2 ClassPathResource 总结 前言 最近的工作中遇到了复杂的excel报表导出业务 采用的是用excel模板来实现该业务 可以规避大量勾画excel格式的代码