股票数据报表与导出
股票数据报表与导出
目标
- 🎯任务7:理解涨幅榜业务需求🍐✏️
- 理解涨停跌停概念,并涨停跌停基本实现;
- 理解涨停跌停SQL分析流程,并根据接⼝⽂档⾃定义实现;
- 理解echartJs数据格式✏️🚀
- 🎯任务8:掌握easyExcel基本使⽤,并实现涨幅榜数据导出功能🍐✏️
- 掌握easyExcel基本使⽤(基本导出、高级设置)
- 实现涨幅榜数据导出
1. 股票涨幅统计
此任务是导出Excel任务的基础
1.1 涨幅榜更多数据功能实现 🎯涨幅榜更多数据功能实现

- 功能描述:分⻚查询PageHelper插件
最新
股票交易时间点下沪深两市
个股⾏情数据,并根据涨幅降序
排序展示 - 服务路径:
/api/quot/stock/all
- 服务⽅法:
GET
- 请求参数:
响应数据格式:
{
"code": 1,
"data": {
"totalRows": 46750,//总⾏数
"totalPages": 4675,//总⻚数
"pageNum": 2,//当前⻚
"pageSize": 10,//每⻚⼤⼩
"size": 10,//当前⻚⼤⼩
"rows": [
{
"tradeAmt": 4594802,//交易量
"preClosePrice": 18.78,//前收盘价
"amplitude": 0.059638,//振幅
"code": "000004",//股票编码
"name": "国华⽹安",//股票名称
"curDate": "2021-12-30 10:20",//当前⽇期
"tradeVol": 4594802,//交易⾦额
"increase": 0.039936,//涨跌
"upDown": 0.75,//涨幅
"tradePrice": 19.53//当前价格
},
//省略......
]
}
}
- 相关参数:
- 涨跌:当前价-前收盘价
- 涨幅:(当前价-前收盘价)/ 前收盘价 *100%
- 振幅:(最⾼成交价-最低成交价)/ 前收盘价 * 100%
代码操作
- 实体类封装
- 查询记录实体封装
在stock_common⼯程下封装查询⾏记录数据:StockUpdownDomain.java
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel("个股涨幅榜数据封装对象")
public class StockUpdownDomain {
@ApiModelProperty("股票编码")
@ExcelProperty(value = {"股票涨幅信息统计表","股票编码"},index = 0)
private String code;
@ApiModelProperty("股票名称")
@ExcelProperty(value = {"股票涨幅信息统计表","股票名称"},index = 1)
private String name;
@ApiModelProperty("前收盘价格")
@ExcelProperty(value = {"股票涨幅信息统计表","前收盘价格"},index = 2)
private BigDecimal preClosePrice;
@ApiModelProperty("当前价格")
@ExcelProperty(value = {"股票涨幅信息统计表","当前价格"},index = 3)
private BigDecimal tradePrice;
@ApiModelProperty("涨跌值")
@ExcelProperty(value = {"股票涨幅信息统计表","涨跌值"},index = 4)
private BigDecimal increase;
@ApiModelProperty("涨幅")
@ExcelProperty(value = {"股票涨幅信息统计表","涨幅"},index = 5)
private BigDecimal upDown;
@ApiModelProperty("振幅")
@ExcelProperty(value = {"股票涨幅信息统计表","振幅"},index = 6)
private BigDecimal amplitude;
@ApiModelProperty("交易量")
@ExcelProperty(value = {"股票涨幅信息统计表","交易量"},index = 7)
private Long tradeAmt;
@ApiModelProperty("交易金额")
@ExcelProperty(value = {"股票涨幅信息统计表","交易金额"},index = 8)
private BigDecimal tradeVol;
/**
* 日期
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")//springmvc的注解-》json格式数据
@ApiModelProperty("交易时间")
@DateTimeFormat("yyyy-MM-dd HH:mm")
@ExcelProperty(value = {"股票涨幅信息统计表","交易时间"},index = 9)
private Date curDate;
}
- 封装分⻚实体类
分⻚实体类是前端响应对象,我们维护到stock_backend⼯程下即可;
分⻚实体对象的数据来⾃分⻚PageInfo对象,所以我们在构造器中传⼊PageInfo直接转化即可:PageResult.java
分⻚实体类维护到stock_backend下vo/resp下即可------>直接导⼊:day03\资料\后端资料\PageResult.java;
/**
* 分页工具类
*/
@Data
public class PageResult<T> implements Serializable {
/**
* 总记录数
*/
private Long totalRows;
/**
* 总页数
*/
private Integer totalPages;
/**
* 当前第几页
*/
private Integer pageNum;
/**
* 每页记录数
*/
private Integer pageSize;
/**
* 当前页记录数
*/
private Integer size;
/**
* 结果集
*/
private List<T> rows;
/**
* 分页数据组装
* @param pageInfo
* @return
*/
public PageResult(PageInfo<T> pageInfo) {
totalRows = pageInfo.getTotal();
totalPages = pageInfo.getPages();
pageNum = pageInfo.getPageNum();
pageSize = pageInfo.getPageSize();
size = pageInfo.getSize();
rows = pageInfo.getList();
}
}
- 涨幅榜更多SQL分析
⽅式1:全表数据根据时间和涨幅降序排序
# 分析:统计国内A股股票的最新数据,根据涨幅排序取前4
# ⽅式1:根据⽇期和涨幅降序排序取前4即可
select
sri.trade_amount as tradeAmt,
sri.pre_close_price as preClosePrice,
(sri.max_price- sri.min_price)/sri.pre_close_price as amplitude,
sri.stock_code as code,
sri.stock_name as name,
sri.cur_time as curDate,
sri.trade_volume as tradeVol,
(sri.cur_price-sri.pre_close_price) as upDown,
(sri.cur_price- sri.pre_close_price)/sri.pre_close_price as increase,
sri.cur_price as tradePrice
from stock_rt_info as sri
order by sri.cur_time desc,upDown desc
存在问题: 存在的问题:全表排序查询开下太⼤,不适合⼤数据量的查询;
⽅式2:先根据最新股票交易时间点⾛索引查询,然后再根据涨幅排序
参考答案点击这里查看(需要密码)👈part3_涨幅榜更多SQL分析.txt
- 定义服务访问接⼝⽅法
@ApiOperation("分页降序查询最新的个股涨幅排数据")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "当前页", required = false, dataType = "Integer", paramType = "query"),
@ApiImplicitParam(name = "pageSize", value = "每页大小", required = false, dataType = "Integer", paramType = "query")
})
@GetMapping("/stock/all")
public R<PageResult<StockUpdownDomain>> getPageStockInfos(
@RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
@RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize) {
return stockService.getPageStockInfos(page, pageSize);
}
- 定义服务接⼝⽅法和实现 1.1 StockService接口方法
/**
* 分页降序查询最新的个股涨幅排数据
* @param page 当前页
* @param pageSize 每页大小
* @return
*/
R<PageResult<StockUpdownDomain>> getPageStockInfos(Integer page, Integer pageSize);
1.2 StockServiceImpl实现类代码
@Autowired
private StockInfoConfig stockInfoConfig;
@Autowired
private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
/**
* 分页降序查询最新的个股涨幅排数据
* @param page 当前页
* @param pageSize 每页大小
* @return
*/
@Override
public R<PageResult<StockUpdownDomain>> getPageStockInfos(Integer page, Integer pageSize) {
//1.获取最新的股票交易时间
//TODO 伪造数据,后续删除
//2.设置分页参数
//3.调用mapper查询数据
//判断数据是否为空
//4.组装数据
//转化成PageInfo对象
//PageInfo<StockUpdownDomain> pageInfo = new PageInfo<>(infos);
//4.响应数据
先自己敲.......
return R.ok(pageResult);
}
- 定义mapper接⼝⽅法和xml
- 在StockMarketIndexInfoMapper接⼝下定义
List<InnerMarketDomain> getInnerIndexByTimeAndCodes(@Param("dateTime") Date dateTime,@Param("innerCodes") List<String> innerCodes);
- 在StockMarketIndexInfoMapper.xml下定义绑定sql
先自己敲.....
参考答案点击这里查看(需要密码)👈part3_涨幅榜更多功能业务代码实现.txt
当做作业,做完其他任务在做
1.2 涨幅榜功能实现🎯涨幅榜功能实现
- 原型需求

