POI设置单元格背景为自定义颜色

39

我想将单元格背景设置为自定义颜色。
我使用 HSSFWorkbook (不能使用其他任何东西)。

HSSFPalette palette = aWorkBook.getCustomPalette();             
Color col = new Color(backgroundColor);                     
HSSFColor myColor  = palette.addColor((byte) 10, (byte) 11, (byte) 12); 

我遇到了这个错误:java.lang.RuntimeException: Could not find free color index


你已经定义了文件中颜色的最大数量吗?(Excel对各种事物都有硬限制,例如行和列的数量,还有样式等的数量) - Gagravarr
@kenny:你能否考虑接受下面的答案之一,如果它确实解决了你的问题? - veer7
6个回答

39

你之所以会遇到这个错误是因为调色板已满。你需要覆盖预设颜色。

这里是我正在使用的函数示例:

public HSSFColor setColor(HSSFWorkbook workbook, byte r,byte g, byte b){
    HSSFPalette palette = workbook.getCustomPalette();
    HSSFColor hssfColor = null;
    try {
        hssfColor= palette.findColor(r, g, b); 
        if (hssfColor == null ){
            palette.setColorAtIndex(HSSFColor.LAVENDER.index, r, g,b);
            hssfColor = palette.getColor(HSSFColor.LAVENDER.index);
        }
    } catch (Exception e) {
        logger.error(e);
    }

    return hssfColor;
}

然后将其用于背景颜色:

HSSFColor lightGray =  setColor(workbook,(byte) 0xE0, (byte)0xE0,(byte) 0xE0);
style2.setFillForegroundColor(lightGray.getIndex());
style2.setFillPattern(CellStyle.SOLID_FOREGROUND);

2
使用 Apache POI 版本 > 4,现在必须使用以下代码来获取颜色索引:HSSFColor.HSSFColorPredefined.LAVENDER.getIndex() - Yann39

28

请查看http://poi.apache.org/spreadsheet/quick-guide.html#CustomColors

自定义颜色

HSSF:

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
HSSFRow row = sheet.createRow((short) 0);
HSSFCell cell = row.createCell((short) 0);
cell.setCellValue("Default Palette");

//apply some colors from the standard palette,
// as in the previous examples.
//we'll use red text on a lime background

HSSFCellStyle style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.LIME.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

HSSFFont font = wb.createFont();
font.setColor(HSSFColor.RED.index);
style.setFont(font);

cell.setCellStyle(style);

//save with the default palette
FileOutputStream out = new FileOutputStream("default_palette.xls");
wb.write(out);
out.close();

//now, let's replace RED and LIME in the palette
// with a more attractive combination
// (lovingly borrowed from freebsd.org)

cell.setCellValue("Modified Palette");

//creating a custom palette for the workbook
HSSFPalette palette = wb.getCustomPalette();

//replacing the standard red with freebsd.org red
palette.setColorAtIndex(HSSFColor.RED.index,
        (byte) 153,  //RGB red (0-255)
        (byte) 0,    //RGB green
        (byte) 0     //RGB blue
);
//replacing lime with freebsd.org gold
palette.setColorAtIndex(HSSFColor.LIME.index, (byte) 255, (byte) 204, (byte) 102);

//save with the modified palette
// note that wherever we have previously used RED or LIME, the
// new colors magically appear
out = new FileOutputStream("modified_palette.xls");
wb.write(out);
out.close();

XSSF:

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

XSSFCellStyle style1 = wb.createCellStyle();
style1.setFillForegroundColor(new XSSFColor(new java.awt.Color(128, 0, 128)));
style1.setFillPattern(CellStyle.SOLID_FOREGROUND);

使用java.awt.Color在现代版本中不再适用。您可以更新一下示例吗? - carlspring

4

不要忘记调用这个方法。

style.setFillPattern(CellStyle.Align_Fill);

参数可能根据您的需求而有所不同。也许是CellStyle.FINE_DOTS或其他类似的参数。


1

在NPOI Excel的索引颜色中有57+个空闲槽位。

            Color selColor;

        var wb = new HSSFWorkbook();

        var sheet = wb.CreateSheet("NPOI");
        var style = wb.CreateCellStyle();
        var font = wb.CreateFont();
        var palette = wb.GetCustomPalette();

        short indexColor = 57; 
        palette.SetColorAtIndex(indexColor, (byte)selColor.R, (byte)selColor.G, (byte)selColor.B);

        font.Color = palette.GetColor(indexColor).Indexed;

在Java的POI中,将颜色设置为索引57+也很好用,谢谢。 - Acuao

0

Vlad's answer所指出的,您已经用完了免费颜色插槽。解决这个问题的一种方法是缓存颜色:每当尝试RGB组合时,程序应首先检查组合是否在缓存中;如果在缓存中,则应使用缓存中的颜色而不是从头开始创建新的颜色;只有当它们还没有在缓存中时才会创建新的颜色。

这是我使用的实现方式;它使用XSSF加上Guava's LoadingCache,并且旨在从CSS rgb(r, g, b)声明生成XSSF颜色,但将其适应于HSSF应该相对容易:

    private final LoadingCache<String, XSSFColor> colorsFromCSS = CacheBuilder.newBuilder()
            .build(new CacheLoader<String, XSSFColor>() {

                private final Pattern RGB = Pattern.compile("rgb\\(\\s*(\\d+)\\s*, \\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)");

                @Override
                public XSSFColor load(String style) throws Exception {
                    Matcher mat = RGB.matcher(style);
                    if (!mat.find()) {
                        throw new IllegalStateException("Couldn't read CSS color: " + style);
                    }                       
                    return new XSSFColor(new java.awt.Color(
                            Integer.parseInt(mat.group(1)), 
                            Integer.parseInt(mat.group(2)), 
                            Integer.parseInt(mat.group(3))));
                }

            });

也许其他人可以发布一个HSSF的等效版本? ;)

0

您可以使用以下方法设置自定义颜色 -

查看此链接 - 点击这里

XSSFWorkbook workbook = new XSSFWorkbook();

IndexedColorMap colorMap = workbook.getStylesSource().getIndexedColors();
Font tableHeadOneFontStyle = workbook.createFont();
        tableHeadOneFontStyle.setBold( true );
        tableHeadOneFontStyle.setColor( IndexedColors.BLACK.getIndex() );

XSSFCellStyle tableHeaderOneColOneStyle = workbook.createCellStyle();
        tableHeaderOneColOneStyle.setFont( tableHeadOneFontStyle );
        tableHeaderOneColOneStyle
                .setFillForegroundColor( new XSSFColor( new java.awt.Color( 255, 231, 153 ), colorMap ) );
        tableHeaderOneColOneStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
        tableHeaderOneColOneStyle = setLeftRightBorderColor( tableHeaderOneColOneStyle );
        tableHeaderOneColOneStyle = alignCenter( tableHeaderOneColOneStyle );

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