如何使用 apache poi 确定合并单元格中的行数?

Posted

技术标签:

【中文标题】如何使用 apache poi 确定合并单元格中的行数?【英文标题】:How to determine number of rows in a merged cell using apache poi? 【发布时间】:2019-01-11 00:55:12 【问题描述】:

我正在使用 excel 为我的测试自动化脚本输入数据,当我知道要读取的确切行和列时,我可以从 excel 中读取数据。我面临的挑战是当我在工作表中合并单元格时。例如。 Test data excel sample

这里 ScriptName 和 Iteration 是我的主键,用于标识我的脚本的一组唯一数据。 所以我的问题是:

    我想获取关于 ScriptName 的所有 ReferenceSetName,以及 Iteration 即登录脚本,Iteration 1:我必须获取 ABC1 Ref set、ABC2 Ref set、ABC3 Ref set李> 我想获取关于 ScriptName、Iteration 和 ReferenceSet 的所有 PackageName,即登录脚本、Iteration 1、ReferenceSet ABC1 Ref 集:我必须获取 ABC1、ABC2、ABC3

目前下面是方法 - getEntireCellValue() 我用来从 excel 中获取数据,我需要帮助来解决上述 2 个问题。任何形式的支持都非常感谢。

public void getExcelRowNum() 
    boolean found = false;
    String scriptCell = null, iterationCell = null;
    try 
        @SuppressWarnings("rawtypes")
        Iterator iterator = sheet.rowIterator();
        while (iterator.hasNext()) 
            Row row = (Row) iterator.next();
            scriptCell = row.getCell(1).toString().trim();
            iterationCell = row.getCell(2).toString().trim();
            if (row.getCell(2).getCellTypeEnum() == CellType.NUMERIC)
                iterationCell = iterationCell.substring(0, iterationCell.indexOf(".")).trim();
            if ((scriptCell.equals(scriptName) && iterationCell.equals(String.valueOf(iteration).trim()))
                    || (scriptCell.equals(scriptName) && Integer.parseInt(iterationCell) == iteration)) 
                rowNum = row.getRowNum();

                found = true;
                break;
            
        
        if (rowNum == -1 || found == false)
            throw new Exception("Please check the test name: " + scriptName + " or the iteration: " + iteration
                    + " in the test data sheet");

        row = sheet.getRow(0);
    
    catch (Exception e) 
        e.printStackTrace();
    


public void getExcelColNum(String colName) 
    boolean found = false;
    try 
        for (int i = 0; i < row.getLastCellNum(); i++) 
            if (row.getCell(i).getStringCellValue().trim().equals(colName.trim())) 
                col_Num = i;
                found = true;
                break;
            
        
        if (col_Num == -1 || found == false)
            throw new Exception("Please check the column name: " + colName + " in the test data sheet");
    
    catch (Exception e) 
        e.printStackTrace();
    


public void getCell() 
    try 
        row = sheet.getRow(rowNum);
        cell = row.getCell(col_Num);
    
    catch (Exception e) 
        e.printStackTrace();
    


    //Prior to calling this method. I am connecting to the excel sheet which 
    is in .xlsx or xls format
    public String getEntireCellValue(String sheetName, String colName) 
            try 
                sheet = workbook.getSheet(sheetName);           
                getExcelRowNum();
                getExcelColNum(colName);
                getCell();
                if (cell.getCellTypeEnum() == CellType.STRING)
                    return cell.getStringCellValue().trim();
                else if (cell.getCellTypeEnum() == CellType.BLANK)
                    return null;
            
            catch (Exception e) 
                e.printStackTrace();
                return null;
         
    

    public int getNumOfMergedRows() 
        int rowsMerged = 0;
        try 
            for(int i = 0; i < sheet.getNumMergedRegions(); i++) 
                CellRangeAddress range = sheet.getMergedRegion(i);
                if (range.getFirstRow() <= rowNum && range.getLastRow() >= 
                rowNum) 
                    ++rowsMerged;
                
            
            System.out.println("Number of rows merged are: " + rowsMerged);
        
        catch (Exception e) 
            e.printStackTrace();
        
        return rowsMerged;
    

附:我在这里做的是,我正在尝试获取脚本的合并行数,例如为登录脚本合并 6 行,然后在这 6 行中查找单元格数以获得参考集名称(3 个单元格)。 注意:当我调用上述方法 - getNumOfMergedRows() 来确定为登录脚本合并的行数时,我得到 4 作为输出而不是 6。

【问题讨论】:

if 条件下 rowNum 变量的值是多少? 添加了我用来确定 rowNum 的代码。注意:所有变量都是实例变量 【参考方案1】:

我有一个将字段作为输入的示例代码。它将计算第三列中所有值的值并将其存储在地图中。它通过计算 excel 文件中的空白值并在每个有效值处重置计数器来做到这一点

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class Demo 

    public static void main(String[] args) 
        readFile(new File("excelstack.xlsx"));
    
    public static void readFile(File file) 

        try 

            FileInputStream excelFile = new FileInputStream(file);
            Workbook workbook = new XSSFWorkbook(excelFile);
            Sheet datatypeSheet = workbook.getSheetAt(0);
            Iterator<Row> iterator = datatypeSheet.iterator();

            Map<String,Integer> map=new HashMap<String,Integer>();

            int coltocheck=1;
            int counter=1;
            String currentitem="";
            while (iterator.hasNext()) 
                Row currentRow = iterator.next();
                Iterator<Cell> cellIterator = currentRow.iterator();                                              
                while (cellIterator.hasNext()) 
                    Cell currentCell = cellIterator.next();                                  
                   if(currentCell.getCellTypeEnum()==CellType.BLANK )  
                            if(currentCell.getColumnIndex()==coltocheck)
                                    map.put(currentitem, counter++);
                                        
                    else if(currentCell.getCellTypeEnum()==CellType.STRING && currentCell.getColumnIndex()==coltocheck) 
                            currentitem=currentCell.getStringCellValue();                       
                            counter=1;
                            map.put(currentitem, counter++);

                    
                                                                
             
           for(Map.Entry<String, Integer> m:map.entrySet())
               System.out.println(m.getKey()+" "+m.getValue());

         catch (FileNotFoundException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
         finally                      
        


    

【讨论】:

【参考方案2】:

以下代码将确定列中合并单元格的数量 - colName,开始行为startingRow

public int getNumOfMergedRows(String colName, int startingRow) 
    int rowsMerged = 0, col = 0;
    XSSFRow mergedRow = null;
    XSSFCell mergedCell = null;
    try 
        col = getExcelColNum(colName);
        for (int i = startingRow + 1; i < sheet.getPhysicalNumberOfRows(); i++) 
            mergedRow = sheet.getRow(i);
            mergedCell = mergedRow.getCell(col);
            if (mergedCell.getCellTypeEnum() == null || mergedCell.getCellTypeEnum() == CellType.BLANK)
                rowsMerged++;
            else
                break;
        
        rowsMerged++;
    
    catch (Exception e) 
        e.printStackTrace();
    
    logger.info(rowsMerged + " rows are merged in columne" + colName + " for " + scriptName + " script");
    return rowsMerged;

【讨论】:

以上是关于如何使用 apache poi 确定合并单元格中的行数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用apache poi从公式单元格中读取单元格值

如何使用Java和apache poi选择excel中的所有单元格

poi 中解析Excel 时 获取单元格中的值。

如何使用合并单元格值大于单元格宽度的 Apache-POI 增加 excel 行的高度?

poi 导出excel 怎么设置合并的单元格自动换行

poi 读取word 遍历表格和单元格中的图片