如何确定某行合并单元格

问题描述 投票:0回答:3

这是我目前所知道的:

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

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

如果有人可以分享他们对此事的想法或建议,我将永远感激不已。

java apache apache-poi
3个回答
12
投票

我相信这里的代码示例可以满足您的要求。 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();
        }
    }
}

4
投票

我有一个解决方案。基本上我只是将你的想法翻译成 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());
        }
    }
}

0
投票
  package maven.dustan.io.java_read_write_excel;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

public class RowsMerge {


    public static 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;
    }

    private static String readContentFromMergedCells(Sheet sheet, CellRangeAddress mergedCells) {

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

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

    public static void main(String[] args) throws IOException {
        File file = new File("C:/Users/GSolunke/test.xlsx");
        FileInputStream fis = new FileInputStream(file);
        XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFSheet sheet =  wb.getSheetAt(0);
        int lastRow = sheet.getLastRowNum();
        System.out.println("lastRow :"+lastRow);
        for (int rowNum = 0; rowNum < lastRow-1; rowNum++) {
            System.out.println("RowNum :"+rowNum);
            Row row = sheet.getRow(rowNum);
            if (row == null) {
                continue;
            }

            int lastColumn = row.getLastCellNum();
            System.out.println("lastColumn :"+lastColumn);

            for (int columnNum = 0; columnNum < lastColumn  && columnNum >=0; ++columnNum) {
                System.out.println("ColumnNo :"+columnNum);
                Integer mergedCellIndex = getIndexIfCellIsInMergedCells(sheet, rowNum, columnNum);

                if (mergedCellIndex != null) {
                    CellRangeAddress cell = sheet.getMergedRegion(mergedCellIndex);
                    System.out.println("Cell is in a merged cell");
                    System.out.println(">>>>"+readContentFromMergedCells(sheet, sheet.getMergedRegion(mergedCellIndex)));

                    int lastColumnOfThisMergedCell = sheet.getMergedRegion(mergedCellIndex).getLastColumn();

                    //columnNum = columnNum - lastColumnOfThisMergedCell - 1;
                    System.out.println("Next column being processed is {}"+ columnNum);
                } else {
                    Cell cell = row.getCell(columnNum, Row.MissingCellPolicy.RETURN_NULL_AND_BLANK);
                    if (cell == null) {
                        continue;
                    }
                    System.out.println("Cell is an individual cell");
                    System.out.println("Content is {}"+row.getCell(columnNum).getStringCellValue());
                }
            }
        }
    }}
© www.soinside.com 2019 - 2024. All rights reserved.