- 表结构
- 功能描述:统计沪深两市个股最新交易数据,并按
涨幅降序
排序查询前4条数据
- 服务路径:
/api/quot/stock/increase
- 前端请求频率:
每分钟
- 服务⽅法:
GET
- 请求参数:无 响应数据格式:
{
"code": 1,
"data": [
{
"code": "000004",//股票编码
"name": "国华⽹安",//股票名称
"preClosePrice": 18.78,//前收盘价
"tradePrice": 19.53//当前价格
"tradeAmt": 4594802,//交易量
"tradeVol": 4594802,//交易⾦额
"increase": 0.039936,//涨跌
"upDown": 0.75,//涨幅
"amplitude": 0.059638,//振幅
"curDate": "2021-12-30 10:30",//当前⽇期
},
//省略......
]
}
参考答案点击这里查看(需要密码)👈part3_涨幅榜(前10条)代码实现.txt
当做作业,难度大,最后做
1.3 涨停跌停数据统计功能 🎯涨停跌停数据统计功能

- 说明:
- A股市场有涨幅±10%限制;
- 股票是否涨停和跌停并不以我们的统计结果为基准,⽽是由证券交易所来确定,可能真实情况是涨幅超过10%或者低于-10%;
涨停跌停接⼝说明
- 功能描述:统计
沪深两市T⽇
(当前股票交易⽇)每分钟
达到涨跌停
股票的数据
注意:如果不在股票的交易⽇内,则统计最近的股票交易⽇下的数据
- 服务路径:
/api/quot/stock/updown/count
- 服务⽅法:
GET
- 请求参数:无
响应数据格式:
{
"code": 1,
"data": {
"upList": [
{
"count": 1,//涨停数量
"time": "202112311412"//当天分时
},
{
"count": 3,//涨停数量
"time": "202112311413"//当天分时
},
//省略......
],
"downList": [
{
"count": 2,//跌停数量
"time": "202112310925"//当天分时
},
//省略......
]
}
}
- 总之,业务要求获取最新交易⽇下每分钟达到涨跌停数股票的数量
- 关于SQL⽇期函数,详⻅:今⽇指数资料\V3\day03-股票数据报表与导出\资料\预习基础知识点[SQL⽇期函数.md](./SQLDateFunction.md) 点击查看
代码操作
- 查询数据组装思路
- 涨跌停数据包含了涨停统计数据和跌停统计数据,⽽每个数据组中的元素⼜仅仅包含时间和数量,这些数据是⾼度聚合得出的结果,所以我们可以把每组数据封装到map下,数据类型为:
Map<String,List>
- 涨停统计SQL和跌停统计的SQL除了条件外,结构是⼀致的,我们可定义⼀个flag标识,mapper中传⼊时,0代表涨停,1代表跌停;
- SQL分析思路
# 1.以统计当前股票交易⽇下,每分钟对应的涨停数量为例
# 思考:涨停与涨幅有关,但是我们的股票流⽔表中没有涨幅的数据,需要⾃⼰去就是那
# 1.先统计指定⽇期下(开盘时间点到最新时间点)涨幅达到涨停的数据
# 查询后的条件过滤,使⽤关键字:having
select
(sri.cur_price-sri.pre_close_price)/sri.pre_close_price as ud,
sri.cur_time as time
from stock_rt_info sri
where sri.cur_time BETWEEN '2022-01-06 09:30:00' and '2022-
01-06 14:25:00'
having ud>=0.1;
# 2.将上述结果作为⼀张表,然后根据time时间分组,统计出每分钟对应的数量,⽽这个数量就是涨停的数量
select
tmp.time,
count(*) as count
from () as tmp
group by tmp.time;
# 填充sql
select
tmp.time,
count(*) as count
from (select
(sri.cur_price-sri.pre_close_price)/sri.pre_close_price as ud,
sri.cur_time as time
from stock_rt_info sri
where sri.cur_time BETWEEN '2022-01-06 09:30:00' and '2022-01-06 14:25:00'
having ud>=0.1) as tmp
group by tmp.time
order by tmp.time asc;
# 跌停
select
date_format(tmp.time,'%Y%m%d%H%i') as time ,
count(*) as count
from
(select
(sri.cur_price-sri.pre_close_price)/sri.pre_close_price as ud,
sri.cur_time as time
from stock_rt_info sri
where sri.cur_time BETWEEN '2022-01-06 09:30:00' and '2022-01-06 14:25:00'
having ud<=-0.1) as tmp
group by tmp.time
order by tmp.time asc;
⽅式2:先根据最新股票交易时间点⾛索引查询,然后再根据涨幅排序
参考答案点击这里查看(需要密码)👈part3_涨停跌停数据统计功能sql分析.txt
- 定义服务访问接⼝⽅法
- 定义服务接⼝⽅法和实现
- 2.1 接口方法
- 2.2 实现类代码
- 定义mapper接⼝⽅法和xml
- 3.1 在Mapper接⼝下定义
- 3.2. 在Mapper.xml下定义绑定sql
参考答案点击这里查看(需要密码)👈part3_涨停跌停数据统计功能代码实现.txt
- web接口测试
接口链接:
- 接口测试效果

