前言

又又又接手老项目 进行改造… 之前poi写的excel导入会导致oom内存溢出,调了内存也没用 就用EasyExcel重写了下 基于原项目结构的写 确实好难受

一句话概括本文:

引用传递

开始

由于我需要基于原项目逻辑走 导入之后的各种校验需要根据service层的逻辑进行数据校验(这里我要基于原项目结构的写,easyexcel有数据校验注解具体看官方文档),

校验失败然后service层会抛出个异常,正常应该在controller层捕捉异常然后返回给页面的,但是在使用easyexcel 时候被重写方法是没有异常抛出的 根据java重写规则重写的方法只能比原方法抛出更小的异常,也就是说我在service层抛出异常 路过监听器的时候就已经没了

这时候想返回前台某一列数据校验失败就要用到值传递,

步骤:

在controller层初始化一个ajax返回对象 然后通过监听器的构造方法将返回对象传入 捕捉service的异常(或者你将错误信息返回出来也行,这个老项目写的是用异常将错误信息带出来) 将错误信息存到ajax返回对象就行,然后controller直接返回这个ajax对象

上代码:

controller

	@ResponseBody
	@RequestMapping(value = "orderImport", method = RequestMethod.POST, produces = Constant.CONTENT_TYPE_UTF8)
	public RestResponse orderImport(HttpServletRequest request,  @RequestParam(value = "file") MultipartFile file) throws Exception {
		UserVO userVo = this.getCurrentUser(request);

		// 初始化ajax返回对象 默认是操作成功
		RestResponse build = RestResponse.build();

		EasyExcel.read(file.getInputStream(), new NoModleDataListener(orderService, userVo, build)).sheet().doRead();
		// 直接返回  如果错误这个对象的值已被改变 如果没有错误值没有被改变 返回的是默认成功的对象
		return build;
		// return orderService.importOrder(userVo, file);
	}

监听器:


/**
 * @author: [青衫] 'QSSSYH@QQ.com'
 * @Date: 2020-01-07 11:09
 * @Description: < map接收解析数据-监听器 >
 */
public class NoModleDataListener extends AnalysisEventListener<Map<Integer, String>> {
	private static final Logger LOGGER = LoggerFactory.getLogger(NoModleDataListener.class);


	/**业务逻辑层*/
	private OrderService orderService;
	/**用户Vo*/
	private UserVO userVO;
	/**ajax返回对象*/
	private RestResponse build;
	/**excel头*/
	private Map<Integer, String> headMaps;


	/**
	 * 监听器构造方法
	 *
	 * @param orderService 业务逻辑层
	 * @param userVO       用户vo (Service业务使用)
	 * @param build        ajax返回对象
	 */
	public NoModleDataListener(OrderService orderService, UserVO userVO, RestResponse build) {
		this.orderService = orderService;
		this.userVO = userVO;
		this.build = build;
	}

	/**
	 * 每隔3000条存储数据库
	 */
	private static final int BATCH_COUNT = 3000;
	List<Map<Integer, String>> list = new ArrayList<Map<Integer, String>>();

	@Override
	public void invoke(Map<Integer, String> data, AnalysisContext context) {

		list.add(data);
		if (list.size() >= BATCH_COUNT) {
			try {
				saveData();
			} catch (Exception e) {
				build.setCode(1);
				build.setMsg(e.getMessage());
			}
			list.clear();
		}
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		try {
			saveData();
		} catch (Exception e) {
            // 将返回对象code改为错误状态码
			build.setCode(1);
            // 存入错误信息
			build.setMsg(e.getMessage());
		}
	}


	@Override
	public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
		headMaps = headMap;
	}

	/**
	 * 存储数据库
	 */
	private void saveData() throws Exception {

		orderService.importOrders(userVO, list, headMaps);
		LOGGER.info("存储数据库成功!");
	}

    /**
    *解析出现错误会进入该方法 具体看源代码或文档
    */
	@Override
	public void onException(Exception exception, AnalysisContext context) throws Exception {
		System.out.println("hello");
		throw exception;
	}
}

GitHub 加速计划 / ea / easyexcel
31.64 K
7.47 K
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:3 个月前 )
c42183df Bugfix 3 个月前
efa7dff6 * 重新加回 `commons-io` 3 个月前
Logo

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

更多推荐