Java POI读取XLSX单元格填充颜色失败,求有效示例代码
读取XLSX单元格填充颜色的正确方法
你遇到的所有单元格返回颜色代码64的问题,核心原因有两个:
- POI中单元格的填充颜色实际是
FillForegroundColor,但只有当填充样式为SOLID_FOREGROUND时,这个颜色才会显示为单元格的背景色; - 当颜色使用默认索引时,
getFillForegroundColorColor()会返回null,此时需要通过颜色索引从工作簿的颜色映射表中获取实际颜色。
以下是修正后的有效代码:
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; public class ReadXlsxCellColor { public static void main(String[] args) throws IOException { String filepath = "你的文件路径.xlsx"; FileInputStream fileInputStream = new FileInputStream(filepath); XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream); XSSFSheet sheet = workbook.getSheetAt(0); int lastRowNum = sheet.getLastRowNum(); int lastCellNum = 0; // 先获取最大列数 for (int i = 0; i <= lastRowNum; i++) { // 注意这里要<=,因为getLastRowNum是索引,包含该行 Row rowValue = sheet.getRow(i); if (rowValue != null) { int temp = rowValue.getLastCellNum(); if (lastCellNum < temp) { lastCellNum = temp; } } } System.out.println("共 " + (lastRowNum + 1) + " 行,最大列数:" + lastCellNum); System.out.println(); // 遍历前4列的单元格 for (int j = 0; j < 4; j++) { for (int i = 0; i <= lastRowNum; i++) { Row rowValue = sheet.getRow(i); if (rowValue == null) { System.out.println("行 " + i + ",列 " + j + ":无数据"); continue; } Cell cell = rowValue.getCell(j); if (cell == null) { System.out.println("行 " + i + ",列 " + j + ":单元格为空"); continue; } CellStyle cellStyle = cell.getCellStyle(); // 先判断填充样式是否为实心填充 if (cellStyle.getFillPattern() == FillPatternType.SOLID_FOREGROUND) { XSSFColor color = (XSSFColor) cellStyle.getFillForegroundColorColor(); if (color != null) { byte[] rgb = color.getRgb(); System.out.println("行 " + i + ",列 " + j + ",填充颜色RGB:" + Arrays.toString(rgb)); } else { // 处理颜色索引的情况 short colorIndex = cellStyle.getFillForegroundColor(); // 从工作簿的颜色表获取对应颜色 XSSFColor indexedColor = workbook.getStylesSource().getIndexedColors().getColor(colorIndex); if (indexedColor != null) { byte[] rgb = indexedColor.getRgb(); System.out.println("行 " + i + ",列 " + j + ",填充颜色RGB(索引):" + Arrays.toString(rgb)); } else { System.out.println("行 " + i + ",列 " + j + ",填充颜色:无有效颜色"); } } } else { System.out.println("行 " + i + ",列 " + j + ",填充样式非实心,无填充颜色"); } // 读取单元格值(兼容不同类型) String cellValue; switch (cell.getCellType()) { case STRING: cellValue = cell.getStringCellValue(); break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { cellValue = cell.getDateCellValue().toString(); } else { cellValue = String.valueOf(cell.getNumericCellValue()); } break; case BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break; default: cellValue = "未知类型"; } System.out.println("行 " + i + ",列 " + j + ",单元格值:" + cellValue); System.out.println(); } } workbook.close(); fileInputStream.close(); } }
关键修正点说明
- 遍历行时改为
<= lastRowNum,因为getLastRowNum()返回的是最后一行的索引,需要包含该行; - 增加了填充样式的判断,只有
SOLID_FOREGROUND样式下,前景色才是单元格的填充背景色; - 处理了
getFillForegroundColorColor()返回null的情况,通过颜色索引获取实际颜色; - 优化了单元格值的读取逻辑,兼容不同数据类型。
内容的提问来源于stack exchange,提问作者user84592
相关产品推荐
相关产品推荐