2. EasyExcel入门 🎯
EasyExcel入门
传统操作Excel⼤多都是利⽤Apach POI进⾏操作的,但是POI框架并不完善,使⽤过程⾮常繁琐且有较多的缺陷:
动态操作Excel⾮常繁琐,对于新⼿来说,很难在短时间内上⼿;
读写时需要占⽤较⼤的内存,当数据量⼤时容易发⽣内存溢出问题(OOM);
基于上述原因,阿⾥开源出⼀款易于上⼿,且⽐较节省内存的Excel框架:EasyExcel 官⽹地址:https://www.yuque.com/easyexcel/doc/easyexcel
<!--引⼊easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.4</version>
</dependency>
注意:
easyExcel底层也是使⽤POI实现的;
⽬前版本与JDK8较为契合,⾼版本的JDK可能会出现兼容性问题

代码实操
步骤
- EasyExcel导出数据快速⼊⻔
- EasyExcel导出数据⾼级设置
- 构建测试实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements Serializable {
private String userName;
private Integer age;
private String address;
private Date birthday;
}
- 数据导出到excel
public class TestEasyExcel {
public List<User> init(){
//组装数据
ArrayList<User> users = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setAddress("上海"+i);
user.setUserName("张三"+i);
user.setBirthday(new Date());
user.setAge(10+i);
users.add(user);
}
return users;
}
/**
* 直接导出后,表头名称默认是实体类中的属性名称
*/
@Test
public void test02(){
List<User> users = init();
//不做任何注解处理时,表头名称与实体类属性名称⼀致
EasyExcel.write("C:\\Users\\46035\\Desktop\\ex\\⽤户.xls",User.class).sheet("⽤户信息").doWrite(users);
}
}

