EasyExcel读操作

①、添加依赖(com.alibaba)
easyexcel
②、封装实体类
java
@Data
public class CategoryExcelVo{
@ExcleProperty(value="id",index=0)
private Long id;
@ExcelProperty(value="名称",index=1)
private String name;
@ExcelProperty(value="图片url",index=2)
private String imageUrl;
@ExcelProperty(value="上级id",index=3)
private Long parentId;
@ExcelProperty(value="状态",index=4)
private Integer status;
@ExcelProperty(value="排序",index=5)
private Integer orderNum;
}
③、定义一个监听器
java
public class ExcelListener<T> extends AnalysisEventListener<T>{
//可以通过实例获取该值
private List<T> datas = new ArrayList<>();
//每解析一行数据,就会调用一次该方法
//从第二行开始读取,将内容封装到t对象中
@Override
public void invoke(T t,AnalysisContext anlaysisContext){
dtas.add(t);//将每行数据存储到list,供批量处理,或后续业务逻辑处理
}
public List<T> getDatas(){
return datas;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext){
//excel解析完毕以后需要执行的代码
}
}
④、测试
java
public class EashExcelTest{
@Test
public void read(){
String fileName = "C://01.xlsx";
ExcelListener<CategoryExcelVo> excelListener = new ExcelListener();
EasyExcel.read(fileName,CategoryExcelVo.class,excelListener)
.sheet().doRead();
List<CategoryExcelVo> data = excelListener.getData();
System.out.println(data);
}
}
EasyExcel写操作
java
@Test
public void write(){
List<CategoryExcelVo> list = new ArrayList<>();
list.add(1L,"数码办公","",0L,1,1);
list.add(11L,"华为手机","",1L,1,1);
EasyExcel.write("C://02.xlsx",CategoryExcelVo.class).sheet("分类数据").doWrite(list);
}
项目中的应用
导出功能
- 将数据库的数据,写入到Excel中
前端整合
src/api/category.js
js
export const ExportCategoryData = ()=>{
return request({
url:'${api_name}/exportData',
method:'get',
responseType:'blob' //响应类型为blob,二进制数据类型
})
}
category.vue
js
<div class="tools-div">
<el-button type="success" size="small" @click="exportData">导出</el-button>
</div>
<script setup>
import {FindCategoryByParentId,ExportCategoryData} from '@/api/category.js'
const exportData = ()=>{
ExportCategoryData().then(res=>{
const blob = new Blob([res]);
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
//设置下载文件的名称
link.download = '分类数据.xlsx';
link.click();
})
}
</script>
代码开发需求
java
@GetMapping("/exportData")
public void exportData(HttpServletResponse response){
categoryService.exportData(response);
}
java
@Override
public void exportData(HttpServletResposne response){
try{
//1.设置响应头信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("分类数据","UTF-8");//防止中文乱码
response.setHeader("Content-disposition","attachment;filename"+fileName+".xlsx");
//2.查询数据库的数据
List<Category> categoryList = categoryMapper.findAll();
//list<Category> -> List<CategoryExcelVo>
for(Category category:categoryList){
CategoryExcelVo categoryExcelVo = new CategoryExcelVo();
BeanUtils.copyProperties(category,categoryExcelVo);
categoryExcelVoList.add(categoryExcelVo);
}
//3.调用EasyExcel的write方法完成写操作
EasyExcel.write(response.getOutputStream(),CategoryExcelVo.class)
.sheet("分类数据").doWrite(categoryList);
}catch(Exception e){
e.printStackTrace();
throw new GuiguException(ResultCodeEnum.DATA_ERROR);
}
}
导入功能
- 将Excel表中的数据导入到数据库中
java
@PostMapping("/importData")
public ResultimportData(MultipartFile file){
categoryService.importData(file);
return Result.build(null,ResultCodeEnum);
}
java
@Override
public void importData(MultipartFile file){
try{
ExcelListener<CategoryExcelVo> excelListener = new ExcelListener(categoryMapper);
EasyExcel.read(file.getInputStream(),CategoryExcelVo.class,excelListener)
.sheet().doRead();
}catch(IOException e){
e.printStackTrace()
throw new GuiguException(ResultCodeEnum.DATA_ERROR);
}
}

java
public class ExcelListener implements ReadListener<T>{
//每隔5条存储数据库,实际使用者可以100条,然后清理list,方便内存回收
private static final int BATCH_COUNT = 100;
private List<T> cacheDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
//构造传递mapper,操作数据库
private CategoryMapper categoryMapper;
public ExcelListener(CategoryMapper categoryMapper){
this.categoryMapper = categoryMapper;
}
//从第二行开始读取,把每行读取的内容封装到t对象
@Override
public void invoke(T t,AnalysisContext analysisContext){
cacheDataList.add(t);//把每行数对象t放到cacheDataList集合里面
if(cachedDataList.size()>BATCH_COUNT){//达到BATCH_COUNT需要一次存储数据库,防止数据OOM
saveData();//调用方法一次性批量添加数据库里面
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);//重新创建对象,相当于清理list
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext){
//如果没达到BATCH_COUNT
saveData();
}
private void saveData(){
categoryMapper.batchInsert((List<CategoryExcelVo>) cacheDataList);
}
}
前端整合
js
<el-button type="primary" size="small" @click="importData">导入</el-button>
<el-dialod v-model="dislogImportVisible" title="导入" width="30%">
<el-form label-width="120px">
<el-form-item label="分类文件">
<el-upload class="upload=demo"
action="http://localhost:8501/admin/product/category/importData"
:on-success="onUploadSuccess"
:headers="headers">
<el-button type="primary">上传</el-button>
</el-upload>
</el-form-item>
</el-form>
</el-dialog>
<script setup>
import {useApp} from '@/pinia/modules/app'
const dialogImportVisible = ref(false)
const headers = {
token:useApp().authorization.token //从pinia中获取token,进行文件上传时将token设置到请求头
}
const importData = ()=>{
dialogImportVisible.value=true
}
//上传文件成功后执行方法
const onUploadSuccess = async(response,file)=>{
ElMessage.success('操作成功')
dialogImportVisible.value=false
const{data} = await FindCategoryByParentId(0)
list.value=data;
}
</script>