EasyExcel导出百万级连表查询xlsx数据方法实测102万105秒

先看sql语句:查询全部数据时间14秒
在这里插入图片描述
分页查询10万数据时间1秒左右
在这里插入图片描述

连接点,分组都加了索引,没加索引可能要10来分钟,
sql详情:
在这里插入图片描述
对于百万级的数据如果一下查出来是会内存溢出的,所以需要分页查出来,分页放到excel表格中

直接上我写的代码:excel表头类就不沾出来了,每个人的都不一样

/**
     * 导出excel
     * */
    @RequestMapping("/export")
    @RequiresPermissions("b2b:contract:export")
    public void export(HttpServletResponse response) throws IOException {
        OutputStream outputStream = response.getOutputStream();
        String time = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date());
        //添加响应头信息
        response.setHeader("Content-disposition", "attachment; filename=" + "contract"+time+".xlsx");
        //设置类型
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        //设置头
        response.setHeader("Pragma", "No-cache");
        //设置头
        response.setHeader("Cache-Control", "no-cache");
        //设置日期头
        response.setDateHeader("Expires", 0);

        //获取总数据量
        Integer count = contractService.getCount(null);
        //如果总数据量多余10万,分页导出
        if(count>100000){
            //每页多少个
            int max=100000;
            //必须放到循环外,否则会刷新流
            ExcelWriter excelWriter=EasyExcel.write(outputStream).build();;
            for (int i=0;i<(count/max)+1;i++){
                List<ContractAndCompanyExcel> exportList = contractService.export(i *max,max);
                WriteSheet writeSheet = EasyExcel.writerSheet(i, "合同" + (i + 1)).head(ContractAndCompanyExcel.class)
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
                excelWriter.write(exportList,writeSheet);
            }

            //刷新流
            excelWriter.finish();
        }else {
            List<ContractAndCompanyExcel> exportList = contractService.export(null,null);
            EasyExcel.write(outputStream,ContractAndCompanyExcel.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("合同").doWrite(exportList);
        }

        outputStream.flush();
        response.getOutputStream().close();

    }

实测:导出用时105秒左右
在这里插入图片描述
每个表10万条
在这里插入图片描述

我这个肯定不是最优的方法,不过能用,如果您有更好的办法,或是我有什么错误,欢迎大牛指出或评论区分享出来,供大家交流学习谢谢!

  • 12
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
要通过EasyExcel导出百万SQL查询语句,可以使用以下步骤: 1. 使用Java中的EasyExcel库来读写Excel文件,可以在代码中添加以下依赖项: ``` <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency> ``` 2. 创建一个实体类来存储查询结果,例如: ``` public class QueryResult { private String column1; private String column2; // ... // getter and setter methods } ``` 3. 使用JDBC连接到数据库并执行SQL查询: ``` String url = "jdbc:mysql://localhost:3306/mydb"; String user = "root"; String password = "password"; Connection conn = DriverManager.getConnection(url, user, password); String sql = "SELECT column1, column2, ... FROM mytable WHERE ..."; PreparedStatement pstmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); pstmt.setFetchSize(Integer.MIN_VALUE); ResultSet rs = pstmt.executeQuery(); List<QueryResult> results = new ArrayList<>(); while(rs.next()) { QueryResult result = new QueryResult(); result.setColumn1(rs.getString("column1")); result.setColumn2(rs.getString("column2")); // ... results.add(result); } ``` 请注意,在处理大量数据时,需要使用`ResultSet.TYPE_FORWARD_ONLY`和`ResultSet.CONCUR_READ_ONLY`类型的结果集,并设置`fetchSize`为`Integer.MIN_VALUE`,这将使JDBC驱动程序尽可能快地将数据发送到客户端,以便EasyExcel可以及时处理它们。 4. 通过EasyExcel的写操作,将查询结果导出Excel文件中: ``` String fileName = "query_results.xlsx"; ExcelWriter writer = EasyExcel.write(fileName, QueryResult.class).build(); Sheet sheet = new Sheet(1, 0, QueryResult.class); writer.write(results, sheet); writer.finish(); ``` 5. 遍历查询结果并生成SQL查询语句: ``` StringBuilder sqlBuilder = new StringBuilder(); for(QueryResult result : results) { sqlBuilder.append("SELECT * FROM mytable WHERE column1 = '") .append(result.getColumn1()).append("' AND column2 = '") .append(result.getColumn2()).append("' AND ...;\n"); } ``` 6. 将生成的SQL查询语句写入磁盘: ``` String sqlFileName = "query.sql"; FileWriter sqlWriter = new FileWriter(sqlFileName); sqlWriter.write(sqlBuilder.toString()); sqlWriter.close(); ``` 请注意,在处理大量数据时,内存可能会成为一个问题。您可以考虑使用SXSSFWorkbook来处理大量数据,它可以在内存中保持较小的数据集,并将其写入磁盘。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZGIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值