poi导出大量数据到Excel

使用SXSSFWorkbook导出

案例

java 复制代码
@Override
    public void getUserExport(UserExportDTO dto) {

        // 开始时间
        LocalDateTime time = LocalDateTime.now();

        // 准备后续查询需要使用的id集合
        List<Integer> userList = testMapper.getUserGetId();

        // 创建线程池(根据第二步查询的耗时情况调整大小)
//        ExecutorService executor = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                5,// 线程数量
                10,// 最大线程数量
                1,// 线程存活时间
                TimeUnit.MINUTES,// 存活时间单位
//                new ArrayBlockingQueue<>(600),// 任务队列
                new LinkedBlockingQueue<>(),// 任务队列 -无界队列 (容易内存溢出)
                Executors.defaultThreadFactory()// 线程工厂
        );

        // 使用线程安全的集合存储最终结果
        List<UserVO> voList = Collections.synchronizedList(new ArrayList<>());
        // 创建任务列表
        List<CompletableFuture<Void>> futures = new ArrayList<>();

        if (userList != null && userList.size() > 0){
            for (Integer id : userList) {
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    // 查询用户信息
                    UserVO userVO = testMapper.getUserFindByIdGetUserVO(id);
                    // 查询用户详情
                    List<UserDetails> userDetailsList = testMapper.getUserDetailsByUserId(id);
                    userVO.setUserDetailsList(userDetailsList);
                    voList.add(userVO);
                }, executor);

                // 收集任务
                futures.add(future);
            }
        }

        // 等待所有任务完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        // 关闭线程池
        executor.shutdown();

        // 查询结果赋值
        List<UserVO> voList2 = voList;
        // 处理最终结果排序问题
        voList2 = voList2.stream()
                .sorted(Comparator.comparing(UserVO::getId))
                .collect(Collectors.toList());

        // 数据处理完成时间
        LocalDateTime time2 = LocalDateTime.now();

        // ============================================

        try {
            // 创建一个新的工作簿
//            Workbook workbook = new XSSFWorkbook();
            // 创建SXSSFWorkbook,设置行访问窗口为100(内存中保留的行数)
            SXSSFWorkbook workbook = new SXSSFWorkbook(500);
            // 自动刷新临时文件
            workbook.setCompressTempFiles(true);

            // 创建一个新的工作表
            Sheet sheet = workbook.createSheet("Sheet1");

            // 设置标题
            Row row = sheet.createRow(0);
            String[] headers = {"id","姓名","性别","年龄","电话","地址"};
            for (int i = 0; i < headers.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellValue(headers[i]);
                // 设置列宽
                sheet.setColumnWidth(i,30 * 256);
            }
            // 设置行高
            row.setHeightInPoints(30);

            // 从第一行开始,第零行是标题
            int lineNumber = 1;
            // 设置每行数据
            for (int i = 0; i < voList2.size(); i++) {
                UserVO userVO = voList2.get(i);
                List<UserDetails> userDetailsList = userVO.getUserDetailsList();
                // id合并
                sheet.addMergedRegion(new CellRangeAddress(lineNumber,lineNumber + userDetailsList.size() - 1,0,0));
                // 姓名合并
                sheet.addMergedRegion(new CellRangeAddress(lineNumber,lineNumber + userDetailsList.size() - 1,1,1));
                // 性别合并
                sheet.addMergedRegion(new CellRangeAddress(lineNumber,lineNumber + userDetailsList.size() - 1,2,2));
                // 年龄
                sheet.addMergedRegion(new CellRangeAddress(lineNumber,lineNumber + userDetailsList.size() - 1,3,3));
                // 电话
                sheet.addMergedRegion(new CellRangeAddress(lineNumber,lineNumber + userDetailsList.size() - 1,4,4));

                for (UserDetails userDetails : userDetailsList) {
                    // 创建一行
                    row = sheet.createRow(lineNumber);

                    // 设置行高
                    row.setHeightInPoints(60);

                    // id
                    Cell cell = row.createCell(0);
                    cell.setCellValue(userVO.getId());

                    // 姓名
                    cell = row.createCell(1);
                    cell.setCellValue(userVO.getName());

                    // 性别
                    cell = row.createCell(2);
                    cell.setCellValue(userVO.getSex());

                    // 年龄
                    cell = row.createCell(3);
                    cell.setCellValue(userVO.getAge());

                    // 电话
                    cell = row.createCell(4);
                    cell.setCellValue(userDetails.getTel());

                    // 地址
                    cell = row.createCell(5);
                    cell.setCellValue(userDetails.getAddress());

                    // 增加一行
                    lineNumber = lineNumber + 1;
                }
            }

            // 请求头(这两种请求头二选一,具体不同点在于前端下载方式可能不同,二选一即可,可以都试试)
                response.setCharacterEncoding("UTF-8");
                response.addHeader("content-Type", "application/vnd.ms-excel");
                response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("用户导出.xlsx", "UTF-8"));

            ServletOutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            // 清理临时文件
            workbook.dispose();

            //关闭资源
            outputStream.flush();
            workbook.close();
            outputStream.close();

            // 数据导出完成时间
            LocalDateTime time3 = LocalDateTime.now();

            Duration duration = Duration.between(time, time2);
            Duration duration2 = Duration.between(time2, time3);

            System.out.println("数据处理时间:" + duration.toMillis());
            System.out.println("数据导出时间:" + duration2.toMillis());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
DBGPT对外API文件说明 以及 DBGPT对外API接口说明
数据库·windows·db-gpt
Bruce_Liuxiaowei2 小时前
Windows安全事件4625分析:检测登录失败与防范暴力破解
运维·windows·安全·网络安全
吕了了3 小时前
113 隐藏此电脑中的常用文件夹
运维·windows·系统
C++ 老炮儿的技术栈3 小时前
用密码学安全随机数生成256位密钥
c语言·开发语言·c++·windows·安全·密码学·visual studio
dubochao_xinxi4 小时前
fastapi 接收10g 以上的文件 pandas 读取超过 10GB 的 Excel 文件
excel·pandas·fastapi
天下·第二4 小时前
python处理【orc】下载压缩的.zip文件,windows和linux同时适配
linux·windows·python
凑齐六个字吧4 小时前
单细胞LIANA受配体分析框架学习
linux·服务器·windows
红石榴花生油4 小时前
RBAC权限配置 核心笔记
数据库·windows·笔记
不知所云,5 小时前
2.windows c/c++ 编译器安装, mingw和clang
c语言·c++·windows·mingw·clang·c编译器