1、添加依赖
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency>
2、xls和xlsx的区别介绍
- xls是Excel03版本,最大支持65536行、256列,poi 操作xls,使用HSSFWorkbook
- xlsx是Excel007版本,最大支持1048576行、16384列,poi-ooml操作xlsx,使用XSSFWorkbook
3、代码示例,读取Excel
/*** 读.xlsx文件*/
private static List<List<String>> readXlsx(String path) throws Exception {InputStream is = Files.newInputStream(Paths.get(path));XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);List<List<String>> result = new ArrayList<List<String>>();// 循环每一页,并处理当前循环页 (sheet 页)int numberOfSheets = xssfWorkbook.getNumberOfSheets();for (int i = 0; i < numberOfSheets; i++) {XSSFSheet sheetAt = xssfWorkbook.getSheetAt(i);if (sheetAt == null) {continue;}// 从第一行一直循环到当前sheet的最后一行for (int rowNum = 1; rowNum <= sheetAt.getLastRowNum(); rowNum++) {// 获取行数据,然后在获取列数据XSSFRow xssfRow = sheetAt.getRow(rowNum);int minColIx = xssfRow.getFirstCellNum();int maxColIx = xssfRow.getLastCellNum();List<String> rowList = new ArrayList<String>();for (int colIx = minColIx; colIx < maxColIx; colIx++) {XSSFCell cell = xssfRow.getCell(colIx);if (cell == null) {continue;}rowList.add(cell.toString());}result.add(rowList);}}return result;
}/*** 读.xls文件*/
private static List<List<String>> readXls(String path) throws IOException {InputStream is = Files.newInputStream(Paths.get(path));HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);List<List<String>> result = new ArrayList<List<String>>();int numberOfSheets = hssfWorkbook.getNumberOfSheets();for (int i = 0; i < numberOfSheets; i++) {HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(i);if (hssfSheet == null) {continue;}int firstRowNum = hssfSheet.getFirstRowNum();int lastRowNum = hssfSheet.getLastRowNum();for (int rowIx = firstRowNum; rowIx < lastRowNum; rowIx++) {HSSFRow row = hssfSheet.getRow(rowIx);int minColIx = row.getFirstCellNum();int maxColIx = row.getLastCellNum();List<String> rowList = new ArrayList<String>();for (int colIx = minColIx; colIx < maxColIx; colIx++) {HSSFCell cell = row.getCell(colIx);if (cell == null) {continue;}rowList.add(cell.toString());}result.add(rowList);}}return result;
}
4、代码示例,写Excel (HSSFWorkBook类似)
// 将上面读取的数据,在重新写到一个新的文件中
private static void writeXlsx(List<List<String>> dataList, String destPath) throws IOException {// 创建一个工作簿XSSFWorkbook xssfWorkbook = new XSSFWorkbook();Sheet sheet001 = xssfWorkbook.createSheet("sheet001");for (int i = 0; i < dataList.size(); i++) {Row row = sheet001.createRow(i);List<String> rowData = dataList.get(i);for (int j = 0; j < rowData.size(); j++) {Cell cell = row.createCell(j);cell.setCellValue(rowData.get(j));}}FileOutputStream fileOutputStream = new FileOutputStream(destPath);xssfWorkbook.write(fileOutputStream);fileOutputStream.close();
}
5、合并单元格 --- addMergedRegion
private static void mergeWithXSSF(String destPath) throws IOException {XSSFWorkbook xssfWorkbook = new XSSFWorkbook();XSSFSheet sheet = xssfWorkbook.createSheet("new Sheet");XSSFRow row = sheet.createRow(1);XSSFCell cell = row.createCell(1);cell.setCellValue("测试合并单元格");// 按照范围合并单元格sheet.addMergedRegion(new CellRangeAddress(1, 1, 1, 2));FileOutputStream fileOutputStream = new FileOutputStream(destPath);xssfWorkbook.write(fileOutputStream);fileOutputStream.close();
}
合并效果:
6.合并单元格的优化 ----- addMergedRegionUnsafe
当我们还使用addMergedRegion方法的时候,比如循环10000次合并操作,可以计算一下耗时
private static void mergeWithXSSF1(String destPath) throws IOException {XSSFWorkbook xssfWorkbook = new XSSFWorkbook();XSSFSheet sheet = xssfWorkbook.createSheet("new Sheet");long startTime = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {XSSFRow row = sheet.createRow(i);XSSFCell cell = row.createCell(1);cell.setCellValue("测试合并单元格");sheet.addMergedRegion(new CellRangeAddress(i, i, 1, 2));}long endTime = System.currentTimeMillis();System.out.println("耗费时间: " + (endTime - startTime));FileOutputStream fileOutputStream = new FileOutputStream(destPath);xssfWorkbook.write(fileOutputStream);fileOutputStream.close();
}耗费时间: 22918
如果换成addMergedRegionUnsafe方法,同样循环10000次合并操作,计算了一下耗时
private static void mergeWithXSSF1(String destPath) throws IOException {XSSFWorkbook xssfWorkbook = new XSSFWorkbook();XSSFSheet sheet = xssfWorkbook.createSheet("new Sheet");long startTime = System.currentTimeMillis();for (int i = 0; i < 10000; i++) {XSSFRow row = sheet.createRow(i);XSSFCell cell = row.createCell(1);cell.setCellValue("测试合并单元格");// 改成不校验sheet.addMergedRegionUnsafe(new CellRangeAddress(i, i, 1, 2));}long endTime = System.currentTimeMillis();System.out.println("耗费时间: " + (endTime - startTime));FileOutputStream fileOutputStream = new FileOutputStream(destPath);xssfWorkbook.write(fileOutputStream);fileOutputStream.close();
}耗费时间: 926
可以看到,消耗的时间是大大减少的。