Apache POI XSSFColor从十六进制代码中获取颜色

49

我想将单元格的前景色设置为给定的十六进制颜色代码。例如,当我尝试将其设置为红色时:

style.setFillForegroundColor(new XSSFColor(Color.decode("#FF0000")).getIndexed());
无论我在解码函数的参数中设置什么十六进制值,getIndexed函数总是返回黑色。这可能是我做错了什么吗?我认为这是一个bug,但我不确定...

为什么需要 getIndexed()?为了向后兼容性吗?尝试将其删除。 - gtiwari333
如果您将样式应用于单元格,它是否会在Excel中正确显示为红色? - Gagravarr
2
我需要使用getindexed,因为该方法只接受一个short值。 - Neets
6个回答

102

好消息是,如果你正在使用XSSF而不是HSSF,那么解决你的问题相对简单。你只需要将你的样式变量强制转换为XSSFCellStyle即可。如果这样做,那么就有一个版本的setFillForegroundColor方法可以接受一个XSSFColor参数,所以你不需要调用getIndexed()。以下是一些示例代码:

XSSFCellStyle style = (XSSFCellStyle)cell.getCellStyle();
XSSFColor myColor = new XSSFColor(Color.RED);
style.setFillForegroundColor(myColor);

如果你正在使用HSSF,那么事情会比较困难。HSSF使用颜色调色板,即颜色数组。你传递给setFillForegroundColor的short值是调色板中的索引。

所以你需要解决的问题是将RGB值转换为调色板索引。你提出的解决方案,使用getIndexed(),在XSSFColor上并不像你想象的那样起作用。

幸运的是,有一个解决方案。暂且假设你满意于使用默认调色板中的一种颜色,而不是使用自定义颜色。在这种情况下,你可以使用HSSFPalette和HSSFColor类来解决问题。以下是一些示例代码:

HSSFWorkbook hwb = new HSSFWorkbook();
HSSFPalette palette = hwb.getCustomPalette();
// get the color which most closely matches the color you want to use
HSSFColor myColor = palette.findSimilarColor(255, 0, 0);
// get the palette index of that color 
short palIndex = myColor.getIndex();
// code to get the style for the cell goes here
style.setFillForegroundColor(palIndex);
如果您想使用默认调色板中没有的自定义颜色,则需要将它们添加到调色板中。HSSFPalette的Javadoc定义了您可以使用的方法来完成此操作。

我使用XSSF,所以第一个解决方案解决了问题。非常感谢! - Neets
1
这个 palette.findSimilarColor(255, 0, 0); 让我免于疯狂。非常感谢你。当然点赞了。 - Alkis Kalogeris
上述代码在我从工作簿中创建样式而不是像@JonathanL下面的答案那样从单元格中获取样式之前都无法正常工作。 - isaac.hazan
4
"new XSSFColor(Color.RED)" 现在已经被弃用。 - Jonathan Rosenne

37

对于 Apache POI 4.0 之前的版本,您可以简单地执行以下操作:

 XSSFColor grey = new XSSFColor(new java.awt.Color(192,192,192));
 cellStyle.setFillForegroundColor(grey);

自POI 4.0版本开始,您需要提供工作台IndexedColorMap:

 IndexedColorMap colorMap = workbook.getStylesSource().getIndexedColors();
 XSSFColor grey = new XSSFColor(new java.awt.Color(192,192,192), colorMap);
 cellStyle.setFillForegroundColor(grey);

4
这也可以起作用,并且提供了一种简单的方式将RGB颜色应用于单元格。 - Gleeb
请注意,由于依赖于AWT类,这可能会破坏您的服务器,并且服务器可能是无头的。我还没有检查过。 - Daniel
4
感谢提供 POI 4.0 示例,这对我帮助很大。我唯一建议的更改是不能添加 XSSFColor,而是必须添加 **.getIndex()**:cellStyle.setFillForegroundColor(grey.getIndex()) - leole
4
无论你使用什么 RGB 值,这将使细胞变为黑色。 - Tom Swifty
2
你好,我正在使用poi 4.0.1版本,但我的IDE无法识别在workbook.getStylesSource().getIndexedColors()中的getStyleSources()。你需要导入哪些内容?我已经导入了以下内容,但没有效果: import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.xssf.usermodel.IndexedColorMap; import org.apache.poi.xssf.model.StylesTable; - Guillaume
显示剩余2条评论

18
使用XSSFColor来操作XSSFWorkbookXSSFColor 可以接受byte[] rgb 或者一个 java.awt.Color参数。如下所示:
  1.  

    XSSFWorkbook wb = new XSSFWorkbook();
    XSSFCellStyle cellStyle = wb.createCellStyle();
    byte[] rgb = new byte[3];
    rgb[0] = (byte) 242; // red
    rgb[1] = (byte) 220; // green
    rgb[2] = (byte) 219; // blue
    XSSFColor myColor = new XSSFColor(rgb); // #f2dcdb
    cellStyle.setFillForegroundColor(myColor);
    cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
    
  2. see GuenSeven's answer

    XSSFColor myColor = new XSSFColor(new java.awt.Color(242, 220, 219)); // #f2dcdb
    cellStyle.setFillForegroundColor(myColor);
    cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
    

1
我无法使用.setFillForegroundColor(myColor);该怎么办? - meme
@meme,请升级到poi版本3.0.7或更高版本,我使用的是3.10版本。 - Jonathan L

4

我不想使用AWT的Color,因为现在已经没有只接受字节数组作为参数的构造函数了(我正在使用版本3.17)。但是,有一个构造函数public XSSFColor(byte[] rgb, IndexedColorMap colorMap)可以解决我的问题。

byte[] byteColor = new byte[]{255,0,0};
XSSFColor color = new XSSFColor(byteColor, null);

2

您可以使用以下代码从十六进制颜色值(FFEEDDCC或112233格式)中获取XSSFColor。如果您使用的是RGB,只需删除#字符:

XSSFWorkbook workbook = new XSSFWorkbook();
XSSFColor color = new XSSFColor(workbook.getStylesSource().getIndexedColors());
color.setARGBHex("#000000".substring(1));

0

XSSFCellStyle在poi 3.07以上版本的setFillForegroundColor方法中接受颜色参数...因此请先检查您的版本,以避免遇到我曾经遇到的问题...之前的版本需要使用short作为参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接