赞
踩
Java使用EasyExcel实现文件导入导出
<!--easyExcel依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.0</version>
</dependency>
注意如果本来工程中引入了poi依赖,最好升级成4.1.2等高版本,比如我引入的poi的3.9版本在使用easyExcel时会报错。
/** * 基础数据类 * **/ @Getter @Setter @EqualsAndHashCode public class DownloadData { @ExcelProperty("编号") private Integer id; @ExcelProperty("姓名") private String username; @ExcelProperty("密码") private String password; }
/** * Excel文件下载导出 * <p> * 1. 创建excel对应的实体对象 参照{@link DownloadData} * <p> * 2. 设置返回的 参数 * <p> * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大 */ @GetMapping("/download") public void download(HttpServletResponse response) throws IOException { // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); //自行编写查询数据库数据 List<DownloadData> users = commodityService.getUsers(); EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(users); }
/** * 用户表 */ @EqualsAndHashCode public class TUser { @ExcelIgnore private Integer id; private String username; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
@Slf4j public class UploadDataListener implements ReadListener<TUser> { /** * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 100; private List<TUser> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); /** * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。 */ private CommodityMapper commodityMapper; /** * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来 * * @param */ public UploadDataListener(CommodityMapper commodityMapper) { this.commodityMapper = commodityMapper; } /** * 这个每一条数据解析都会来调用 * * @param data one row value. It is same as {@link AnalysisContext#readRowHolder()} * @param context */ @Override public void invoke(TUser data, AnalysisContext context) { log.info("解析到一条数据:{}", JSON.toJSONString(data)); cachedDataList.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } } /** * 所有数据解析完成了 都会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); log.info("所有数据解析完成!"); } /** * 加上存储数据库 */ private void saveData() { log.info("{}条数据,开始存储数据库!", cachedDataList.size()); commodityMapper.saveUsers(cachedDataList); log.info("存储数据库成功!"); }
@Mapper
@Repository
public interface CommodityMapper {
void saveUsers(List<TUser> tUsers);
}
<insert id="saveUsers" parameterType="java.util.List">
insert into t_user (username,password) values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.username},#{item.password})
</foreach>
</insert>
/**
* 文件上传
* <p>1. 创建excel对应的实体对象 参照{@link }
* <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener}
* <p>3. 直接读即可
*/
@PostMapping("/upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), TUser.class, new UploadDataListener(commodityMapper)).sheet().doRead();
return "success";
}
2.4 查看数据库已经导入成功了
提示:更具体的用法可参考EasyExcel官方文档:EasyExcel官方文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。