Java Apache Poi,如何同时设置背景颜色和边框?

19

首先我要说,我完全是新手,刚开始接触开发领域。

我尝试生成一个包含乘法表、有边框并设置背景颜色但只针对第一列和第一行的Excel表格。

这里有一个正确的示例: 正确示例

我写了类似下面的代码,但结果文件中有颜色的单元格没有边框 :(

请告诉我如何同时设置背景颜色和边框。

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;

import java.awt.image.IndexColorModel;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

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

        Scanner in = new Scanner(System.in);

        System.out.println("请输入行数: ");
        int x = in.nextInt();
        System.out.println("请输入列数: ");
        int y = in.nextInt();
        System.out.println("请输入文件名: ");
        String fileName = in.next() + ".xls";

        System.out.println("乘法表将被创建在文件 " + fileName + " 中");

        createExcelMultiplicationTable(fileName, x, y);

        System.out.println("进程执行成功");
    }

    private static void createExcelMultiplicationTable(String fileName, int x, int y) throws IOException {
        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet("multiplicationTable");

        CellStyle backgroundStyle = workbook.createCellStyle();

        backgroundStyle.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        backgroundStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

        CellStyle borderStyle = workbook.createCellStyle();

        borderStyle.setBorderBottom(CellStyle.BORDER_THIN);
        borderStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        borderStyle.setBorderLeft(CellStyle.BORDER_THIN);
        borderStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        borderStyle.setBorderRight(CellStyle.BORDER_THIN);
        borderStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        borderStyle.setBorderTop(CellStyle.BORDER_THIN);
        borderStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

        for (int i = 1; i <= x; i++) {
            Row row = sheet.createRow(i - 1);

            for (int j = 1; j <= y; j++) {
                Cell cell = row.createCell(j - 1);
                cell.setCellValue(i * j);
                cell.setCellStyle(borderStyle);

                if (cell.getRowIndex() == 0 || cell.getColumnIndex() == 0) {
                    cell.setCellStyle(backgroundStyle);
                }
            }
        }

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

也许这个链接能帮到你。 - lrnzcig
4个回答

28

backgroundStyle.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); 更改为

 backgroundStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());

你可以像下面这样设置边框:

        backgroundStyle.setBorderBottom(CellStyle.BORDER_THIN);
        backgroundStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        backgroundStyle.setBorderLeft(CellStyle.BORDER_THIN);
        backgroundStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        backgroundStyle.setBorderRight(CellStyle.BORDER_THIN);
        backgroundStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        backgroundStyle.setBorderTop(CellStyle.BORDER_THIN);
        backgroundStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

这将按要求为您提供黄色背景和边框


我检查了你的解决方案,但它与我的版本相同,只返回一个变量(打印背景或打印边框),使用此程序无法打印带边框的彩色单元格。但我找到了正确的解决方案。我创建了两种不同的样式。第一种样式仅打印边框,第二种样式打印边框并设置背景。它可以正常工作,但我几乎确定这里还有其他更简短的解决方案。 - Robert Lewandowski
看,我已经将setFillBackgroundColor更改为setFillForegroundColor。回到前景色。这肯定会改变你的背景颜色。你试过了吗?如果你只是复制粘贴我所提到的内容,它一定会起作用。 - Karthik
是的,当我按照你的建议去做时,它起作用了。总的来说,你的解决方案与我的类似。 - Robert Lewandowski
3
我认为你忘了提到.setFillPattern(FillPatternType.SOLID_FOREGROUND);,如果没有它,单元格的背景颜色不会改变。 - parsecer

23

从POI 3.x开始,单元格填充颜色设置如下:

CellStyle cs = wb.createCellStyle();
cs.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
cs.setFillPattern(FillPatternType.SOLID_FOREGROUND);

谢谢。然而编译器说,FillpatternType 无法转换为 short。因此必须使用 setFillPattern((short)1);。 - Monster Brain
1
cs.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()) cs.setFillPatternType(CellStyle.SOLID_FOREGROUND) with poi-3.14 - levolutionniste

12

你的真正问题在于你有两种样式,一种名为backgroundStyle,另一种名为borderStyle。然后你将两种样式都应用到同一个单元格上,但单元格只能有一个样式,因此你不是添加第二个样式,而是用第二个样式覆盖了第一个样式。

