Excel处理方法

1.高效数据结构选择

1.1HashMap/HashSet

  • 适用场景:主键唯一且需要快速查找(如ID匹配、数据合并)。

  • 实现方式:将小表数据预加载到内存,通过主键构建HashMap<Key, Entity>,比对时直接通过O(1)复杂度查询。

  • 示例

    Map<String, Entity> smallTableMap = smallTableList.stream()
    .collect(Collectors.toMap(Entity::getId, Function.identity()));

    for (Entity entity : largeTableList) {
    Entity matched = smallTableMap.get(entity.getId());
    // 执行比对或合并操作
    }

2. 流式读取与分批次处理

2.1 逐行读取

  • 使用ReadListener逐行处理数据(EasyExcel特性),避免全量加载到内存。

  • 示例

    // 自定义监听器实现增量处理
    public class DataListener extends AnalysisEventListener<Entity> {
    @Override
    public void invoke(Entity entity, AnalysisContext context) {
    // 实时处理单行数据
    }
    }

2.2 分块处理

  • 对超大文件分批次读取(如每次处理1000行),降低内存峰值。
  • 结合数据库或缓存保存中间状态。

3. 多线程与并行处理

3.1 并行流

  • 对已加载到内存的数据使用并行流加速处理:

    largeTableList.parallelStream()
    .forEach(entity -> process(entity));

3.2 生产者-消费者模式

  • 独立线程读取Excel,由工作线程池处理数据,最大化IO和CPU利用率。

4. 预处理与数据优化

4.1 列裁剪

  • 仅读取需要的列,减少内存占用:

    ExcelReaderBuilder readerBuilder = EasyExcel.read(file)
    .head(Entity.class)
    .ignoreEmptyRow(true)
    .sheet()
    .addReadListener(listener);

4.2 数据格式优化

  • 避免使用字符串存储数值或日期,改用IntegerLocalDateTime等类型,提升比较和计算速度。

5. 差异化对比策略

5.1 排序后双指针遍历

  • 若两表数据有序,使用双指针法一次遍历完成比对,时间复杂度O(n)
  • 步骤
    1. 按主键排序两表数据。
    2. 双指针同步移动,比较当前行并记录差异。

5.2 布隆过滤器

  • 快速判断某主键不存在于另一表(减少不必要的精确查询)。