Skip to main content

08小节:EasyExcel解析百万Excel创建批量分发任务

作者:程序员马丁

在线博客:https://nageoffer.com

note

热门项目实战社群,收获国内众多知名公司面试青睐,近千名同学面试成功!助力你在校招或社招上拿个offer。

EasyExcel解析百万Excel创建批量分发任务,元数据信息:

©版权所有 - 拿个offer-开源&项目实战星球专属学习项目,依据《中华人民共和国著作权法实施条例》《知识星球产权保护》,严禁未经本项目原作者明确书面授权擅自分享至 GitHub、Gitee 等任何开放平台。违者将面临法律追究。


内容摘要:为应对平台和商家的销售额提升,平台通过批量发送优惠券的方式主动推送给用户。我们开发了基于 Excel 文件的优惠券分发功能。考虑到常规的 Excel 文件解析常常导致内存占用过高和 OOM(内存溢出)问题,我们采用了 EasyExcel 解决方案以高效完成此功能。

课程目录如下所示:

  • 业务背景
  • 数据库表设计
  • Git 分支
  • 生成百万测试 Excel 文件
  • 开发创建优惠券分发任务
  • 文末总结

业务背景

我们设想一个场景,你是一个保险公司的运营人员,如果你们出了一个新的保险,怎么让用户更好知道?漫无目的宣传肯定不行,是不是可以找之前购买过你们保险或者有意向购买保险的用户,给他们发个短信通知或者电话营销好一些。

我们优惠券的分发和上面保险推广是相同的原理,获取到用户信息的 Excel 后,将优惠券写入到用户领券列表中,同时根据配置选择是否通知用户,通知的话有短信、微信公众号、邮件等。

用户信息的 Excel 从哪里来?一般来说,可以通过数据仓库里提取,或者每个公司对于这种需求实现方式不一样,但是万变不离其宗。

数据仓库指的是数仓,一个专门设计用于数据存储和分析的系统。它用于集成、存储和管理来自不同来源的数据,并提供对这些数据的高效查询和分析功能。

例如,如果我们要上线一家高端服装店,为了提升其生意,我们可以从数据仓库中提取长期浏览高端服装或已经购买过类似品牌或价位的用户信息,然后将优惠券和通知发送到这些用户的账户。这样可以精准地锁定潜在客户,提高营销效果。

数据库表设计

进入 one_coupon_rebuild_0 数据库中执行下述 SQL 语句。

CREATE TABLE `t_coupon_task` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`shop_number` bigint(20) DEFAULT NULL COMMENT '店铺编号',
`batch_id` bigint(20) DEFAULT NULL COMMENT '批次ID',
`task_name` varchar(128) DEFAULT NULL COMMENT '优惠券批次任务名称',
`file_address` varchar(512) DEFAULT NULL COMMENT '文件地址',
`fail_file_address` varchar(512) DEFAULT NULL COMMENT '发放失败用户文件地址',
`send_num` int(11) DEFAULT NULL COMMENT '发放优惠券数量',
`notify_type` varchar(32) DEFAULT NULL COMMENT '通知方式,可组合使用 0:站内信 1:弹框推送 2:邮箱 3:短信',
`coupon_template_id` bigint(20) DEFAULT NULL COMMENT '优惠券模板ID',
`send_type` tinyint(1) DEFAULT NULL COMMENT '发送类型 0:立即发送 1:定时发送',
`send_time` datetime DEFAULT NULL COMMENT '发送时间',
`status` tinyint(1) DEFAULT NULL COMMENT '状态 0:待执行 1:执行中 2:执行失败 3:执行成功 4:取消',
`completion_time` datetime DEFAULT NULL COMMENT '完成时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`operator_id` bigint(20) DEFAULT NULL COMMENT '操作人',
`update_time` datetime DEFAULT NULL COMMENT '修改时间',
`del_flag` tinyint(1) DEFAULT NULL COMMENT '删除标识 0:未删除 1:已删除',
PRIMARY KEY (`id`),
KEY `idx_batch_id` (`batch_id`) USING BTREE,
KEY `idx_coupon_template_id` (`coupon_template_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1816672964423188483 DEFAULT CHARSET=utf8mb4 COMMENT='优惠券模板发送任务表';

因为这种优惠券分发任务不会太多,所以我们默认不进行分库分表,ShardingSphere 5.3.2 对于没有配置分库分表逻辑的表,默认从第一个数据源读取。

我们针对一些核心字段做个讲解:

  • file_address:文件地址,保存分发目标用户的 Excel 文件地址。
  • fail_file_address:发放失败用户文件地址,如果发放执行过程中失败,需要保存错误信息生成一个新的 Excel。
  • send_num:发放优惠券数量,file_address 中共有多少条记录,方便后续记录是否发放完成。

Git 分支

20240822_dev_create-coupon-task_easyexcel_ding.ma

生成百万测试 Excel 文件

1. Excel 中有哪些字段?

上面的数据库表中有个字段是通知方式,一共有四个值:

  • 站内信:需要用户 ID。
  • 弹框推送:需要用户 ID。
  • 邮箱:需要用户邮箱,这个属于是考虑到了,实际中基本不存在。
  • 短信:需要用户手机号,有些公司考虑到用户隐私泄露问题,可能也是记录用户 ID,发送时查询用户接口获取。

那基于上面的描述,我们需要搞三个字段,用户 ID、邮箱、手机号,接下来开始模拟记录。

2. 什么是 Faker?

此 Faker 非彼 Faker。咱们这个章节聊的 Faker 是一个开源库,提供了生成伪随机数据的功能。该库可以用来生成各种各样的测试数据,例如姓名、地址、电话号码、电子邮件、公司名、日期等。

那我们先引入,试试效果怎么样。

2.1 引入 Faker Maven 依赖

<!-- Mock 数据相关依赖 -->
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>
<scope>test</scope>
<version>1.0.2</version>
</dependency>

2.2 写个单元测试

通过一个简单的单元测试让大家熟悉下 Faker 怎么使用。

package com.nageoffer.onecoupon.merchant.admin.task;

import com.github.javafaker.Address;
import com.github.javafaker.Faker;
import com.github.javafaker.PhoneNumber;
import org.junit.jupiter.api.Test;

import java.util.Locale;

/**
* Faker 单元测试类
*/
public class FakerTests {

@Test
public void testFaker() {
// 创建一个 Faker 实例
Faker faker = new Faker(Locale.CHINA);

// 生成中文名
String chineseName = faker.name().fullName();
System.out.println("中文名: " + chineseName);

// 生成手机号
PhoneNumber phoneNumber = faker.phoneNumber();
String mobileNumber = phoneNumber.cellPhone();
System.out.println("手机号: " + mobileNumber);

// 生成电子邮箱
String email = faker.internet().emailAddress();
System.out.println("电子邮箱: " + email);
}
}

打印日志如下:

中文名: 沈烨霖
手机号: 15109362990
电子邮箱: 明哲.孙@gmail.com

解锁付费内容,👉 戳