如何使用Java按字符串类型列对Excel行进行排序?
Java按指定列字符串值排序Excel行
下面是基于Apache POI库实现的方案,这是Java操作Excel最常用的工具库:
1. 添加依赖(Maven)
如果用Maven管理项目,先在pom.xml中加入POI相关依赖:
<dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
2. 核心实现代码
以下代码会加载已生成的Excel文件,按指定列(示例为第2列,索引从0开始计数)的字符串值排序行,最后保存为新文件:
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ExcelSorter { public static void main(String[] args) { String inputFilePath = "生成的Excel文件路径.xlsx"; String outputFilePath = "排序后的Excel文件路径.xlsx"; int sortColumnIndex = 1; // 要排序的列索引(从0开始,这里是第2列) try (Workbook workbook = new XSSFWorkbook(new FileInputStream(inputFilePath))) { Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 Row headerRow = sheet.getRow(0); // 获取表头行 // 提取所有数据行(跳过表头) List<Row> dataRows = new ArrayList<>(); for (int i = 1; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row != null) { dataRows.add(row); } } // 按指定列的字符串值排序 Collections.sort(dataRows, new Comparator<Row>() { @Override public int compare(Row row1, Row row2) { Cell cell1 = row1.getCell(sortColumnIndex); Cell cell2 = row2.getCell(sortColumnIndex); // 处理单元格为空的情况,空值排在前面 String value1 = cell1 == null ? "" : getCellStringValue(cell1); String value2 = cell2 == null ? "" : getCellStringValue(cell2); return value1.compareToIgnoreCase(value2); // 忽略大小写排序,如需区分大小写用compareTo } }); // 清空原工作表的数据行(保留表头) for (int i = sheet.getLastRowNum(); i >= 1; i--) { sheet.removeRow(sheet.getRow(i)); } // 将排序后的行重新写入工作表 int rowIndex = 1; for (Row row : dataRows) { Row newRow = sheet.createRow(rowIndex++); copyRow(row, newRow); } // 保存排序后的Excel try (FileOutputStream fos = new FileOutputStream(outputFilePath)) { workbook.write(fos); } System.out.println("Excel排序完成,已保存至:" + outputFilePath); } catch (IOException e) { e.printStackTrace(); } } // 辅助方法:获取单元格的字符串值,兼容不同单元格类型 private static String getCellStringValue(Cell cell) { CellType cellType = cell.getCellType(); switch (cellType) { case STRING: return cell.getStringCellValue(); case NUMERIC: // 数字转字符串,避免科学计数法 return String.valueOf((long) cell.getNumericCellValue()); case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: return cell.getCellFormula(); default: return ""; } } // 辅助方法:复制行数据 private static void copyRow(Row sourceRow, Row targetRow) { for (int i = 0; i < sourceRow.getLastCellNum(); i++) { Cell sourceCell = sourceRow.getCell(i); if (sourceCell != null) { Cell targetCell = targetRow.createCell(i); copyCell(sourceCell, targetCell); } } } // 辅助方法:复制单元格内容和样式 private static void copyCell(Cell sourceCell, Cell targetCell) { CellStyle sourceStyle = sourceCell.getCellStyle(); targetCell.setCellStyle(sourceStyle); switch (sourceCell.getCellType()) { case STRING: targetCell.setCellValue(sourceCell.getStringCellValue()); break; case NUMERIC: targetCell.setCellValue(sourceCell.getNumericCellValue()); break; case BOOLEAN: targetCell.setCellValue(sourceCell.getBooleanCellValue()); break; case FORMULA: targetCell.setCellFormula(sourceCell.getCellFormula()); break; default: targetCell.setCellValue(""); } } }
3. 关键说明
- 排序逻辑:使用
Collections.sort结合自定义Comparator,通过compareToIgnoreCase实现忽略大小写的字符串排序,如需区分大小写替换为compareTo即可。 - 空值处理:将空单元格视为空字符串,排在所有非空值前面,可根据需求调整排序规则。
- 兼容性:代码基于XSSFWorkbook(.xlsx格式),如果是旧版.xls格式,替换为
HSSFWorkbook即可。 - 样式保留:通过
copyCell方法复制原单元格的样式,确保排序后的Excel格式与原文件一致。
内容的提问来源于stack exchange,提问作者honeybadger
相关产品推荐
相关产品推荐

