当开发基于Java的Web应用时,常常需要实现导入和导出Excel文件的功能。 EasyExcel是一个功能强大、易于使用的Java库,可以帮助我们快速实现Excel文件的导入和导出。本篇文章将介绍如何使用EasyExcel插件来实现导入和导出接口。

简介

EasyExcel是一个基于Java的开源Excel工具,它提供了方便的API来读取和写入Excel文件。与Apache POI相比,EasyExcel具有更高的性能和更简洁的编程方式。它可以轻松地处理大量数据并生成复杂的Excel文件。

导入功能实现

1、添加依赖

在项目的pom.xml文件中添加EasyExcel的依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version><!--使用最新版本-->
</dependency>

2、创建导入的实体类(DTO)

创建一个实体类来映射Excel中的数据,例如,如果我们要导入物料信息,可以创建一个名为ItemImportDTO的类,包含与Excel中列对应的属性

@Data
public class ItemImportDTO {
	/**
     * @ExcelProperty(String)是 EasyExcel 库中的注解,
     * 用于指定 Java 类字段与 Excel 表格中的列之间的映射关系。
     */
	@ExcelProperty("物料编码")
    private String code;
    @ExcelProperty("物料名称")
    private String name;
    // ... 其他属性
}

3、服务接口中创建一个用于导入的方法

在Service接口中定义导入的方法

public interface ItemService {
	void importExcel(InputStream inputStream);
	// ... 其他方法
}

4、编写监听器处理数据

EasyExcel允许你编写监听器来处理每行导入的数据或每行导出的数据。这样你可以在数据导入导出过程中执行自定义的逻辑。以下是一个简单的监听器示例

// 有个很重要的点 ItemExcelListener 不能被spring管理,然后里面用到spring可以构造方法传进去
public class ItemExcelListener extends AnalysisEventListener<ItemDTO> {
	//对数据进行操作和处理的对象,由于无法注入,所以需要用构造函数传进来
    private final ItemService itemService;

    /**
     * 定义100条数据存储一次,然后清理list,方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    
    /**
     * 存储缓存的数据
     */
    private List<ItemDTO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

	//构造函数
    public ItemExcelListener(ItemService itemService) {
        this.itemService = itemService;
    }

