带有 Apache POI 4 的 XSSFColor:单元格背景颜色被另一个单元格背景颜色覆盖

XSSFColor with Apache POI 4: cell background color gets overwritten by another cell background color

我 运行 使用 Apache POI 4.1.2 的以下代码:

        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet();
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell = row.createCell(0);
        cell.setCellValue("Cell one");

        XSSFCellStyle style = wb.createCellStyle();
        Color green = new Color(20, 230, 18);
        style.setFillForegroundColor(new XSSFColor(green, new DefaultIndexedColorMap()));
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cell.setCellStyle(style);

        cell = row.createCell(1);
        cell.setCellValue("cell two");
        Color red = new Color(200, 30, 18);
        style.setFillForegroundColor(new XSSFColor(red, new DefaultIndexedColorMap()));
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cell.setCellStyle(style);

        File outFile = new File(OUTPUT_DIR + "colors.xlsx");
        outFile.getParentFile().mkdirs();
        try (OutputStream fileOut = new FileOutputStream(outFile)) {
            wb.write(fileOut);
        }
        wb.close();

输出文档的两个单元格都有红色背景:似乎在第二个单元格上设置红色背景具有覆盖第一个单元格背景颜色的效果。

如果我仅在第一个单元格上设置背景,背景颜色会正确设置为绿色。

我该如何解决这个问题?

颜色不是存储在单元格中,而是存储在单元格样式中。因此,您需要根据需要创建尽可能多的单元格样式。

但也不要简单地为每个单元格创建单元格样式。唯一单元格 formats/cell 样式的最大数量为 Excel limits。如果超过该限制,工作簿就会损坏。

因此,在工作簿级别根据需要创建尽可能多的单元格样式。然后应用这些单元格样式,同时将单元格值填充到 sheet.

完整示例:

import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import java.util.List;
import java.util.ArrayList;

public class CreateExcelDifferentCellColors {

 public static void main(String[] args) throws Exception {
  XSSFWorkbook workbook = new XSSFWorkbook(); 
  
  // on workbook level create as much CellStyles as needed
  XSSFCellStyle greenCellStyle = workbook.createCellStyle();
  java.awt.Color green = new java.awt.Color(20, 230, 18);
  greenCellStyle.setFillForegroundColor(new XSSFColor(green, new DefaultIndexedColorMap()));
  greenCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);  
  
  XSSFCellStyle redCellStyle = workbook.createCellStyle();
  java.awt.Color red = new java.awt.Color(200, 30, 18);
  redCellStyle.setFillForegroundColor(new XSSFColor(red, new DefaultIndexedColorMap()));
  redCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        
  XSSFSheet sheet = workbook.createSheet(); 

  List<Number> numbers = new ArrayList<Number>();
  numbers.add(12); numbers.add(-12); numbers.add(12.1); numbers.add(-12.1); numbers.add(12.123); numbers.add(-12.123);

  int r = 0;
  for (Number number : numbers) {
   XSSFRow row = sheet.createRow(r++); 
   XSSFCell cell = row.createCell(0); 
   cell.setCellValue(number.doubleValue());
   if (number.doubleValue() < 0d) {
    cell.setCellStyle(redCellStyle);
   } else {
    cell.setCellStyle(greenCellStyle);   
   }
  } 

  FileOutputStream out = new FileOutputStream("./CreateExcelDifferentCellColors.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();
 }
}