APACHE POI 4.1:使用十六进制代码设置单元格背景颜色

4
我尝试了在stackoverflow上发布的不同解决方案,以将背景颜色应用于Apache POI生成的单元格,但没有任何作用。
我正在做类似以下的事情:
Workbook workbook = new XSSFWorkbook(); 
Sheet sheet = workbook.createSheet(sheetName);

XSSFCellStyle cellStyle = ((XSSFCellStyle) workbook.createCellStyle());

if (styleObject.getBgColor() != null) {
    java.awt.Color javaBdgColor = java.awt.Color.decode(voceStyle.getBgColor()); // this is #FFF000
    XSSFColor bgColor = new XSSFColor(javaBdgColor, new DefaultIndexedColorMap());
    cellStyle.setFillForegroundColor(bgColor.getIndex());
    cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}

Row newRow = Rowsheet.createRow(0);
Cell newCell = newRow.createCell(0);
newCell.setCellStyle(cellStyle);

// write file
String pathFileExport = buildPathExportFile("test-export");
FileOutputStream fileOut = new FileOutputStream(pathFileExport);
workbook.write(fileOut);
fileOut.close();

//close workbook
workbook.close();

return Paths.get(pathFileExport);

我认为我的代码没问题,但是每个被这样样式化的单元格都会有黑色背景。 black-cells 我对“DefaultIndexedColorMap”实例有些疑问,在调试时结果没有字段。

code debugger

此时,我不确定该做什么来解决问题。其他帖子中的每个人似乎都能让事情正常运作,但我仍然得到暗背景而不是黄色。

有什么建议吗? 提前致谢!

2个回答

14

如另一个答案所述,在定制颜色方面,使用setFillForegroundColor(XSSFColor color)而不是使用索引颜色在XSSFCellStyle中是必要的。但在XSSF中,还可以使用来自org.apache.poi.ss.usermodel.IndexedColors的索引颜色。如果不需要使用定制颜色,则这将是最兼容的方式。

但是也应该避免从java.awt.Color创建XSSFColor。构造函数XSSFColor(java.awt.Color clr, IndexedColorMap map)被标记为“仅测试”。而且在某些情况下,java.awt.Color将不可用。

因此,如果需要的是“从十六进制代码设置单元格背景颜色”,并且十六进制代码在String中,则可以使用org.apache.commons.codec.binary.Hex从该String中获取byte[]数组。 Apache commons codec已经是apache poi的一个依赖项。然后可以使用构造函数XSSFColor(byte[] rgb, IndexedColorMap colorMap)。目前尚未使用IndexedColorMap,因此可以将其设置为null。如果稍后IndexedColorMap获得任何用途,则无论如何都必须调整代码。

示例:

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import org.apache.commons.codec.binary.Hex;

class CreateXSSFColor {

 public static void main(String[] args) throws Exception {

  try (Workbook workbook = new XSSFWorkbook(); 
       FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {

   String rgbS = "FFF000";
   byte[] rgbB = Hex.decodeHex(rgbS); // get byte array from hex string
   XSSFColor color = new XSSFColor(rgbB, null); //IndexedColorMap has no usage until now. So it can be set null.

   XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
   cellStyle.setFillForegroundColor(color);
   cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);

   Sheet sheet = workbook.createSheet(); 
   Row row = sheet.createRow(0);
   Cell cell = row.createCell(0);
   cell.setCellValue("yellow");
   cell.setCellStyle(cellStyle);

   workbook.write(fileout);
  }

 }
}

像rgettman的解决方案一样,即使我不得不修复一些代码行,这个解决方案也完美地运行了。 实际上,我选择这个作为解决方案,因为它更加广泛,谈论到了代码可维护性。 只需注意,我使用String.replace("#","")从我的十六进制代码字符串“#FFF000”中删除了“#”字符。 - Tobet

2
我注意到在使用xlsx文件(XSSF)中处理颜色时,使用索引颜色不起作用。似乎在XSSFWorkbook中没有任何颜色的索引,因此您不能使用未索引的颜色索引。
但是,您可以使用直接采用XSSFColorsetFillForegroundColor重载方法
cellStyle.setFillForegroundColor(bgColor);

当我使用这个重载时,我得到了你所期望的黄色背景。
一般来说,在使用XSSF中的颜色时,应该使用XSSFColor本身,而不是它的索引。这同样适用于其他东西,比如另一个有图案的颜色(“背景”),边框颜色和字体颜色。

完美地工作了!非常感谢。 是的,使用索引颜色并不是很清晰,即使遵循API文档。 - Tobet

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