简体   繁体   English

使用Apache POI获取Excel填充颜色

[英]Getting Excel fill colors using Apache POI

I'm using Apache POI 3.17 to read an Excel 2013 workbook. 我正在使用Apache POI 3.17来阅读Excel 2013工作簿。 The workbook is created and edited by users directly in Excel. 用户直接在Excel中创建和编辑工作簿。 I then run a Java 8 program that uses POI to read and process the workbook. 然后我运行一个Java 8程序,它使用POI来读取和处理工作簿。

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单元格如下所示:

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: 调用上面每个示例Excel单元格时的结果是:

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

Cell=BBH53 No fill indexFore=64 indexBack=64 colorFore=Null colorBack=Null Cell = BBH53无填充indexFore = 64 indexBack = 64 colorFore = Null colorBack = Null

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

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

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

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

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

Cell=BBH59 White indexFore=0 indexBack=64 colorFore=FFFFFFFF colorBack=null Cell = BBH59白色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? 知道为什么灰色和白色的阴影都转换为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. “Excel 2013工作簿”是以Office Open XML格式存储的工作簿。 There the colors may have an extra 4th alpha channel but also may have ColorType.Tint property set. 那里的颜色可能有额外的第4个alpha通道,但也可能有ColorType.Tint属性集。 So actually all grey shades are RGB white FFFFFF having different tint set. 实际上所有灰色阴影都是具有不同tint设置的RGB白色FFFFFF For example in xl/styles.xml the Grey 1 is: 例如,在xl/styles.xmlGrey 1是:

...
<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. 主题颜色0是白色FFFFFFtint -0.0499893185216834变暗,白色变为灰色。

So we must take the tint into account. 所以我们必须考虑tint Fortunaltely apache poi 's ExtendedColor provides method getRGBWithTint for this. Fortunaltely apache poiExtendedColor为此提供了方法getRGBWithTint

So the following example gets the fill colors properly also if they have tint set: 因此,如果它们具有tint集,则以下示例也正确获取填充颜色:

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));

   }
  }
 }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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