您的位置:

easyexcel导出百万级数据

一、easyexcel导出百万级数据思路

当需要将大量数据导出到Excel中时,使用easyexcel会非常便捷,它可以轻松地处理大批量数据,并提供了多种导出方式,例如导出到本地、输出到浏览器等。easyexcel的导出思路可以分为以下几个步骤:

1、使用EasyExcel对象创建一个输出流,通常使用response.getOutputStream()。

2、调用EasyExcel的write()方法依次写入需要导出到Excel的每一行数据。在处理百万级数据时,需要结合分页查询的方式,分批写入避免内存溢出。

3、将EasyExcel对象的finish()方法执行,将数据刷到Excel文件中。

4、将输出流关闭,结束导出操作。

以下是代码示例:

public void exportData(HttpServletResponse response) throws IOException {
    // 获取数据
    List dataList = getDataList();
    // 设置文件名
    String fileName = "导出数据.xlsx";
    // 设置响应头
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
    // 创建输出流
    ServletOutputStream outputStream = response.getOutputStream();
    // 创建excel对象
    EasyExcel.write(outputStream, DataDTO.class).sheet("数据").doWrite(dataList);
    // 关闭输出流
    outputStream.flush();
    outputStream.close();
}

  

二、easyexcel导入大量数据

除了导出功能外,easyexcel还提供了大量数据导入的功能。与导出不同的是,easyexcel导入数据操作需要实现监听器(EasyExcelReadListener),而导出则不需要监听器。

导入大量数据时,需要分批读取Excel文件中的数据。读取Excel文件时,需要用到EasyExcel对象的read()方法,该方法中涉及到的listener参数就是实现了EasyExcelReadListener接口的监听器对象,可以在其中处理每个读取到的数据行。同时,还可以在监听器中处理Excel文件的读取进度及相关的异常情况,保证读取操作的顺利进行。

以下是代码示例:

public void importData(MultipartFile file) throws IOException {
    // 创建读取excel的输入流
    InputStream inputStream = file.getInputStream();
    // 创建监听器
    EasyExcel.read(inputStream, DataDTO.class, new DataListener()).sheet().doRead();
    // 关闭输入流
    inputStream.close();
}

public class DataListener extends AnalysisEventListener {

    // 每次读取3000条数据,然后存入数据库
    private static final int BATCH_COUNT = 3000;
    List
    dataList = new ArrayList<>();
    private DataService dataService = new DataService();

    @Override
    public void invoke(DataDTO dataDTO, AnalysisContext analysisContext) {
        dataList.add(dataDTO);
        if (dataList.size() >= BATCH_COUNT) {
            saveDataList();
            dataList.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveDataList();
    }

    private void saveDataList() {
        dataService.saveDataList(dataList);
    }
}

   
  

三、easyexcel导入百万级数据

当需要导入百万级数据时,需要特别注意导入操作的性能与稳定性。由于easyexcel仅使用内存来读取Excel文件,处理大量数据时会出现内存溢出的问题。因此,需要使用分批读取的方式,每次将一部分数据读取到内存中进行处理,避免一次性读入全部数据导致内存溢出。

以下是分批读取Excel文件并读取数据的代码示例:

public void importData(MultipartFile file) throws IOException {
    // 创建读取excel的输入流
    InputStream inputStream = file.getInputStream();
    // 创建workbook对象
    Workbook workbook = WorkbookFactory.create(inputStream);
    // 获取sheet总数
    int sheetCount = workbook.getNumberOfSheets();
    // 设置分页大小
    int pageSize = 3000;
    // 循环读取每一个sheet
    for (int i = 0; i < sheetCount; i++) {
        // 获取当前sheet
        Sheet sheet = workbook.getSheetAt(i);
        // 获取总行数
        int rowCount = sheet.getPhysicalNumberOfRows();
        // 遍历行,从第3行开始读取数据
        for (int j = 2; j < rowCount; j++) {
            // 创建一行数据对象
            DataDTO dataDTO = new DataDTO();
            // 获取当前行的单元格
            Row row = sheet.getRow(j);
            // 读取单元格数据
            dataDTO.setName(row.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());
            dataDTO.setAge((int) row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getNumericCellValue());
            dataDTO.setSex(row.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue());
            // 将数据保存到数据库
            dataService.saveData(dataDTO);
        }
    }
    // 关闭输入流与workbook对象
    inputStream.close();
    workbook.close();
}

四、easyexcel分批写入

在处理百万级数据时,为了防止一次性将全部数据写入Excel文件,导致内存溢出,需要使用分批写入的方式。EasyExcel提供了write()方法的重载方法,支持传入多个list集合,将多个集合中的数据依次写入到一个sheet中,避免一次性写入过多数据。

以下是分批写入Excel文件的代码示例:

public void exportData(HttpServletResponse response) throws IOException {
    // 总数据量
    int totalSize = dataService.getDataCount();
    // 分页大小
    int pageSize = 3000;
    // 总页码
    int totalPage = (totalSize + pageSize - 1) / pageSize;
    // 设置文件名
    String fileName = "导出数据.xlsx";
    // 设置响应头
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
    // 创建输出流
    ServletOutputStream outputStream = response.getOutputStream();
    // 创建excel对象
    ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
    // 分批写入数据
    for (int i = 1; i <= totalPage; i++) {
        // 计算起始索引
        int startIndex = (i - 1) * pageSize;
        // 计算结束索引
        int endIndex = i * pageSize;
        if (endIndex > totalSize) {
            endIndex = totalSize;
        }
        // 获取数据
        List dataList = dataService.getDataList(startIndex, endIndex);
        // 创建Sheet对象
        WriteSheet writeSheet = EasyExcel.writerSheet("数据"+i).build();
        excelWriter.write(dataList, writeSheet);
    }
    // 关闭excelWriter对象
    excelWriter.finish();
    // 关闭输出流
    outputStream.flush();
    outputStream.close();
}