1.EasyExcel介绍
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
文档地址:https://alibaba-easyexcel.github.io/index.html
2.使用步骤
2.1:在pom文件中导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.1</version> </dependency>
2.2:创建一个实体类UserData
2.3:写操作
public class TestWrite { public static void main(String[] args) { //构建数据list集合,这是要写入excel的数据 List<UserData> list = new ArrayList(); for (int i=0;i<10;i++) { UserData data = new UserData(); data.setUid(i); data.setUsername("lucy"+i); list.add(data); } //设置excel文件路径和文件名称 String fileName = "F:\\excel\\01.xlsx"; //调用方法实现写操作(输入要写入的文件名和类的类别) //sheet就是表中sheet1的命名,然后载调用doWrite把list写入进去 EasyExcel.write(fileName, UserData.class).sheet("用户信息") .doWrite(list); } }
输出的表
2.4:读操作 (读的是上面写的表)
2.4.1:实体类标签添加属性
2.4.2:创建监听器类 ExcelListener
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import java.util.Map; public class ExcelListener extends AnalysisEventListener<UserData> { //一行一行读取excel内容,从第二行读取 @Override public void invoke(UserData userData, AnalysisContext analysisContext) { //将读到的信息进行输出,也是我们取出的表里的信息 System.out.println(userData); } //表头信息输出 @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { System.out.println("表头信息:"+headMap); } //读取之后执行 @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }
3.复杂使用(前后端写操作)
3.1:前端 调用后端接口![](https://i-blog.csdnimg.cn/blog_migrate/204c9fa10c235340e81e914e0ae9e389.png)
3.2:后端controller调用service
注意:后端不用给前端返回数据,但是要设置的文件名路径都需要设置在response里面
//导出数据字典接口 @GetMapping("exportData") public void exportDict(HttpServletResponse response) { dictService.exportDictData(response); }
3.3:service中实现功能
这里使用的是 如下方法,跟简单的参数不同,所以需要设置输出流
@Override
public void exportDictData(HttpServletResponse response) {
//设置下载信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = "dict";
response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
//查询数据库所有数据
List<Dict> dictList = baseMapper.selectList(null);
//Dict -- DictEeVo
List<DictEeVo> dictVoList = new ArrayList<>();
for(Dict dict:dictList) {
DictEeVo dictEeVo = new DictEeVo();
// dictEeVo.setId(dict.getId());
BeanUtils.copyProperties(dict,dictEeVo);
dictVoList.add(dictEeVo);
}
//调用方法进行写操作
try {
EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("dict")
.doWrite(dictVoList);
} catch (IOException e) {
e.printStackTrace();
}
}
4.复杂使用(前后端写操作)
4.1:前端调用弹框
4.2:弹框代码 ,会将当前文件传到:action
<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="'http://localhost:8202/admin/cmn/dict/importData'"
class="upload-demo">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传excel文件,且不超过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.3:弹框的显示关闭
4.4:后端Controller调用service
//导入数据字典 @PostMapping("importData") public Result importDict(MultipartFile file) { dictService.importDictData(file); return Result.ok(); }
4.5:service调用
//导入数据字典 @Override @CacheEvict(value = "dict", allEntries=true) public void importDictData(MultipartFile file) { try { EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper)).sheet().doRead(); } catch (IOException e) { e.printStackTrace(); } }
4.6: 在Listener中实现功能
代码如下
public class DictListener extends AnalysisEventListener<DictEeVo> {
private DictMapper dictMapper;
public DictListener(DictMapper dictMapper) {
this.dictMapper = dictMapper;
}
//一行一行读取
@Override
public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
//调用方法添加数据库
Dict dict = new Dict();
BeanUtils.copyProperties(dictEeVo,dict);
dictMapper.insert(dict);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
5.有关于演示的疑惑
dict和dictEeVo的转换:这两个其实属性是差不多的,但是dict里面的标签很多,所以格外写了一个类专门实现导入导出的操作,(因为在导入的时候,创建时间或者isdelete这些属性没有必要导出,也不用写入,属于自动生成)
因此,写入数据库在listener用的类是dictEeVo.class,真正写入数据到数据库时,转换成dict