gpt4 book ai didi

java - Apache POI 不应用某些颜色索引

转载 作者:行者123 更新时间:2023-12-02 09:12:13 25 4
gpt4 key购买 nike

这里是 Java 8 和 Apache POI 4.1.x。我有一些 Java 代码,可以将对象列表写入 Excel 文件,并且它的工作完美正常,除了我尝试应用的一些基于颜色的单元格样式:

public void applyPriceListDataCellStyle(PriceListItem priceListItem, Cell cell) {

short colorIndex;
switch(priceListItem.getChangeType()) {
case ADDITION:
colorIndex = IndexedColors.YELLOW.getIndex();
break;
case DELETION:
XSSFColor purple = new XSSFColor(new java.awt.Color(120,81,169), new DefaultIndexedColorMap());
colorIndex = purple.getIndex();
break;
case PRICE_ADJUSTMENT_INCREASE:
colorIndex = IndexedColors.RED.getIndex();
break;
case PRICE_ADJUSTMENT_DECREASE:
colorIndex = IndexedColors.GREEN.getIndex();
break;
default:
// NO_CHANGE (leave unstyled)
colorIndex = IndexedColors.WHITE.getIndex();
break;
}

Map<String,Object> cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, colorIndex);
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);

CellUtil.setCellStyleProperties(cell, cellProps);

}

以上,applyPriceListDataCellStyle方法在 Cell 之后调用是从 Row 创建的目的。 cell然后将实例连同我的 PriceListItem 作为参数传递到此方法中bean(这是我写入 Excel 文件中每一行的数据)。

PriceListItem bean 有一个 ChangeType属性(枚举),指示单元格在最终 Excel 文件中应显示的颜色。

在运行时,我在每个 PriceListItems 的 5 个不同行(因此 5 个不同的 ChangeType )的单元格上调用此方法值,我得到的输出如下所示:

enter image description here

所以:

  • 第一行是“NO_CHANGE ”(映射到 IndexedColors.WHITE ),正如预期的那样,工作得很好
  • 第二行是“ADDITION ”(映射到 IndexedColors.YELLOW ),正如预期的那样,工作得很好
  • 第三行是“DELETION ”(映射到我的自定义 purple 颜色)显示为深黑色 - 错误!
  • 第四行,即“PRICE_ADJUSTMENT_INCREASE ”(映射到 IndexedColors.RED )显示为灰色 - 错误!
  • 第 5 行,即“PRICE_ADJUSTMENT_DECREASE ”(映射到 IndexedColors.GREEN )显示较浅的灰色阴影 - 错误!

在这些不同行的单元格上设置颜色时我在哪里出错了?

最佳答案

apache poi CellUtil 仅适用于 org.apache.poi.ss.* 。它无法使用 XSSFColor 工作,因为 org.apache.poi.ss.usermodel.CellStyle 没有方法从 XSSFColor 获取/设置填充前景色。它只能使用 IndexedColors 中的 short 颜色索引。因此是黑色,因为在您的代码中 purple.getIndex() 始终返回 0 。因此,如果应使用 CellUtil(推荐),请从 IndexedColors 中选择颜色,而不是创建自定义颜色。例如有IndexedColors.VIOLET

但是其他错误的情况对我来说是无法重现的。以下 Minimal, Reproducible Example 按预期对我有用。它需要一个至少有一个工作表的 price-list-template.xlsx

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

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PoiColors {

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

List<PriceListItem> priceList = new ArrayList<>();

PriceListItem noChange = new PriceListItem();
noChange.modelNumber = "123";
noChange.price = BigDecimal.valueOf(1.99);
noChange.changeType = ChangeType.NO_CHANGE;

PriceListItem addition = new PriceListItem();
addition.modelNumber = "456";
addition.price = BigDecimal.valueOf(2.99);
addition.changeType = ChangeType.ADDITION;

PriceListItem deletion = new PriceListItem();
deletion.modelNumber = "789";
deletion.price = BigDecimal.valueOf(3.99);
deletion.changeType = ChangeType.DELETION;

PriceListItem increase = new PriceListItem();
increase.modelNumber = "234";
increase.price = BigDecimal.valueOf(4.99);
increase.changeType = ChangeType.PRICE_ADJUSTMENT_INCREASE;

PriceListItem decrease = new PriceListItem();
decrease.modelNumber = "345";
decrease.price = BigDecimal.valueOf(5.99);
decrease.changeType = ChangeType.PRICE_ADJUSTMENT_DECREASE;

priceList.add(noChange);
priceList.add(addition);
priceList.add(deletion);
priceList.add(increase);
priceList.add(decrease);

new PoiColors().exportPriceList(priceList, "acme.xlsx");

}

