千百万级别数据导出核心代码

发布时间 2023-08-30 18:43:31作者: 栖林藏鱼

抓核心:导出效率 + 导出形式

解释: 导出效率:线程、 导出形式:压缩包

示例

// 第一步:创建压缩包输出流
        File dir = new File(path);
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
            }
        }
        String filePath = path + "文件名";
        File file = new File(filePath);
        ZipOutputStream outputStream = null;
        if (!file.exists()) {
            file.createNewFile();
        }
        outputStream = new ZipOutputStream(new FileOutputStream(file));

 

// 第二步: 数据压缩

// 数据总量
int total = "数据总量"
// 单文件总数据量 2<<11 = 2的12次方
Integer pageSize = 2<<11;  
 // 数据分页
int pageTotal = total % pageSize == 0 ? total/ pageSize : total / pageSize + 1;

// 注意: 这里pageSize 和  pageSize 配合数据库分页查询使用

 // 计量           
CountDownLatch countDownLatch = new CountDownLatch(pageTotal);

for (int i = 1; i <= pageTotal; i++) {
              // 自己实现PoiExportTask类 实现Runable接口  run方法里面放入生成excel逻辑以及将excel文件放入压缩输出流中
                PoiExportTask<JSONObject> task = new PoiExportTask<>();
                task.setColumns(columnList);//columnList: List<ExcelUtil.ExcelColumn> excel 表头
                task.setData(list);//list : 数据库分页查询
                task.setCountDownLatch(countDownLatch);
                task.setZipOutputStream(zipOutputStream);
                task.setIndexStr("["+(i - 1) * pageSize+"-"+((i - 1) * pageSize + pageSize)+"]");
                new Thread(task,"exportWithMultiThreadByPoi-"+i).start();
}
 countDownLatch.await();
zipOutputStream.close();    
// 第二步中,如何将excel放入zipoutstream压缩输出流中
if (workbook instanceof HSSFWorkbook) {
         //这里只是声明文件路径和名称
            filePath = filePath+"_"+index + ".xls"; 
        } else {
            filePath = filePath+"_"+index + ".xlsx";
        }

        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            //读取数据
            InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());

            zipOutputStream.putNextEntry(new ZipEntry(filePath));
            int len;
            byte[] buf = new byte[1024];
            while ((len = inputStream.read(buf)) > 0) {
                zipOutputStream.write(buf, 0, len);
            }
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            if(zipOutputStream != null) {
                try {
                    zipOutputStream.closeEntry();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }