当前位置: 首页 > news >正文

EasyExcel导入导出

EasyExcel读操作

在这里插入图片描述

①、添加依赖(com.alibaba)

easyexcel

②、封装实体类

@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;
}

③、定义一个监听器

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解析完毕以后需要执行的代码
	}
}

④、测试

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写操作

@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

export const ExportCategoryData = ()=>{
	
	return request({
		url:'${api_name}/exportData',
		method:'get',
		responseType:'blob' //响应类型为blob,二进制数据类型
	})
}

category.vue

<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>

代码开发需求
在这里插入图片描述

@GetMapping("/exportData")
public void exportData(HttpServletResponse response){
	
	categoryService.exportData(response);
}
@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表中的数据导入到数据库中
@PostMapping("/importData")
public ResultimportData(MultipartFile file){
	
	categoryService.importData(file);
	return Result.build(null,ResultCodeEnum);
}
@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);
	}
}

监听器,不能让spring管理

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);
	}
	
}

前端整合

<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>
http://www.dtcms.com/a/121865.html

相关文章:

  • 雷电防护检测工作流程及重要性
  • 【愚公系列】《高效使用DeepSeek》062-图书库存管理
  • 台式电脑插入耳机没有声音或麦克风不管用
  • Dify 生成提示词的 Prompt
  • git回滚指定版本并操作
  • Llama 4的争议
  • 【重装系统】大白菜自制U盘装机,备份C盘数据,解决电脑启动黑屏/蓝屏
  • 批量合并多张 jpg/png 图片为长图或者 PDF 文件,支持按文件夹合并图片
  • 面向大模型的开发框架LangChain
  • LLM Agents项目推荐:MetaGPT、AutoGen、AgentVerse详解
  • 工业制造核心术语
  • 每日文献(十)——Part two
  • STM32 CRC校验与芯片ID应用全解析:从原理到实践 | 零基础入门STM32第九十七步
  • 分类算法的介绍和应用场景
  • Spring MVC 重定向(Redirect)详解
  • 【Linux笔记】文件的传输(scp、rsync、归档、压缩)
  • 使用 VSCode 本地历史记录‌恢复误删除文件
  • 复习防火墙(一)
  • 知微·智研重磅发布:AI加持的智能化研发管理,革新科技组织数字化转型
  • 4.9复习记
  • Flutter Invalid constant value.
  • 【Java设计模式】第3章 软件设计七大原则
  • ragflow开启https访问:添加证书后,使用浏览器还是有警告,如何解决?
  • [ AI工具库 ] 宝藏级 AI 工具合集
  • MySQL多表查询、事务与索引的实践与应用
  • C++字符串复习
  • 如何在Dify中安装运行pandas、numpy库(离线、在线均支持,可提供远程指导)
  • 每日定投40刀BTC(13)20250404 - 20250408
  • vue3中watch的使用示例
  • 算法小练习