private void exportPriceList(
List<PriceListItem> priceList,
String targetAbsPath) throws IOException {

// set variables based on specified format
String templateName = "price-list-template.xlsx";

// load the template
InputStream inp = this.getClass().getClassLoader().getResource(templateName).openStream();
Workbook workbook = WorkbookFactory.create(inp);

Sheet sheet = workbook.getSheetAt(0);
workbook.setSheetName(workbook.getSheetIndex(sheet), "ACME");

// plug in the header/metadata info and format some headers so they get autosized properly
Row row2 = CellUtil.getRow(1, sheet);
Cell c2 = CellUtil.getCell(row2, 2);
c2.setCellValue("ACME");


// create the data rows and apply styling
// start at row #11 which is where data rows begin
int rowNum = 11;

// rip through the items and write them to the rows; apply styling as appropriate
for (PriceListItem priceListItem : priceList) {

Row nextRow = sheet.createRow(rowNum);

Cell changeType = nextRow.createCell(0);
changeType.setCellValue(priceListItem.changeType.name());
applyPriceListDataCellStyle(priceListItem, changeType);

Cell modelNumber = nextRow.createCell(1);
modelNumber.setCellValue(priceListItem.modelNumber);
applyPriceListDataCellStyle(priceListItem, modelNumber);

Cell price = nextRow.createCell(2);
price.setCellValue(priceListItem.price.doubleValue());
applyPriceListDataCellStyle(priceListItem, price);

rowNum++;

}

// resize the columns appropriately
for (int c = 0; c < 3; c++) {
sheet.autoSizeColumn(c);
}


// export to file system
FileOutputStream fos = new FileOutputStream(targetAbsPath);
workbook.write(fos);

fos.close();
inp.close();
workbook.close();

}

private void applyPriceListDataCellStyle(PriceListItem priceListItem, Cell cell) {

short colorIndex;
switch(priceListItem.changeType) {
case ADDITION:
colorIndex = IndexedColors.YELLOW.getIndex();
break;
case DELETION:
colorIndex = IndexedColors.VIOLET.getIndex();
break;
case PRICE_ADJUSTMENT_INCREASE:
colorIndex = IndexedColors.RED.getIndex();
break;
case PRICE_ADJUSTMENT_DECREASE:
colorIndex = IndexedColors.GREEN.getIndex();
break;
default:
// NO_CHANGE (leave unstyled)
colorIndex = IndexedColors.WHITE.getIndex();
break;
}

Map<String,Object> cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, colorIndex);
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);

CellUtil.setCellStyleProperties(cell, cellProps);

}

}

class PriceListItem {
public String modelNumber;
public BigDecimal price;
public ChangeType changeType;
}

enum ChangeType {
NO_CHANGE,
ADDITION,
DELETION,
PRICE_ADJUSTMENT_INCREASE,
PRICE_ADJUSTMENT_DECREASE
}

结果是 acme.xlsx ,如下所示:

enter image description here

<小时/>

使用 IndexedColors,在 Office Open XML /xl/styles.xml 中设置颜色,如下所示:

...
<fill>
<patternFill patternType="solid">
<fgColor indexed="13"/>
<bgColor indexed="64"/>
</patternFill>
</fill>
...

索引颜色不是由 RGB 给出的,而是从默认调色板中获取的。如果您怀疑电子表格计算应用程序使用与 Excel 不同的默认调色板,那么您可以使用以下代码进行测试:

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

import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

public class TestIndexedColors {

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

String templateName = "price-list-template.xlsx";
InputStream inp = TestIndexedColors.class.getClassLoader().getResource(templateName).openStream();
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);

Row row; Cell cell; int r = 11;
Map<String,Object> cellProps;
for (IndexedColors color : IndexedColors.values()) {
row = sheet.createRow(r++);
cell = row.createCell(0); cell.setCellValue(color.getIndex());
cell = row.createCell(1); cell.setCellValue(color.name());
cell = row.createCell(2);
cellProps = new HashMap<>();
cellProps.put(CellUtil.FILL_FOREGROUND_COLOR, color.getIndex());
cellProps.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
CellUtil.setCellStyleProperties(cell, cellProps);
}

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

它需要一个至少有一个工作表的price-list-template.xlsx。结果 acme.xlsx 显示使用当前默认调色板的所有可能索引颜色的索引、名称和颜色。

关于java - Apache POI 不应用某些颜色索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59311923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com