- ⾃定义表头
修改User实体类,设置表头数据和排序规则
/**
* 通过注解⾃定义表头名称 注解添加排序规则,值越⼤ 越靠近右边
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements Serializable {
@ExcelProperty(value = {"⽤户名"},index = 1)
private String userName;
@ExcelProperty(value = {"年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"⽣⽇"},index = 3)
private Date birthday;
}

- ⾃定义⽇期格式
/**
* 通过注解⾃定义表头名称 注解添加排序规则,值越⼤ 越靠近右边
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements Serializable {
@ExcelProperty(value = {"⽤户名"},index = 1)
private String userName;
@ExcelProperty(value = {"年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"⽣⽇"},index = 3)
//注意:⽇期格式注解由alibaba.excel提供
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date birthday;
}

- 合并表头
/**
* 通过注解⾃定义表头名称 注解添加排序规则,值越⼤ 越靠近右边
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements Serializable {
@ExcelProperty(value = {"⽤户基本信息","⽤户名"},index = 1)
private String userName;
@ExcelProperty(value = {"⽤户基本信息","年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"⽤户基本信息","地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"⽤户基本信息","⽣⽇"},index = 3)
//注意:⽇期格式注解由alibaba.excel提供
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date birthday;
}

- 忽略指定表头信息
/**
* 通过注解⾃定义表头名称 注解添加排序规则,值越⼤ 越靠近右边
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements Serializable {
@ExcelProperty(value = {"⽤户基本信息","⽤户名"},index = 1)
@ExcelIgnore
private String userName;
@ExcelProperty(value = {"⽤户基本信息","年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"⽤户基本信息","地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"⽤户基本信息","⽣⽇"},index = 3)
//注意:⽇期格式注解由alibaba.excel提供
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date birthday;
}

- 设置单元格⼤⼩
/**
* 通过注解⾃定义表头名称 注解添加排序规则,值越⼤ 越靠近右边
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@HeadRowHeight(value = 35) // 表头⾏⾼
@ContentRowHeight(value = 25) // 内容⾏⾼
@ColumnWidth(value = 50) // 列宽
public class User implements Serializable {
@ExcelProperty(value = {"⽤户基本信息","⽤户名"},index = 1)
@ExcelIgnore
private String userName;
@ExcelProperty(value = {"⽤户基本信息","年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"⽤户基本信息","地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"⽤户基本信息","⽣⽇"},index = 3)
//注意:⽇期格式注解由alibaba.excel提供
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date birthday;
}

/**
* excel数据格式必须与实体类定义⼀致,否则数据读取不到
*/
@Test
public void readExcel(){
ArrayList<User> users = new ArrayList<>();
//读取数据
EasyExcel.read("C:\\Users\\46035\\Desktop\\ex\\⽤户.xls", User.class, new AnalysisEventListener<User>() {
@Override
public void invoke(User o, AnalysisContext analysisContext) {
System.out.println(o);
users.add(o);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("完成。。。。");
}
}).sheet().doRead();
System.out.println(users);
}
4. 股票涨幅数据导出 🎯
股票涨幅数据导出
通过点击【导出数据】按钮,将当前⻚的数据导出到excel下:

