Java 8和Apache POI4.1.x。我有一些Java代码,可以将对象列表写入Excel文件,并且可以正常工作[[perfectly,但我尝试应用的某些基于颜色的单元格样式除外:
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
)的单元格上调用此方法,并且得到如下所示的输出:
所以:
NO_CHANGE
”(映射到IndexedColors.WHITE
),按预期效果很好ADDITION
”(映射到IndexedColors.YELLOW
),按预期效果很好DELETION
”(映射到我的自定义purple
颜色)PRICE_ADJUSTMENT_INCREASE
”(映射到IndexedColors.RED
)PRICE_ADJUSTMENT_DECREASE
”(映射到IndexedColors.GREEN
)我要去哪里设置这些不同行的单元格上的颜色?
apache poi
CellUtil仅在使用org.apache.poi.ss.*
时有效。它无法使用XSSFColor
使用,因为org.apache.poi.ss.usermodel.CellStyle
没有方法从XSSFColor
获取/设置填充前景色。它仅适用于使用short
中的IndexedColors颜色索引。因此为黑色,因为在您的代码中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
,看起来像这样: