赞
踩
EasyExcel大大减少了内存占用的原因是,它会一行一行的解析Excel中的数据,从磁盘读到内存,并不会一次性加载到内存中。
- <dependencies>
- <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>2.1.1</version>
- </dependency>
- </dependencies>
- @Data
- public class Stu {
- //设置表头名称
- @ExcelProperty("学生编号")
- private int sno;
- //设置表头名称
- @ExcelProperty("学生姓名")
- private String sname;
- }
用来接收从数据库查出来的数据
- public class WriteTest {
- public static void main(String[] args) {
- String fileName = "D:\\test\\220718\\a.xlsx";
- EasyExcel.write(fileName,Stu.class).sheet("学员信息")
- .doWrite(data());
- }
-
- //循环设置要添加的数据,最终封装到list集合中
- private static List<Stu> data() {
- List<Stu> list = new ArrayList<Stu>();
- for (int i = 0; i < 10; i++) {
- Stu data = new Stu();
- data.setSno(i);
- data.setSname("张三"+i);
- list.add(data);
- }
- return list;
- }
- }
核心代码 就一行
EasyExcel.write(“文件名 or 输入流 or 文件”,"实体类的class").sheet("可以理解为表名").doWrite(数据集合)
- @Data
- public class Stu {
- //设置表头名称
- @ExcelProperty(value = "学生编号",index = 0)
- private int sno;
- //设置表头名称
- @ExcelProperty(value = "学生姓名",index = 1)
- private String sname;
- }
读的时候 index的值就是 要读的Excel表的第几列 列名
通过监听器来指定怎么读 (就是指定具体的操作)
- public class ExcelListener extends AnalysisEventListener<Stu> {
- @Override
- public void invoke(Stu stu, AnalysisContext analysisContext) {
- System.out.println("stu = " + stu);
- }
-
- //读取excel表头信息
- @Override
- public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
- System.out.println("表头信息:"+headMap);
- }
-
- @Override
- public void doAfterAllAnalysed(AnalysisContext analysisContext) {
-
- }
- }
关键继承 AnalysisEventListener<自己定义的实体类> 重写两个方法
在invoke方法中 可以将读到的一行数据 存到数据库中 在本文下面会有实例
- public class ReadTest {
- public static void main(String[] args) {
- String fileName = "D:\\test\\220718\\a.xlsx";
- EasyExcel.read(fileName,Stu.class,new ExcelListener()).sheet().doRead();
- }
- }
关键代码就一行
EasyExcel.read("文件名(路径) or 输入流",实体类的class,new 一个监听器).sheet().doRead();
如此 一个简单的Demo就完成了
下面将在前后端实现业务
========================================================================
1、首先导入依赖
2、确认VO对象(也就是Excel表头)
3、实现controller
(1)分析接口
*参数:reponse
*返回值:无
(2)实现方法
- @ApiOperation(value = "导出")
- @GetMapping(value = "/exportData")
- public void exportData(HttpServletResponse response){
- dictService.exportData(response);
- }
实现service
- 4、实现service
- //导出
- @Override
- public void exportData(HttpServletResponse response) {
- try {
- //1设置response基础参数
- response.setContentType("application/vnd.ms-excel");
- response.setCharacterEncoding("utf-8");
- // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
- String fileName = URLEncoder.encode("数据字典", "UTF-8");
- response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
- //2查询所有字典数据
- List<Dict> dictList = baseMapper.selectList(null);
-
- //3数据对象转型 Dict集合=>DictEeVo集合
- List<DictEeVo> dictEeVoList = new ArrayList<>();
- for (Dict dict : dictList) {
- DictEeVo dictEeVo = new DictEeVo();
- //dictEeVo.setId(dict.getId());
- BeanUtils.copyProperties(dict,dictEeVo);
- dictEeVoList.add(dictEeVo);
- }
- //4调用方法生成文件
- EasyExcel.write(response.getOutputStream(),DictEeVo.class)
- .sheet("数据字典").doWrite(dictEeVoList);
- } catch (IOException e) {
- e.printStackTrace();
- throw new YyghException(20001,"导出失败");
- }
- }
实现逻辑:
从数据库查询出所有的数据 存到一个集合中(dictList)
创建出来VO的集合 用来保存将来Excel中的数据
遍历dictList集合 将每一个对象都复制到 VO的集合中
将来把这个VO集合作为写入数据导出到Excel
核心代码
EasyExcel.write("文件目录 or 输出流",实体类的class).sheet("名字").doWrite();
4、对接前端
(2)添加页面元素
- <div class="el-toolbar">
-
- <div class="el-toolbar-body" style="justify-content: flex-start;">
-
- <el-button type="text" @click="exportData">
-
- <i class="fa fa-plus"/> 导出
-
- </el-button>
-
- </div>
-
- </div>
(3)实现js
- //导出
-
- exportData(){
-
- window.open(`${process.env.VUE_APP_BASE_API}admin/cmn/dict/exportData`)
-
- }
二、实现文件导入功能
1、创建controller
(1)接口分析
*参数:文件
*返回值:R.ok()
(2)实现方法
- @ApiOperation(value = "导入")
-
- @PostMapping("importData")
-
- public R importData(MultipartFile file){
-
- dictService.importData(file);
-
- return R.ok();
-
- }
2、创建监听器
- @Component
-
- public class DictListener extends AnalysisEventListener<DictEeVo> {
-
- @Autowired
-
- private DictMapper dictMapper;
-
-
-
- //手动注入,利用有参构造,new DictListener(dictMapper)
-
- //private DictMapper dictMapper;
-
-
-
- @Override
-
- public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
-
- Dict dict = new Dict();
-
- BeanUtils.copyProperties(dictEeVo,dict);
-
- dict.setIsDeleted(0);
-
- dictMapper.insert(dict);
-
- }
-
-
-
- @Override
-
- public void doAfterAllAnalysed(AnalysisContext analysisContext) {
-
-
-
- }
-
- }
注意使用注解@component的话 就是让spring来管理我们这个监听器了,在service想要使用的话 一定要提前@Autowired自动注入,要不然用不了
复制Excel中的数据的话 使用BeanUtils.copyProperties(dictEeVo,dict);
不要忘了在设置一下is_deleted=0
3、实现service
//导入
- @Override
-
- public void importData(MultipartFile file) {
-
- try {
-
- InputStream inputStream = file.getInputStream();
-
- EasyExcel.read(inputStream,DictEeVo.class,dictListener)
-
- .sheet().doRead();
-
- } catch (IOException e) {
-
- e.printStackTrace();
-
- throw new YyghException(20001,"导入失败");
-
- }
-
-
-
- }
核心代码
EasyExcel.read(输入流,实体类的)
4、对接前端
(1)确认入口
正在上传…重新上传取消
(2)实现方案
正在上传…重新上传取消
(3)添加页面元素
*入口
<div class="el-toolbar">
<div class="el-toolbar-body" style="justify-content: flex-start;">
<el-button type="text" @click="exportData">
<i class="fa fa-plus"/> 导出
</el-button>
<el-button type="text" @click="importData">
<i class="fa fa-plus"/> 导入
</el-button>
</div>
</div>
*对话框
<el-dialog title="导入" :visible.sync="dialogImportVisible" width="480px">
<el-form label-position="right" label-width="170px">
<el-form-item label="文件">
<el-upload
:multiple="false"
:on-success="onUploadSuccess"
:action="BASE_API"
class="upload-demo"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传xls文件,且不超过500kb</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogImportVisible = false">取消</el-button>
</div>
</el-dialog>
(4)实现js
data() {
return {
list: [],//表格数据
dialogImportVisible: false,//对话框是否显示
BASE_API:`${process.env.VUE_APP_BASE_API}admin/cmn/dict/importData`
};
},
methods: {
……
//打开上传对话框
importData(){
this.dialogImportVisible = true
},
//上传成功后操作
onUploadSuccess(response,file){
//1成功提示
this.$message({
type: "success",
message: "上传成功!"
});
//2关闭对话框
this.dialogImportVisible = false
//3刷新数据
this.getData(1)
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。