一、easyexcel导出百万级数据思路
当需要将大量数据导出到Excel中时,使用easyexcel会非常便捷,它可以轻松地处理大批量数据,并提供了多种导出方式,例如导出到本地、输出到浏览器等。easyexcel的导出思路可以分为以下几个步骤:
1、使用EasyExcel对象创建一个输出流,通常使用response.getOutputStream()。
2、调用EasyExcel的write()方法依次写入需要导出到Excel的每一行数据。在处理百万级数据时,需要结合分页查询的方式,分批写入避免内存溢出。
3、将EasyExcel对象的finish()方法执行,将数据刷到Excel文件中。
4、将输出流关闭,结束导出操作。
以下是代码示例:
public void exportData(HttpServletResponse response) throws IOException { // 获取数据 ListdataList = 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; } // 获取数据 ListdataList = dataService.getDataList(startIndex, endIndex); // 创建Sheet对象 WriteSheet writeSheet = EasyExcel.writerSheet("数据"+i).build(); excelWriter.write(dataList, writeSheet); } // 关闭excelWriter对象 excelWriter.finish(); // 关闭输出流 outputStream.flush(); outputStream.close(); }