大量数据MySQL导出到Excel的方法

举报
星汉网络 发表于 2021/05/12 10:32:44 2021/05/12
【摘要】 对于数据的Excel报表导出,在相关项目中比较常用。但是对于大量数据的导出,就要有一定的策略。例如导出10万行数据,或者更大数字。要采用流的方式进行数据的处理。

需求背景

对于数据的Excel报表导出,在相关项目中比较常用。但是对于大量数据的导出,就要有一定的策略。例如导出10万行数据,或者更大数字。要采用流的方式进行数据的处理。

前提条件

基于星汉公共基础类的操作。主要还是通过POI导出Excel文件,通过Hibernate操作MySQL数据库。

场景1、一条HQL语句,即可完成查询

@Test
public void testExportExcel()
{
	//创建Excel拼装对象
	ExcelWriter<UpkeepBean> writer = ExcelWriter.defaultAutoFlush();
	writer.createSheet("保修基础数据Excel表格");
	writer.add("经销店编码", "shopCode")
		.add("车架号", "carCode")
		.add("延保开始时间","insuranceStartDate");

	XhHQL hql = XhHQL.from(BasicInsuranceBean.class);

	//流式数据导出,分段书写Excel文件
	stream(hql, stream -> {
		writer.build(stream);
		return null;
	});

	//TODO 导出数据流到Excel文件中
	File xls = writer.write();
	try (FileInputStream in = new FileInputStream(xls)) {
		XhFile.save(in, "D:\\07-LocalCache\\out-basic-insurance.xlsx");
	}
	catch (IOException e) {
		XhLogger.error(e);
	}
}

说明: 不能够先执行HQL,获取数据到List中。对于数据量过大,速度极慢,效率低,要边读边写。

场景2、对于查询出的数据,还要进行二次封装和处理

这种情况稍微复杂些,主要思路还是流式处理。

@Test
public void testExportLargeDataExcel()
{
	//01 首先创建Excel拼装对象
	ExcelWriter<UpKeepView> builder = ExcelWriter.defaultAutoFlush();
	builder.createSheet("保养报案导出Excel");

	builder.add("报案号", "bean.id")
		.add("报案状态", "statusName")
		.add("组织编码", "bean.shopCode")
		.add("组织名称", "shopName")
		.add("报案人", "userName");
	builder.buildTitle();

	//02 构造数据库查询语句
	InsuranceCondition condition = new InsuranceCondition();
	condition.setStatus(OrderStatus.stayAudit.toString());

	XhHQL hql = upkeepDao.getListHql(condition);

	//03 流式处理数据
	stream(hql, stream -> {
		DoSomething ds = new DoSomething(builder);
		stream.forEach(bean -> ds.push((UpKeepView) bean));
		ds.doDeal();

		//导出Excel文件
		File xls = builder.write();
		try (FileInputStream in = new FileInputStream(xls)) {
			XhFile.save(in, "D:\\07-LocalCache\\upkeep-out.xlsx");
		}
		catch (IOException e) {
			XhLogger.error(e);;
		}

		return null;
	});
}

/**
     * 处理业务数据
     */
private class DoSomething
{
	//要处理的数据列表
	private final List<UpKeepView> list = new ArrayList<>();
	ExcelWriter<UpKeepView> builder = ExcelWriter.defaultAutoFlush();
	//一批量处理数据的长度
	private static final int SIZE = 1024;

	//得到Excel构造器
	DoSomething(ExcelWriter<UpKeepView> builder) {
		this.builder = builder;
	}

	//逐条插入数据
	void push(UpKeepView bean)
	{
		if (list.size() == SIZE) {
			doDeal();
		}

		list.add(bean);
	}
	//执行处理过程
	void doDeal()
	{
		if (list.isEmpty()) return;
		list.forEach(item->{
			//TODO 对于业务数据进行相关的处理
		});

		//写入数据到Excel中
		for (UpKeepView item : list) {
			builder.addContent(item);
		}

		//清空数据,继续处理
		list.clear();
	}
}

说明:要注意内部类的使用方法。如果业务处理复杂,可以提出新的类完成

说明

对于无论数据量大小,都建议采用这种方式导出Excel文件。经测试,导出50万条数据,效率也还不错。但是对于超20万以上数据的导出,要注意服务器的CPU和内存的限制。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。