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);
        }
    }
相关推荐
别来无恙blwy6 小时前
SQL Server高可用自动故障转移失败(短时间内多次转移失败,只需一步可处理)
数据库·windows·sqlserver·负载均衡·可用性测试
石像鬼₧魂石10 小时前
SET的钓鱼网站钓鱼模块
windows·学习·ubuntu
喵了几个咪10 小时前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:Makefile 在后端开发中的应用与 Windows 环境配置
windows
love530love12 小时前
在 PyCharm 中配置 x64 Native Tools Command Prompt for VS 2022 作为默认终端
ide·人工智能·windows·python·pycharm·prompt·comfyui
gf132111112 小时前
python_制作视频开头_根据短句字长占总字幕的长度比例拆分
windows·python·音视频
非凡ghost12 小时前
eDiary电子日记本(记录生活点滴)
windows·学习·生活·软件需求
kaka-33312 小时前
微信小程序中使用 xlsx(xlsx.mini.min.js)实现 Excel 导入导出功能
javascript·微信小程序·excel
纸带13 小时前
如何理解USB 配置描述符wTotalLength位运算深度
linux·网络·windows
开开心心_Every13 小时前
优化C盘存储:自定义软件文档保存路径工具
java·网络·数据库·typescript·word·asp.net·excel
love530love13 小时前
Win11+RTX3090 亲测 · ComfyUI Hunyuan3D 全程实录 ③:diso 源码编译实战(CUDA 13.1 零降级)
开发语言·人工智能·windows·python·comfyui·hunyuan3d·diso