简体   繁体   中英

Getting Excel fill colors using Apache POI

I'm using Apache POI 3.17 to read an Excel 2013 workbook. The workbook is created and edited by users directly in Excel. I then run a Java 8 program that uses POI to read and process the workbook.

Some cells are color-coded and so I need to obtain the fill color. In many cases this works fine, but there are a set of grey/silver colors where it does not work and I'm unsure as to why.

As an example, the Excel cells look like this:

Excel示例

My code for obtaining the fill color is:

private String getFillColor(XSSFCell cell) {
    String fColorString = "None";
    if (cell != null) {
        XSSFCellStyle cellStyle = cell.getCellStyle();

        short sColorFore = cellStyle.getFillForegroundColor();
        short sColorBack = cellStyle.getFillBackgroundColor();
        XSSFColor xColorFore =  cellStyle.getFillForegroundColorColor();
        XSSFColor xColorBack =  cellStyle.getFillBackgroundColorColor();

        String s = "";
        s += " indexFore=" + sColorFore;
        s += " indexBack=" + sColorBack;
        s += " colorFore=" + ((xColorFore == null) ? "Null" : xColorFore.getARGBHex());
        s += " colorBack=" + ((xColorBack == null) ? "Null" : xColorBack.getARGBHex());
        System.out.println("Cell=" + cell.getAddress() + " " + cell.getStringCellValue() + s);

        if (xColorFore != null) {
            fColorString = xColorFore.getARGBHex();
        }8
    }
    return fColorString;
}

The results of this when called for each of the example Excel cells above are:

Cell=BBH52 Pink indexFore=0 indexBack=64 colorFore=FFF79646 colorBack=null

Cell=BBH53 No fill indexFore=64 indexBack=64 colorFore=Null colorBack=Null

Cell=BBH54 Grey 1 indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Cell=BBH55 Grey 2 indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Cell=BBH56 Grey 3 indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Cell=BBH57 Grey 4 indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Cell=BBH58 Grey 5 indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Cell=BBH59 White indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null

Any idea why the shades of Grey and White all translate to a Hex value of FFFFFFFF? Is there a more correct method to access the actual fill color? Thanks.

The "Excel 2013 workbook" is a workbook stored in Office Open XML format. There the colors may have an extra 4th alpha channel but also may have ColorType.Tint property set. So actually all grey shades are RGB white FFFFFF having different tint set. For example in xl/styles.xml the Grey 1 is:

...
<fill>
 <patternFill patternType="solid">
  <fgColor theme="0" tint="-0.0499893185216834"/>
  <bgColor indexed="64"/>
 </patternFill>
</fill>
...

Theme color 0 is white FFFFFF and the tint -0.0499893185216834 is darkening that white to grey.

So we must take the tint into account. Fortunaltely apache poi 's ExtendedColor provides method getRGBWithTint for this.

So the following example gets the fill colors properly also if they have tint set:

import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.hssf.util.HSSFColor;

public class ReadExcelColorHavingTint {

 private static String getFillColorHex(Cell cell) throws Exception { 
  String fillColorString = "none";
  if (cell != null) {
   CellStyle cellStyle = cell.getCellStyle();
   Color color =  cellStyle.getFillForegroundColorColor();
   if (color instanceof XSSFColor) {
    XSSFColor xssfColor = (XSSFColor)color;
    byte[] argb = xssfColor.getARGB();
    fillColorString = "[" + (argb[0]&0xFF) + ", " + (argb[1]&0xFF) + ", " + (argb[2]&0xFF) + ", " + (argb[3]&0xFF) + "]";
    if (xssfColor.hasTint()) {
     fillColorString += " * " + xssfColor.getTint();
     byte[] rgb = xssfColor.getRGBWithTint();
     fillColorString += " = [" + (argb[0]&0xFF) + ", " + (rgb[0]&0xFF) + ", " + (rgb[1]&0xFF) + ", " + (rgb[2]&0xFF) + "]" ;
    }
   } else if (color instanceof HSSFColor) {
    HSSFColor hssfColor = (HSSFColor)color;
    short[] rgb = hssfColor.getTriplet();
    fillColorString = "[" + rgb[0] + ", " + rgb[1] + ", "  + rgb[2] + "]";
   }
  }
  return fillColorString;
 }

 public static void main(String[] args) throws Exception {
  Workbook workbook = WorkbookFactory.create(new FileInputStream("workbook.xlsx"));
  //Workbook workbook = WorkbookFactory.create(new FileInputStream("workbook.xls"));
  Sheet sheet = workbook.getSheetAt(0);
  for (Row row : sheet) {
   for (Cell cell : row) {

    System.out.println("Cell=" + cell.getAddress() + " " + cell.toString() + " " + getFillColorHex(cell));

   }
  }
 }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM