使用Apache POI将填充颜色和边框应用于Excel范围

时间:2018-06-06 04:38:03

标签: java excel apache-poi

我正致力于使用Excel VBAJava脚本转换为Apache POI并且卡住了。在VBA中,很容易将填充颜色和边框连续应用于单元格。但是在POI中,如果不创建数百XSSFCellStyles [(每种颜色使用)x(每个边框组合)x(每个使用的字体)],似乎几乎不可能。我正在尝试重新创建此电子表格,该电子表格目前通过VBA生成: Spreadsheet Image

下面的代码旨在通过将前两行填充为灰色并添加外边框来开始格式化。我已将代码分为三类(请原谅任何草率的代码或noob错误。仍然在学习Java的第2周):

  1. 主类:

    public class CreateExcel {
    
    public static void createExcel(String[] args) throws IOException {
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet resultsSheet = workbook.createSheet("Results");
    ExcelMethods format = new ExcelMethods();
    ExcelStyles style = new ExcelStyles();
    
    format.formatRange(workbook, resultsSheet, style.fillPMEDarkGray(workbook), 1, 2, 2, 14);
    format.formatRange(workbook, resultsSheet, style.borderLeft(workbook), 1, 2, 2, 1);
    format.formatRange(workbook, resultsSheet, style.borderRight(workbook), 1, 2, 16, 1);
    format.formatRange(workbook, resultsSheet, style.borderTop(workbook), 1, 1, 2, 14);
    format.formatRange(workbook, resultsSheet, style.borderBottom(workbook), 2, 1, 2, 14);
    
    try (FileOutputStream fileOut = new FileOutputStream("C:<file location>/workbook.xlsx")) {
        workbook.write(fileOut);
    
            }
        }
    }
    
  2. 具有单元格循环格式的类:

    public class ExcelMethods {
    
    public void formatRange(XSSFWorkbook workbook,
                            XSSFSheet sheet,
                            XSSFCellStyle style,
                            int rowStart,
                            int numRows,
                            int columnStart,
                            int numColumns) {
        for (int i = rowStart; i <= rowStart + numRows; i++) {
            XSSFRow row = sheet.createRow(i);
            for (int j = columnStart; j <= columnStart + numColumns; j++) {
                XSSFCell cell = row.createCell(j);
                cell.setCellStyle(style);
            }
        }
    }
    
  3. 定义了样式的类:

    public class ExcelStyles{
    
    public XSSFCellStyle fillPMEDarkGray(XSSFWorkbook workbook) {
        XSSFColor pmeDarkGray = new XSSFColor(new java.awt.Color(128, 128, 128));
        XSSFCellStyle fillCell = workbook.createCellStyle();
        fillCell.setFillForegroundColor(pmeDarkGray);
        fillCell.setFillPattern(SOLID_FOREGROUND);
    
        return fillCell;
    }
    
    public XSSFCellStyle borderLeft(XSSFWorkbook workbook) {
        XSSFCellStyle cellBorder = workbook.createCellStyle();
        cellBorder.setBorderLeft(BorderStyle.THICK);
    
        return cellBorder;
    }
    
    public XSSFCellStyle borderRight(XSSFWorkbook workbook) {
        XSSFCellStyle cellBorder = workbook.createCellStyle();
        cellBorder.setBorderRight(BorderStyle.THICK);
    
        return cellBorder;
    }
    
    public XSSFCellStyle borderTop(XSSFWorkbook workbook) {
        XSSFCellStyle cellBorder = workbook.createCellStyle();
        cellBorder.setBorderTop(BorderStyle.THICK);
    
        return cellBorder;
    }
    
    public XSSFCellStyle borderBottom(XSSFWorkbook workbook) {
        XSSFCellStyle cellBorder = workbook.createCellStyle();
        cellBorder.setBorderBottom(BorderStyle.THICK);
    
        return cellBorder;
        }
    }
    
  4. 通过梳理Stack Overflow,POI API文档等,我已经明白单元格只能有一个XSSFCellStyle,因此尝试向已经填充的单元格添加边框会消除填充。因此,我的代码只生成一组填充黑色的单元格。

    对我来说,似乎很奇怪Apache POI不能轻易做到这一点。我知道我必须遗漏某些东西/设置错误的代码/ etc。

    顺便说一下,我也尝试使用Apache POI API中描述的PropertyTemplate.drawBorders,但我也无法使用它 - 结果相同。

    我希望有人能够巧妙地解决这个问题,因为我的智慧已经结束。

    感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

好的,让我们举一个例子,了解如何使用apache poi创建样本表,而不必使用低级对象。

主要方法是使用CellUtilPropertyTemplate来创建所需的单元格样式。因此,我们不需要手动创建每个单独的所需单元格样式(例如,边界范围的每个不同颜色边缘)。但是,我们保存不会创建太多的单元格样式(例如,每个单元格都有一种单元格样式)。

但正如Not able to set custom color in XSSFCell Apache POI已提到的,PropertyTemplate以及CellUtilRegionUtil仅基于ss.usermodel级别,而不是基于{{1}水平。但xssf.usermodel直到现在才对org.apache.poi.ss.usermodel.CellStyle有所了解。它只知道setFillForegroundColor(Color color)。因此,setFillForegroundColor(short bg)级别直到现在才能将ss.usermodel设置为填充前景色。只能使用Color(颜色索引)。我们必须记住这一点,并且只使用short设置单元格填充。否则就失败了。

示例代码,评论描述它的作用:

IndexedColors

结果:

enter image description here