EasyExcel 写Excel超过限制自动切换sheet

EasyExcel 写Excel超过限制自动切换sheet

查询数据库超多表超百W数据量写Excel,这里有一个小常识,Excel 2007后版本,单个工作表的记录条数最多为1048576行,最大列数为16384列。如果多于单个sheet后自动切换新sheet

步骤描述

  1. 查数据:查询待写入Excel的数据,并将待写的数据放在一个List对象中
  2. 实例化sheet:判断总记录数,超过单sheet最大限制1048576行,计算sheet个数,否则写在一个sheet中
  3. 写Excel: EasyExcel.write方法写数据到Excel中
  4. 关闭: 写完后调用写相关操作 excelWriter.finsh

参考代码信息

1. 写入Excel中的对象

复制代码
package com.test.zhanglu
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ColumnWidth(30)
@HeadRowHeight(30)
public class ExcelBean {
    @ExcelProperty("测点类型")
    private String deviceNameStr;
    @ExcelProperty("测点编码")
    private String deviceNo;
    @ExcelProperty("实时值")
    private double value;
    @ExcelProperty("安装地址")
    private String deviceAddr;
    @ExcelProperty("实时时间")
    private String realTime;

2 Excel 写入方法逻辑

复制代码
package com.test.zhanglu

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.junit4.SpringRunner;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
public class WriteExcelTest {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void getList() {
        String path = "D:\\001document\\04\\01\\09\\数据样本集\\" + "data_" + DateUtils.format(new Date(), "yyyyMMdd") + ".xlsx";
        //单表最多存储数
        int sheetMaxNum = 1048576;
        //跑去表头,单页数据最大行数为限制减一条
        int pageSize = 1048575;
        //获取查询的数据库表名
        List<String> tableNames = getTableName(2023, 11);
        //创建ExceWriter对象
        ExcelWriter excelWriter = EasyExcel.write(path).build();
        //所有查询出来的数据放在一个对象中
        List<ExcelBean> result = new ArrayList<>(10000000);
        for (String tableName : tableNames) {
            List<ExcelBean> list = new ArrayList<>();
            boolean isExists = mongoTemplate.collectionExists(tableName);
            if (!isExists) {
                continue;
            }
            Query query = new Query();
            //mongoTemplate 模糊查询
            query.addCriteria(Criteria.where("deviceAddr").regex("zhanglu"));
            query.addCriteria(Criteria.where("deviceNo").regex("A"));
            query.fields().include("deviceNo").include("deviceNameStr").include("deviceAddr").include("realTime").include("value").exclude("_id");

            list = mongoTemplate.find(query, ExcelBean.class, tableName);
            System.out.println(tableName + ":" + list.size());
            result.addAll(list);

        }
        int sheetCount = 0;
        int total = result.size();
        System.out.println("===数据总量==" + total);
        //根据总数计算需要多少个sheet页
        if (total > sheetMaxNum) {
            sheetCount = total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1;
        } else {
            sheetCount = 1;
        }
        int currentIndex = 0;
        //按sheet页写数据
        for (int num = 1; num <= sheetCount; num++) {
            String stName = "测试数据-" + num;
            //实例化sheet对象,写个sheetNo,sheetName。这里敲黑板,需要写sheetNo,不然只有一个sheet没切换
            WriteSheet writeSheet = EasyExcel.writerSheet(num,stName).head(ExcelBean.class).build();
            System.out.println(stName);
            //计算当前sheet从第几条记录开始写。和分页是一个道理
            int fromIndex = pageSize * num;
            if (fromIndex >= total) {
                fromIndex = total;
            }
            //调用写的方法
            excelWriter.write(result.subList(currentIndex, fromIndex), writeSheet);
            //赋值给下一个sheet页的开始索引
            currentIndex = fromIndex;
        }
        //关闭写操作
        excelWriter.finish();

    }


  /**以下是查询表名的方法,查询多个数据表,表名规则是日期为后缀**/
  
   public static List<String> getTableName(int year, int month) {
        List<String> dates = new ArrayList<>();

        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1); // 设置为当前月的第一天

        int maxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); // 获取当前月的最大天数

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        for (int i = 1; i <= maxDay; i++) {
            calendar.set(Calendar.DAY_OF_MONTH, i);
            String date = dateFormat.format(calendar.getTime());
            String talbeName = "zhanglu.test_" + date + "_his_value";
            dates.add(talbeName);
        }

        return dates;
    }

知识小总结

1. sheet没切换,每次都写一个sheet中,超限报错

复制代码
原因: WriteSheet writeSheet = EasyExcel.writerSheet(num,stName).head(ExcelBean.class).build();
这行代码中 EasyExcel.writerSheet(num,stName).只给了一个sheetName参数,没给sheetNo。 如下所示:EasyExcel.writerSheet(stName)

2. Bean中常用注解说明

可参考官网:

https://easyexcel.opensource.alibaba.com/docs/current/api/write#注解

注解 说明 常用属性
ExcelProperty 用于匹配excel和实体类的匹配(可为表头显示的表名) value,order,index,converter
ExcelIgnore 默认所有字段都会和excel去匹配,加了这个注解会忽略该字段 -
DateTimeFormat 日期转换,用String去接收excel日期格式的数据会调用这个注解 value,use1904windowing
NumberFormat 数字转换,用String去接收excel数字格式的数据会调用这个注解。 value,roundingMode
相关推荐
hPw0eKIqD13 小时前
使用二次封装的Excel COM 组件操作Excel\WPS ET中的区域、行和列
excel·wps
笨鸟先飞,勤能补拙14 小时前
AI 赋能网络安全领域深度剖析
网络·人工智能·windows·安全·web安全·网络安全·github
我上去就是一套QWER然后等待复活15 小时前
Windows 清理 CC Switch 并恢复官方 Codex CLI 登录流程(完整记录)
windows
吾儿良辰16 小时前
一个被BCL遗忘的高性能集合:C# CircularBuffer<T>深度解析
开发语言·windows·c#
哎呦喂我去去去16 小时前
C#实现屏幕墙:同时监控多个电脑桌面(支持Windows、信创Linux、银河麒麟、统信UOS)
linux·windows·c#
脚踏实地皮皮晨20 小时前
002002002_DepandencyObject类2
开发语言·windows·算法·c#·visual studio
冰心孤城20 小时前
Excel: xls与xlsx格式转换排坑指南
java·前端·excel
驱动小百科20 小时前
Windows运行库合集下载 VC++、DirectX、.NET运行库安装教程
c++·windows·.net·windows运行库合集下载·windows运行库安装
05664621 小时前
Python康复训练——数据结构
数据结构·windows·python
软萌萌的11 天前
Python零基础从入门到精通详细教程-数据类型
开发语言·windows·python