在excel Apache poi java中为合并单元格添加边框。

24

我正在使用Apache POI,需要在一系列单元格或合并区域中添加边框。我正在合并具有三行五列的单元格,但是无法为其添加边框。那么我该如何做到这一点呢?


合并单元格后,创建单元格并为其添加样式即可。这样就可以正常工作了。 - swamy
嗨Swamy,你能告诉我创建单元格并添加样式的意思吗?我们是在创建单元格后合并单元格,对吧?顺便问一下,@ashu,你解决了这个问题吗?我也卡在同样的问题上 :( - Anoop
8个回答

28

我的解决方案是根据它们的位置合并单元格,然后创建一个单元格(引用合并单元格的第一个块),分配一个值,并通过HSSFRegionUtil设置边框。

// Merges the cells
CellRangeAddress cellRangeAddress = new CellRangeAddress(start, start, j, j + 1);
sheet.addMergedRegion(cellRangeAddress);

// Creates the cell
Cell cell = CellUtil.createCell(row, j, entry.getKey());

// Sets the borders to the merged cell
HSSFRegionUtil.setBorderTop(CellStyle.BORDER_MEDIUM, cellRangeAddress, sheet, workbook);
HSSFRegionUtil.setBorderLeft(CellStyle.BORDER_MEDIUM, cellRangeAddress, sheet, workbook);
HSSFRegionUtil.setBorderRight(CellStyle.BORDER_MEDIUM, cellRangeAddress, sheet, workbook);
HSSFRegionUtil.setBorderBottom(CellStyle.BORDER_THIN, cellRangeAddress, sheet, workbook);

谢谢,对我有用。 - Varun Arya

16

10

首先,很好知道您正在尝试创建哪种工作表格式。因为当您在HSSF中合并空单元格时,这是完全正常的,而XSSF则会创建格式不正确的文件,在Microsoft EXCEL中打开时会导致错误。在两种情况下,样式倾向于表现相同。您需要为要合并的每个单元格分配相同的样式(在您的情况下包括边框的样式)。我建议创建一个检查和纠正功能,将样式设置为合并区域中的所有单元格。

private static final XSSFColor COLOR_ORANGE         = new XSSFColor(new java.awt.Color(254, 253, 189));
private static final XSSFColor COLOR_GREY           = new XSSFColor(new java.awt.Color(191, 190, 154));

. . .

        XSSFCellStyle styleSubHeader = (XSSFCellStyle) wb.createCellStyle();
        styleSubHeader.setFont(fontBold);
        styleSubHeader.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        styleSubHeader.setAlignment(CellStyle.ALIGN_CENTER);
        styleSubHeader.setFillForegroundColor(COLOR_ORANGE);
        styleSubHeader.setFillPattern(CellStyle.SOLID_FOREGROUND);
        styleSubHeader.setBorderBottom(CellStyle.BORDER_THIN);
        styleSubHeader.setBottomBorderColor(COLOR_GREY);
        styleSubHeader.setBorderLeft(CellStyle.BORDER_THIN);
        styleSubHeader.setLeftBorderColor(COLOR_GREY);
        styleSubHeader.setBorderRight(CellStyle.BORDER_THIN);
        styleSubHeader.setRightBorderColor(COLOR_GREY);
        styleSubHeader.setBorderTop(CellStyle.BORDER_THIN);
        styleSubHeader.setTopBorderColor(COLOR_GREY);

. . .

 /**
 * Checking if every row and cell in merging region exists, and create those which are not    
 * @param sheet in which check is performed
 * @param region to check
 * @param cellStyle cell style to apply for whole region
 */
private void cleanBeforeMergeOnValidCells(XSSFSheet sheet,CellRangeAddress region, XSSFCellStyle cellStyle )
{
    for(int rowNum =region.getFirstRow();rowNum<=region.getLastRow();rowNum++){
        XSSFRow row= sheet.getRow(rowNum);
        if(row==null){
            sheet.createRow(rowNum);
            logger.trace("while check row "+rowNum+" was created");
        }
        for(int colNum=region.getFirstColumn();colNum<=region.getLastColumn();colNum++){
            XSSFCell currentCell = row.getCell(colNum); 
           if(currentCell==null){
               currentCell = row.createCell(colNum);
               logger.trace("while check cell "+rowNum+":"+colNum+" was created");
           }    

           currentCell.setCellStyle(cellStyle);

        }
    }


}

最后,在实际执行合并操作之前,您需要调用类似以下代码的函数:

CellRangeAddress region = new CellRangeAddress(rowIndex, rowIndex, mergeStart, cellIndex+cellOffset);
cleanBeforeMergeOnValidCells(row.getSheet(),region,styleSubHeader );
row.getSheet().addMergedRegion(region);// merging cells that has a title name
希望对你有所帮助。

我曾经迷失方向,但它真的起作用了!非常感谢! - Gian Marco Carrasco Vasquez

8
我建议您使用 getMergedRegions 方法,该方法将返回工作表中合并区域的列表。然后您可以迭代每个区域来应用边框。例如:
private void setBordersToMergedCells(Workbook workBook, Sheet sheet) {
  List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
  for (CellRangeAddress rangeAddress : mergedRegions) {
    RegionUtil.setBorderTop(CellStyle.BORDER_THIN, rangeAddress, sheet, workBook);
    RegionUtil.setBorderLeft(CellStyle.BORDER_THIN, rangeAddress, sheet, workBook);
    RegionUtil.setBorderRight(CellStyle.BORDER_THIN, rangeAddress, sheet, workBook);
    RegionUtil.setBorderBottom(CellStyle.BORDER_THIN, rangeAddress, sheet, workBook);
  }
}

然后,在你完成所有需要合并的工作表后,可以调用此方法。

3

使用:

int rownumm=0;
rownumm++;

Row row = sheet.createRow(rownumm);
Cell cell = row.createCell(0);
cell.setCellValue(web.getUrl());
cell.setCellStyle(styles.get("font"));//font for text

CellRangeAddress region = CellRangeAddress.valueOf("$A$"+ (rownumm) + ":$E$+" + (rownumm));
frame(region, sheet, wb); 

并使用方法:

private static void frame(CellRangeAddress region,Sheet sheet, Workbook wb){
    sheet.addMergedRegion(region);

    final short borderMediumDashed = CellStyle.BORDER_MEDIUM;
    RegionUtil.setBorderBottom(borderMediumDashed, region, sheet, wb);
    RegionUtil.setBorderTop(borderMediumDashed, region, sheet, wb);
    RegionUtil.setBorderLeft(borderMediumDashed, region, sheet, wb);
    RegionUtil.setBorderRight(borderMediumDashed, region, sheet, wb);
}

请参阅链接上的“使用便利函数”部分。

https://poi.apache.org/spreadsheet/quick-guide.html#FooterPageNumbers


1
    cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
    cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
    cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
    cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());

2
这并未提及如何在合并的单元格/区域上设置样式。 - Necrototem

0
根据 Apache POI v3,以下代码对我有效:
// Defining and merging the cells
CellRangeAddress cellRangeAddress = new CellRangeAddress(start, start, j, j + 1);
sheet.addMergedRegion(cellRangeAddress);

// Adding a border to the cell
RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet);
RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet);
RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet);
RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet);

0
一般来说,我知道使用RegionUtil会使你的生活更轻松,因为它是一个易于使用的类,但它非常消耗CPU。尽可能使用cellstyle来执行这些类型的过程。最好自己编写设置表格边框的方法,而不是使用RegionUtils。

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