    /**
     * 每一条数据解析都会调用该方法
     */
    @Override
    public void invoke(ItemDTO itemDTO, AnalysisContext analysisContext) {
        cachedDataList.add(itemDTO);
        // 达到BATCH_COUNT了,需要存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (cachedDataList.size() >= BATCH_COUNT) {
        	//执行数据存储操作,需要自己来写相关逻辑
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成后调用该方法
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        //*******************************************************************
        //这里一定要确保cachedDataList不为空再调用saveData
        //否则当导入数据记录数等于BATCH_COUNT时可能会导致批量插入空数据数据报错
        //*******************************************************************  
        if (!cachedDataList.isEmpty()){
            saveData();
            // 存储完成清理 list
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    private void saveData(){
        // ... 批量保存数据的逻辑
    }

}

5、在服务类中实现导出方法

在ItemServiceImpl类中实现导入方法的具体细节

@Service
@Transactional(rollbackFor = Exception.class)
public class ItemServiceImpl implements ItemService {
	//根据自己使用的框架注入数据库访问对象,用于与数据库交互并操作数据库中的数据
	@Resource
    private ItemMapper itemMapper;

    @Override
    public void importExcel(InputStream inputStream) {
        ItemExcelListener itemExcelListener = new ItemExcelListener(this);
        EasyExcel.read(inputStream, ItemDTO.class, itemExcelListener).sheet().doRead();
    }
    
	// ... 其他方法

}

6、控制器层调用

创建一个控制器类来处理导入的请求

@RestController
@RequestMapping("/item")
public class ItemController {
    @Resource
    private ItemService itemService;

	@PostMapping("/import")
    @ApiOperation(value = "导入物料信息接口")
    public String importExcel(@RequestParam("file") MultipartFile file){
        try {
            itemService.importExcel(file.getInputStream());
            return "文件导入成功";
        } catch (Exception e) {
            return "文件导入失败: " + e.getMessage();
        }
    }

	// ... 其他方法

}

7、调用接口

最后,调用该接口并上传Excel文件即可完成数据导入

在这里插入图片描述

导出功能实现

1、 创建用于导出的实体类(VO)

创建一个实体类来映射数据库中数据,例如,如果我们要导出物料信息,可以创建一个名为ItemExportVO的类,包含需要导出的属性

@Data
public class ItemExportVO{
	/**
     * @ExcelIgnore 是 EasyExcel 库中的注解,用于标记 Java 类中的字段,
     * 指示在进行 Excel 文件读写时,忽略这些被标记的字段。
     */
    @ExcelIgnore
    private Long id;
	@ExcelProperty("物料编码")
    private String code;
    @ExcelProperty("物料名称")
    private String name;
    // ... 其他属性
}

2、服务接口中创建一个用于导出的方法

在Service接口中定义导出的方法

public interface ItemService {
	//定义用于导出的方法,[]中的是可选参数,如果想要在请求中传递额外参数可以使用这种方式
	void exportExcel(HttpServletResponse response[,Long platformId]) throws IOException;
	// ... 其他方法
}

3、在服务类中实现导出方法

在ItemServiceImpl类中实现导出方法的具体细节

@Service
@Transactional(rollbackFor = Exception.class)
public class ItemServiceImpl implements ItemService {
	//根据自己使用的框架注入数据库访问对象,用于与数据库交互并操作数据库中的数据
	@Resource
    private ItemMapper itemMapper;

    @Override
    public void exportExcel(HttpServletResponse response,Long platformId) throws IOException {
    	//文件名及编码方式,System.currentTimeMillis()为当前系统的时间戳
        String filename = URLEncoder.encode(String.valueOf(System.currentTimeMillis()),"utf-8");
        //设置响应头信息:将响应内容类型设置为 Excel 文件,并指定文件名和编码方式
        response.setHeader("Content-Disposition","attachment;filename=" + filename + ".xlsx");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        //获取响应的输出流,用于将数据写入响应。
        OutputStream outputStream = response.getOutputStream();
        //创建一个 ExcelWriter 对象,用于写入 Excel 文件。
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
        //从数据库中根据自己的方法查询出需要导出的数据
        List<ItemVO> data = getData(platformId);
        //创建一个工作表,指定工作表名称和表头
        WriteSheet sheet = EasyExcel.writerSheet(status.getMsg()).head(ItemVO.class).build();
        //将数据写入该工作表
        excelWriter.write(data, sheet);
        // 完成写入操作,关闭 ExcelWriter
        excelWriter.finish();


		//如果想要写入多个工作表中则可以更改代码为:
		for(int i=0;i<3;i++){
		//根据自己方法调整获取不同的数据
		List<ItemVO> data = getData(platformId);
		WriteSheet sheet = EasyExcel.writerSheet("sheet"+i).head(ItemVO.class).build();
        //将数据写入该工作表
        excelWriter.write(data, sheet);
        }
		excelWriter.finish();
    }

	// ... 其他方法

}

4、控制器层调用

创建一个控制器类来处理导出的请求

@RestController
@RequestMapping("/item")
public class ItemController {
    @Resource
    private ItemService itemService;

	@GetMapping("/export")
    @ApiOperation(value = "导出物料信息接口")
    public void exportExcel(HttpServletResponse response,@RequestParam Long platformId) throws IOException {
        itemService.exportExcel(response,platformId);
    }

	// ... 其他方法

}

5、调用接口

最后,调用该接口就可以直接下载导出的Excel文件

在这里插入图片描述
在这里插入图片描述

总结

通过EasyExcel插件,我们可以轻松地实现导入和导出Excel文件的功能。使用它可以减少开发工作量,提高开发效率,并且支持大数据量的读写操作。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