Springboot使用hutool实现Excel文件导入导出功能

导入依赖

<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-core</artifactId>
	<version>5.8.1</version>
</dependency>

Excel文件导入

导入后返回前端的信息实体VO

@Data
public class ImportReturnVO {

    @ApiModelProperty(value = "是否所有记录都是有效导入的数据,只有所有数据都为有效数据才视为导入成功")
    private Boolean isSuccessImport;

    @ApiModelProperty(value = "是否所有记录都成功保存到数据库")
    private Boolean isSuccessSave;

    @ApiModelProperty(value = "无效导入的数据的数量")
    private Integer errCount;

    @ApiModelProperty(value = "Map{无效导入的数据行号 : 无效的原因}")
    private Map<Integer, String> errItem;

    @ApiModelProperty(value = "成功保存到数据库的数据总数")
    private Integer count;
}

注:此处的导入是写死的,即每一列固定是表示什么数据
若需其他导入方式可参考

@Transactional(readOnly = false)
public ImportReturnVO importFromExcel(MultipartFile file) throws IOException {
	ImportReturnVO returnVO = new ImportReturnVO();
	InputStream inputStream = file.getInputStream();
	ExcelReader reader = ExcelUtil.getReader(inputStream);
	//跳过标题行,直接读取表的内容
	List<List<Object>> objectList = reader.read(1);
	//导入保存的实体列表
	List<Entity> list = new ArrayList<>();
	//{无效的数据行号 : 无效的原因}
	Map<Integer, String> errItem = new HashMap<>();
	for (int i = 0; i < objectList.size(); i++) {
		//一行的所有数据
		List<Object> row = objectList.get(i);
		//若该行有哪列数据格式错误,拼接错误消息
		StringBuilder errMsg = new StringBuilder();
		//导入后保存到数据库表的实体
		//Entity e = new Entity();
		
		//...判断数据合法性及赋值...
		
		//含有非法数据
		if (errMsg.length() > 0) {
			//行号从2开始,第1行标题不读,[i+2]为当前行号
			errItem.put(i + 2, errMsg.toString());
		} else {
			list.add(entity);
		}
	}
	//导入失败
	if (errItem.size() > 0) {
		returnVO.setErrItem(errItem);
		returnVO.setErrCount(errItem.size());
		returnVO.setIsSuccessImport(false);
		return returnVO;
	} else {
		//导入成功
		returnVO.setIsSuccessImport(true);
		returnVO.setErrCount(0);
	}
	//将导入的列表保存到数据库
	int count = 0;
	
	//...
	
	//保存数据库成功
	if (count == list.size()) {
		returnVO.setCount(count);
		returnVO.setIsSuccessSave(true);
	} else {
		//保存数据库失败
		returnVO.setIsSuccessSave(false);
		//手动回滚
		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
	}
	return returnVO;
}

Excel文件导出

@Data
public class ExportVO {

	@ApiModelProperty(value = "要导出的实体id列表")
	private List<String> idList;
	
	//添加其余条件查询所需的字段...
}
//在Excel中显示的行数据对象
@Data
public class EntityExcel {

	private String title;
	
	private String details;
}
@Transactional(readOnly = true)
public void exportToExcel(ExportVO vo, HttpServletResponse response) {
	//默认创建xls格式的(getWriter(true)则创建xlsx格式)
	ExcelWriter writer = ExcelUtil.getWriter(true);
	
	//自定义标题别名(Excel的标题行/第一行),根据EntityExcel的属性映射对应的标题名
	writer.addHeaderAlias("title", "标题");
	writer.addHeaderAlias("details", "详情");
	
	EntityExample example = new EntityExample();
	//逻辑删除字段
	example.createCriteria().andDelFlagEqualTo(Entity.DEL_FLAG_NORMAL);
	List<String> idList = vo.getIdList();
	//id列表为空, 则导出所有未被删除的实体
	//id列表不为空,则导出id列表对应的实体
	if (idList != null && idList.size() > 0) {
		example.getOredCriteria().get(0).andIdIn(idList);
	}
	List<Entity> list = mapper.selectByExample(example);
	//Excel行数据,一个EntityExcel对应一行数据
	List<EntityExcel> rows = new ArrayList<>();
	for (Entity e : list) {
		EntityExcel entityExcel = new EntityExcel();
		//给EntityExcel行数据赋值
		BeanUtils.copyProperties(e, entityExcel);
		
		rows.add(entityExcel);
	}
	
	// 一次性写出内容,使用默认样式
	writer.write(rows, true);
	//response为HttpServletResponse对象
	response.setContentType("application/vnd.ms-excel");
	ServletOutputStream out = null;
	//文件名格式:文件+当前时间,如文件20220617094900
	String rawFileName = "文件" + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
	try {
		//弹出下载对话框的文件名不能为中文,中文请自行编码
		//P.S 这里可以中文命名,但是只能通过URL请求,通过swagger或postman请求还是会乱码,若要测试可以通过Get请求
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(rawFileName, "UTF-8") + ".xlsx");
		out = response.getOutputStream();
		writer.flush(out, true);
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		// 关闭writer,释放内存
		writer.close();
		//此处记得关闭输出Servlet流
		IoUtil.close(out);
	}
}

本文参考地址
若有误,欢迎评论区指正~

posted @ 2022-06-17 09:59  .Blank  阅读(1585)  评论(0编辑  收藏  举报