10

到目前为止,这是我所知道的:

  1. 您使用 sheet.getNumMergedRegions() 方法获取特定工作表中合并区域的数量
  2. 您遍历每个计数并使用方法 sheet.getMergedRegion(i) 并分配给 CellRangeAddress 变量
  3. 然后使用 isInRange(rowIndex, colIndex) 函数来查看特定单元格是否是合并区域的一部分。

但我想要完成的是:我想看看是否可以确定仅给定特定行的合并单元格。就像我有某一行一样,我想知道仅在该行下找到的所有合并区域的计数。

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

4

2 回答 2

11

这是一个代码示例,我相信它可以满足您的需求。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();
        }
    }
}
于 2014-06-11T21:58:27.787 回答
3

我有一个解决方案。基本上,我只是将您的想法翻译成 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());
        }
    }
}
于 2019-09-23T09:22:50.770 回答