How to find out how many rows and columns to read from an Excel file with PHPExcel?

With the following code, I am able to read the cells out of an Excel file with PHPExcel.

I currently manually define how many rows and columns to read.

Is there a way that PHPExcel can tell me how many rows and columns I have to read to get all the data out of the worksheet, e.g. even if some rows and columns are left blank?

$file_name = htmlentities($_POST['file_name']);
$sheet_name = htmlentities($_POST['sheet_name']);
$number_of_columns = htmlentities($_POST['number_of_columns']);
$number_of_rows = htmlentities($_POST['number_of_rows']);

$objReader = PHPExcel_IOFactory::createReaderForFile("data/" . $file_name);
$objReader->setLoadSheetsOnly(array($sheet_name));
$objReader->setReadDataOnly(true);
$objPHPExcel = $objReader->load("data/" . $file_name);

echo '<table border="1">';
for ($row = 1; $row < $number_of_rows; $row++) {
    echo '<tr>';
    for ($column = 0; $column < $number_of_columns; $column++) {
        $value = $objPHPExcel->setActiveSheetIndex(0)->getCellByColumnAndRow($column, $row)->getValue();
        echo '<td>';
        echo $value . '&nbsp;';
        echo '</td>';
    }
    echo '</tr>';
}
echo '</table>';

Solution:

Thanks, Mark, here's the full solution with those functions:

$file_name = htmlentities($_POST['file_name']);
$sheet_name = htmlentities($_POST['sheet_name']);
$number_of_columns = htmlentities($_POST['number_of_columns']);
$number_of_rows = htmlentities($_POST['number_of_rows']);

$objReader = PHPExcel_IOFactory::createReaderForFile("data/" . $file_name);
$objReader->setLoadSheetsOnly(array($sheet_name));
$objReader->setReadDataOnly(true);

$objPHPExcel = $objReader->load("data/" . $file_name);

$highestColumm = $objPHPExcel->setActiveSheetIndex(0)->getHighestColumn();
$highestRow = $objPHPExcel->setActiveSheetIndex(0)->getHighestRow();

echo 'getHighestColumn() =  [' . $highestColumm . ']<br/>';
echo 'getHighestRow() =  [' . $highestRow . ']<br/>';

echo '<table border="1">';
foreach ($objPHPExcel->setActiveSheetIndex(0)->getRowIterator() as $row) {
    $cellIterator = $row->getCellIterator();
    $cellIterator->setIterateOnlyExistingCells(false);
    echo '<tr>';
    foreach ($cellIterator as $cell) {
        if (!is_null($cell)) {
            $value = $cell->getCalculatedValue();
            echo '<td>';
            echo $value . '&nbsp;';
            echo '</td>';
        }
    }
    echo '</tr>';
}
echo '</table>';

alt text


$objPHPExcel->setActiveSheetIndex(0)->getHighestColumn();

and

$objPHPExcel->setActiveSheetIndex(0)->getHighestRow();

or

$objPHPExcel->setActiveSheetIndex(0)->calculateWorksheetDimension();

which returns a range as a string like A1:AC2048

although trailing blank rows and columns are included in these.

EDIT

or you can use the iterators to loop through the existing rows and columns to get each cell within the worksheets used range. See /Tests/28iterator.php in the production distribution for an example. The iterators can be set to ignore blanks.


From the 1.7.6 and below PHPExcel versions it is possible to get worksheet information without reading whole file:

$objReader     = PHPExcel_IOFactory::createReader("Excel2007"); 
$worksheetData = $objReader->listWorksheetInfo($uploadedfile);
$totalRows     = $worksheetData[0]['totalRows'];
$totalColumns  = $worksheetData[0]['totalColumns'];

You can do it much less cell reads than itterating all the rows(columns).

In my case, the first column is SKU of item and it's mandatory.

If you expect file with many many rows, in my case it can be 100 000 rows or more, i'm reading the value of the first column at every 10 000 row.

If cell A10000 is not empty, read A20000 and so on.

In this way, for a file with 100 000 rows I need max 10 reads of a single cell to decide in which segment of 10 000 rows the file ends.

For example, let say it's between 30 000 and 40 000 row.

Now get the average from above value - 35 000. One read of cell A35000 will further reduce the scope to 5000 rows. Next average (and the single cell read) will further reduce the scope to 2500 and so on.

Approximately you will need around 13-14 single cell reads, if you know in which 10 000 segment is the end of the file. If you expect file with 100 000 rows add maximum 10 cell reads to determine the exact segment of 10 000 rows. This means maximum of around 25 cell reads for file with 100 000 rows.

Edit: if you expect empty rows - read little more cells, for example, if you expect no more than 1 consequent empty row, read 2 consequent cells every time, for example A10000 and A10001, one of them should be non-empty, or you are beyond the end of the file. If you expect no more than 2 consequent empty rows, read 3 cells every time, for example A10000, A10001 and A10002, and so on.