如何确定某一行中的合并单元格

时间:2013-04-02 03:18:37

标签: java apache apache-poi

这是我目前所知道的:

  1. 使用方法sheet.getNumMergedRegions()获取特定工作表中合并区域的数量
  2. 循环遍历每个计数并使用方法sheet.getMergedRegion(i)并分配给CellRangeAddress变量
  3. 然后使用isInRange(rowIndex,colIndex)函数查看特定单元格是否属于合并区域。
  4. 但我想要完成的是: 我想看看是否可以确定仅给定特定行的合并单元格。 就像我有某一行一样,我想知道在该行下找到的所有合并区域的数量。

    如果有人能就这件事分享他们的想法或建议,我将永远感激。

2 个答案:

答案 0 :(得分:8)

这是一个代码示例,可以完成您想要的内容。 getNbOfMergedRegions会返回特定行中合并区域的数量。请记住,POI行号从零开始!

package test;

import java.io.File;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddress;

public class Main {

    public static int getNbOfMergedRegions(Sheet sheet, int row)
    {
        int count = 0;
        for(int i = 0; i < sheet.getNumMergedRegions(); ++i)
        {
            CellRangeAddress range = sheet.getMergedRegion(i);
            if (range.getFirstRow() <= row && range.getLastRow() >= row)
                ++count;
        }
        return count;
    }

    public static void main(String[] args) {
        File file = new File("/Users/enicolas/Downloads/test.xls");
        try 
        {
            Workbook wb = WorkbookFactory.create(file);  // Line 409 for ref to the exception stack trace
            Sheet sheet = wb.getSheetAt(0);
            for(int row = 0; row < 20; ++row)
            {
                int n = getNbOfMergedRegions(sheet, row);
                System.out.println("row [" + row + "] -> " + n + " merged regions");
            }
            System.out.println(wb);
        }
        catch (Throwable e) 
        {
            e.printStackTrace();
        }
    }
}

答案 1 :(得分:1)

我已经找到了解决方案。基本上,我只是将您的想法翻译成Java代码。

首先,您需要这两种方法。

第一个帮助您确定给定单元格是否在合并的单元格中。

/**
 * Get the index of the merged cell in all the merged cells
 * if the given cell is in a merged cell.
 * Otherwise, it will return null.
 *
 * @param sheet  The Sheet object
 * @param row    The row number of this cell
 * @param column The column number of this cell
 * @return The index of all merged cells, which will be useful for {@link Sheet#getMergedRegion(int)}
 */
private Integer getIndexIfCellIsInMergedCells(Sheet sheet, int row, int column) {
    int numberOfMergedRegions = sheet.getNumMergedRegions();

    for (int i = 0; i < numberOfMergedRegions; i++) {
        CellRangeAddress mergedCell = sheet.getMergedRegion(i);

        if (mergedCell.isInRange(row, column)) {
            return i;
        }
    }

    return null;
}

第二个可以帮助您从中获取内容。

/**
 * Get the value from a merged cell
 *
 * @param sheet       The Sheet object
 * @param mergedCells The {@link CellRangeAddress} object fetched from {@link Sheet#getMergedRegion(int)} method
 * @return The content in this merged cell
 */
private String readContentFromMergedCells(Sheet sheet, CellRangeAddress mergedCells) {

    if (mergedCells.getFirstRow() != mergedCells.getLastRow()) {
        return null;
    }

    return sheet.getRow(mergedCells.getFirstRow()).getCell(mergedCells.getFirstColumn()).getStringCellValue();
}

然后,您可以迭代此工作表中的行和列,并根据此单元格是否在合并的单元格中来做不同的事情。

for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
    Row row = sheet.getRow(rowNum);
    if (row == null) {
        continue;
    }

    int lastColumn = row.getLastCellNum();

    for (int columnNum = 0; columnNum < lastColumn; columnNum++) {
        // Determine if this cell is in a merged cell
        Integer mergedCellIndex = getIndexIfCellIsInMergedCells(sheet, rowNum, columnNum);

        if (mergedCellIndex != null) {
            // If it is in a merged cell
            // then get it
            CellRangeAddress cell = sheet.getMergedRegion(mergedCellIndex);

            // Do your logic here
            log.info("Cell is in a merged cell");
            log.info("Content is {}",
                    readContentFromMergedCells(sheet, sheet.getMergedRegion(mergedCellIndex)));

            // Get the last column of this merged cell
            int lastColumnOfThisMergedCell = sheet.getMergedRegion(mergedCellIndex).getLastColumn();

            // And skip those merged cells
            // since the columnNum will increase 1 on next loop
            // so you have to minus 1 here
            columnNum = columnNum + lastColumnOfThisMergedCell - 1;
            log.info("Next column being processed is {}", columnNum);
        } else {
            // If it is not in a merged cell
            // hence, an "individual" cell
            Cell cell = row.getCell(columnNum, Row.RETURN_BLANK_AS_NULL);
            if (cell == null) {
                continue;
            }

            // Then you can simply do your logic
            // and continue to the next loop
            log.info("Cell is an individual cell");
            log.info("Content is {}",
                    row.getCell(columnNum).getStringCellValue());
        }
    }
}