改为:

    CellStyle backgroundStyle = workbook.createCellStyle();

    backgroundStyle.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
    backgroundStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

    CellStyle borderStyle = workbook.createCellStyle();

    borderStyle.setBorderBottom(CellStyle.BORDER_THIN);
    borderStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
    borderStyle.setBorderLeft(CellStyle.BORDER_THIN);
    borderStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
    borderStyle.setBorderRight(CellStyle.BORDER_THIN);
    borderStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
    borderStyle.setBorderTop(CellStyle.BORDER_THIN);
    borderStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

只需创建一个类似这样的样式:

    CellStyle backgroundStyle = workbook.createCellStyle();

    backgroundStyle.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
    backgroundStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

    backgroundStyle.setBorderBottom(CellStyle.BORDER_THIN);
    backgroundStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
    backgroundStyle.setBorderLeft(CellStyle.BORDER_THIN);
    backgroundStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
    backgroundStyle.setBorderRight(CellStyle.BORDER_THIN);
    backgroundStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
    backgroundStyle.setBorderTop(CellStyle.BORDER_THIN);
    backgroundStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());

然后将其应用于您的单元格:

    Sheet sheet = workbook.createSheet();
    Row row = sheet.createRow(1);
    Cell cell = row.createCell(1);
    cell.setCellStyle(backgroundStyle);

注意: 如其他答案所述,对于FillPattern = SOLID_FOREGROUND,背景颜色将被忽略,您必须为该模式设置前景色。这可能会让人困惑,因为您试图将单元格背景设置为纯色。但是单元格背景背景颜色不同。单元格背景填充图案相同,具有前景色和背景色两种颜色,这些颜色基于所选的填充图案来显示。 SOLID_FOREGROUND填充仅使用前景色


2
请注意:+++++ 是注释符号! - Eljah

1
我找到了一种解决这个问题的方法,但我几乎确定还有其他更简短的方法。
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

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

        Scanner in = new Scanner(System.in);

        System.out.println("enter number of rows: ");
        int x = in.nextInt();
        System.out.println("enter number of columns: ");
        int y = in.nextInt();
        System.out.println("enter name of file: ");
        String fileName = in.next() + ".xls";

        System.out.println("Multiplication table will be created in file: " + fileName);

        createExcelMultiplicationTable(fileName, x, y);

        System.out.println("Process successful executed");
    }

    private static void createExcelMultiplicationTable(String fileName, int x, int y) throws IOException {
        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet("multiplicationTable");

        for (int i = 1; i <= x; i++) {
            Row row = sheet.createRow(i - 1);

            for (int j = 1; j <= y; j++) {
                Cell cell = row.createCell(j - 1);
                cell.setCellValue(i * j);

                if (cell.getRowIndex() == 0 || cell.getColumnIndex() == 0) {
                    CellStyle Style = workbook.createCellStyle();

                    Style.setFillBackgroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
                    Style.setFillPattern(CellStyle.BIG_SPOTS);
                    Style.setBorderBottom(CellStyle.BORDER_THIN);
                    Style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderLeft(CellStyle.BORDER_THIN);
                    Style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderRight(CellStyle.BORDER_THIN);
                    Style.setRightBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderTop(CellStyle.BORDER_THIN);
                    Style.setTopBorderColor(IndexedColors.BLACK.getIndex());

                    cell.setCellStyle(Style);
                } else {
                    CellStyle Style = workbook.createCellStyle();

                    Style.setBorderBottom(CellStyle.BORDER_THIN);
                    Style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderLeft(CellStyle.BORDER_THIN);
                    Style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderRight(CellStyle.BORDER_THIN);
                    Style.setRightBorderColor(IndexedColors.BLACK.getIndex());
                    Style.setBorderTop(CellStyle.BORDER_THIN);
                    Style.setTopBorderColor(IndexedColors.BLACK.getIndex());

                    cell.setCellStyle(Style);
             }
            }
        }

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

这个程序不会给你黄色背景。理解setFillBackgroundColor和setFillForegroundColor之间的区别。 - Karthik
我知道,我只是添加了一个黄色背景的图片作为示例。 - Robert Lewandowski
请勿在for循环内部创建单元格样式,如前所述。对于所有想要复制此代码的人,请将单元格样式的创建移至最外层循环之外。Excel只能处理有限数量的单元格样式。如果太多,将无法创建Excel文件。此外,如果您想稍后使用POI读取Excel,则可能会遇到“ZIP炸弹”! - Christian Lischnig

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