为什么设置工作簿颜色只有一个单元格在使用 poi 时有效

why set workbook color only one cell work when using poi

我正在设置 excel 单元格前景色,这是 Java 8 代码,如下所示:

 /**
 * @param cell
 */
private void setCellColor(Cell cell) {
    Workbook workbook = cell.getSheet().getWorkbook();
    CellStyle cellStyle = createStyle(workbook);
    cell.getRow().getCell(cell.getColumnIndex()).setCellStyle(cellStyle);
}

/**
 * @param cell
 */
private void setCellColor0(Cell cell) {
    Workbook workbook = cell.getSheet().getWorkbook();
    CellStyle cellStyle = createStyle(workbook);
    cell.getRow().getCell(1).setCellStyle(cellStyle);
}

在代码上下文中,我调用了两个函数来改变单元格的颜色。我发现只有一个细胞变成了红色。似乎新的设置单元格样式覆盖了旧单元格。我没有弄清楚为什么会这样,我应该怎么做才能避免这个问题?我想要的是让所有单元格都变成红色,从而调用 setCellColor 函数。我正在使用兴趣点:api group: 'org.apache.poi', name: 'poi', version: '4.0.0'。这是 createStyle 函数:

private CellStyle createStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        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();
        cellStyle.setFillForegroundColor(palIndex);
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return cellStyle;
    }

这没有用:

int idx = cell.getColumnIndex();
cell.getRow().getCell(idx).setCellStyle(cellStyle);

这没有用:

cell.setCellStyle(cellStyle);

这项工作:

cell.getRow().getCell(0).setCellStyle(cellStyle);

经过测试,我发现如果设置当前单元格的列,是行不通的。如果我设置的样式小于当前列。有用。例如,当前列索引为 5,我设置 0、1、2、3、4 列样式有效,但第 5 列无效。为什么当前单元格样式无法设置?我认为单元格是在上下文中创建的,这是设置样式的 class:

public class CellStyleWriteHandler extends AbstractCellStyleStrategy {

    @Override
    protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) {
        setCellColorEnhance(cell, IndexedColors.RED);
        // impl(cell,head,relativeRowIndex);
    }

    static void setCellColorEnhance(Cell cell, IndexedColors color) {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(CellUtil.FILL_FOREGROUND_COLOR, color.getIndex());
        properties.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
        CellUtil.setCellStyleProperties(cell, properties);
    }
}

你的代码是分配一个单元格,就可以了。 如果你想按行填充CellStyle,你需要使用
int cellNum = cell.getRow().getLastCellNum() , 并使用 for i 。 像 for (int j = 0; j < cellNum; j++) { row.getCell(j).setCellStyle(cellStyle); }

在 Excel 中,单元格样式存储在工作簿级别。多个工作表中的多个单元格可能共享相同的样式。单元格样式包含多种样式选项,例如字体、颜色、数字格式、对齐方式...

这就是为什么获取一个单元格的单元格样式并更改它是一个坏主意,因为可能有其他单元格共享相同的样式且不应更改。另外,为每个单元格创建自己的单元格样式也不是一个好主意,因为每个工作簿的唯一单元格 formats/cell 样式的数量是有限制的。参见 Excel specifications and limits

为了解决这个问题,Apache POI 提供了CellUtil。它的方法 CellUtil.setCellStyleProperties 能够为一个单元格设置特定的单元格样式属性,而不影响该单元格的其他样式选项。也是为了防止创建过多的样式达到限制。

下面的完整示例显示了如何使用 CellUtil 设置单元格颜色。如果单元格值包含单词“红色”或包含减号,例如因为负数值,它会更改给定工作簿所有工作表中所有单元格的颜色。

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;

import java.util.Map;
import java.util.HashMap;

public class UsingCellUtilToColorCells {
 
 static void setCellColor(Cell cell, IndexedColors color) {
  Map<String, Object> properties = new HashMap<String, Object>();
  properties.put(CellUtil.FILL_FOREGROUND_COLOR, color.getIndex());
  properties.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
  CellUtil.setCellStyleProperties(cell, properties);
 }
 
 public static void main(String[] args) throws Exception {
  //Workbook workbook = WorkbookFactory.create(new FileInputStream("./Template.xlsx")); String filePath = "./ExcelOut.xlsx";
  Workbook workbook = WorkbookFactory.create(new FileInputStream("./Template.xls")); String filePath = "./ExcelOut.xls";

  DataFormatter dataFormatter = new DataFormatter(java.util.Locale.US);
  FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();

  for (Sheet sheet : workbook) {
   for (Row row : sheet) {
    for (Cell cell : row) {
     String cellValue =  dataFormatter.formatCellValue(cell, formulaEvaluator);
     if (cellValue.contains("red") || cellValue.contains("-")) {
      setCellColor(cell, IndexedColors.RED);
      System.out.println(sheet.getSheetName() + ", " + cell.getAddress()+ ":" + cellValue + ", " + "cell color set to red");
     }
    }
   }   
  }

  FileOutputStream out = new FileOutputStream(filePath);
  workbook.write(out);
  out.close();
  workbook.close();
 }
}