- 功能说明:将
分⻚
涨幅榜下指定⻚码的数据导出到excel表格下 - 请求地址:
/api/quot/stock/export
- 请求⽅式:
GET
- 请求参数:
- 响应:
excel格式的⽂件流
代码操作
- 在stock_common⼯程下引⼊easyExcel依赖:
<!--引⼊easyExcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
- 调整StockUpdownDomain实体类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class StockUpdownDomain {
@ExcelProperty(value = {"股票涨幅信息统计表","股票编码"},index = 0)
private String code;
@ExcelProperty(value = {"股票涨幅信息统计表","股票名称"},index = 1)
private String name;
@ExcelProperty(value = {"股票涨幅信息统计表","前收盘价格"},index = 2)
private BigDecimal preClosePrice;
@ExcelProperty(value = {"股票涨幅信息统计表","当前价格"},index= 3)
private BigDecimal tradePrice;
@ExcelProperty(value = {"股票涨幅信息统计表","涨跌"},index= 4)
private BigDecimal increase;
@ExcelProperty(value = {"股票涨幅信息统计表","涨幅"},index= 5)
private BigDecimal upDown;
@ExcelProperty(value = {"股票涨幅信息统计表","振幅"},index= 6)
private BigDecimal amplitude;
@ExcelProperty(value = {"股票涨幅信息统计表","交易总量"},index = 7)
private Long tradeAmt;
@ExcelProperty(value = {"股票涨幅信息统计表","交易总⾦额"},index = 8)
private BigDecimal tradeVol;
@ExcelProperty(value = {"股票涨幅信息统计表","⽇期"},index = 9)
@DateTimeFormat("yyy-MM-dd HH:mm")//easyExcel的注解-》excel
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")//springmvc⽀持的注解-》json格式数据
private Date curDate
详⻅:day03\资料\后端资料\easyExcel修饰\StockUpdownDomain.java
- 定义web访问⽅法
/**
* 将指定⻚的股票数据导出到excel表下
* @param response
* @param page 当前⻚
* @param pageSize 每⻚⼤⼩
*/
@GetMapping("/stock/export")
public void stockExport(HttpServletResponse response,Integer page,Integer pageSize){
stockService.stockExport(response,page,pageSize);
}
定义服务接⼝及实现
- 接⼝定义:
/** * 将指定⻚的股票数据导出到excel表下 * @param response * @param page 当前⻚ * @param pageSize 每⻚⼤⼩ */ void stockExport(HttpServletResponse response, Integer page, Integer pageSize);
- 接⼝实现:
/** * 将指定⻚的股票数据导出到excel表下 * @param response * @param page 当前⻚ * @param pageSize 每⻚⼤⼩ */ @Override public void stockExport(HttpServletResponse response, Integer page, Integer pageSize) { try { //1.获取最近最新的⼀次股票有效交易时间点(精确分钟) Date curDate = DateTimeUtil.getLastDate4Stock(DateTime.now()).toDate(); //因为对于当前来说,我们没有实现股票信息实时采集的功能,所以最新时间点下的数据 //在数据库中是没有的,所以,先临时指定⼀个假数据,后续注释掉该代码即可 curDate=DateTime.parse("2022-01-05 09:47:00", DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")).toDate(); //2.设置分⻚参数 底层会拦截mybatis发送的sql,并动态追加limit语句实现分⻚ PageHelper.startPage(page,pageSize); //3.查询 List<StockUpdownDomain> infos=stockRtInfoMapper.getAllStockUpDownByTime(curDate); //如果集合为空,响应错误提示信息 if (CollectionUtils.isEmpty(infos)) { //响应提示信息 } //设置响应excel⽂件格式类型 //2.设置响应数据的编码格式 //3.设置默认的⽂件名称 // 这⾥URLEncoder.encode可以防⽌中⽂乱码 当然和 easyexcel没有关系 //设置默认⽂件名称:兼容⼀些特殊浏览器 //4.响应excel流 } catch (IOException e) { e.printStackTrace(); log.info("当前导出数据异常,当前⻚:{},每⻚⼤⼩:{},异常信息:{}",page,pageSize,e.getMessage()); } }
如果要将查询结果导出到Excel,只需将页面的Context-Type修改为:Content-Type: application/vnd.ms-excel
参考答案点击这里查看(需要密码)👈part3_涨停跌停数据导出代码实现.txt
- 测试⽅式:
- 通过浏览器直接访问
http://localhost/aip/quot/stock/export?page=1&pageSize=20
,可直接获取stockRt.xlsx
⽂件 - 通过前端点击按钮获取,则会获取其它名称的⽂件,因为前端对⽂件进⾏了重命名操作;
- 通过浏览器直接访问

面试点:
- 使用读取百万级的Excel数据,且不发生OOM问题?
- 使用POI,一次性全量读--->OOM
- EasyExcel读取-->基于事件机制逐行扫描数据-->逐行处理后,只要对象不被引用,可被jvm快速垃圾回收,避免OOM(内存溢出)
- 测试excel文件导入?-练习题
- 参考:easyExcel官网
- lombok底层实现原理?@Data @Slf4j等;
- 底层编译期间通过字节码技术动态为class字节码插入增强的相关代码(增强的时机:编译期);