简体   繁体   English

如何找出使用PHPExcel从Excel文件中读取的行数和列数?

[英]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. 使用以下代码,我可以使用PHPExcel从Excel文件中读取单元格。

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, eg even if some rows and columns are left blank? 有没有一种方法PHPExcel可以告诉我有多少行和列我必须阅读以从工作表中获取所有数据,例如,即使某些行和列留空?

$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: 谢谢,Mark,这是这些功能的完整解决方案:

$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>';

替代文字

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

and

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

or 要么

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

which returns a range as a string like A1:AC2048 它返回一个范围作为字符串,如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. 有关示例,请参阅生产分发中的/Tests/28iterator.php。 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: 从1.7.6及以下的PHPExcel版本中,可以在不读取整个文件的情况下获取工作表信息:

$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. 就我而言,第一列是商品的SKU,它是强制性的。

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. 如果你期望文件有很多行,在我的情况下它可以是10万行或更多,我正在读取每10 000行的第一列的值。

If cell A10000 is not empty, read A20000 and so on. 如果单元A10000不为空,请阅读A20000,依此类推。

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. 这样,对于具有100 000行的文件,我需要对单个单元格进行最多10次读取,以确定文件结束的10 000行的哪个段。

For example, let say it's between 30 000 and 40 000 row. 例如,假设它在30 000到40 000行之间。

Now get the average from above value - 35 000. One read of cell A35000 will further reduce the scope to 5000 rows. 现在从上面的值得到平均值--35000.一次读取单元格A35000将进一步将范围缩小到5000行。 Next average (and the single cell read) will further reduce the scope to 2500 and so on. 下一个平均值(以及单个单元格读取)将进一步将范围缩小到2500,依此类推。

Approximately you will need around 13-14 single cell reads, if you know in which 10 000 segment is the end of the file. 如果你知道哪个10 000段是文件的末尾,你将需要大约13-14个单细胞读数。 If you expect file with 100 000 rows add maximum 10 cell reads to determine the exact segment of 10 000 rows. 如果您希望文件具有100 000行,则添加最多10个单元格读取以确定10 000行的确切段。 This means maximum of around 25 cell reads for file with 100 000 rows. 这意味着对于具有100 000行的文件,最多大约25个单元读取。

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. 编辑:如果您期望空行 - 读取更多单元格,例如,如果您期望不超过1个后续空行,则每次读取2个后续单元格,例如A10000和A10001,其中一个应为非空,或者你超出了文件的末尾。 If you expect no more than 2 consequent empty rows, read 3 cells every time, for example A10000, A10001 and A10002, and so on. 如果预计不会有超过2个空行,请每次读取3个单元格,例如A10000,A10001和A10002,依此类推。

Following @nikolay's thinking from answer above, I decided to make the first cell of every row mandatory. 按照@ nikolay上面的回答思考,我决定将每行的第一个单元格强制执行。 That way, I just look at each cell of each row first to find out how many rows actually have data, depending on the first row. 这样,我只是先查看每一行的每个单元格,找出实际有多少行数据,具体取决于第一行。

$uploadedfile = \PHPExcel_IOFactory::load(Yii::getAlias('uploads').'/'.$file_location);
$uploadeddata = $uploadedfile->getActiveSheet()->toArray(null, true, true, true);

    //we need to first know how many rows actually have data
    //my first two rows have column labels, so i start with the third row.
    $row_count = 3;
    // read through the data and see how many rows actually have data
    //the idea is that for every row, the first cell should be mandatory...
    //if we find one that is not, we stop there...
    do
    {
      $row_count++;
    } while($uploadeddata[$row_count]['A'] == "null");

    //get the actual number of rows with data, removing the column labels
    $actual_rows = $row_count-3;

I don't think you can do that, you would have to loop through starting from say 1000 and go backwards until you hit the first non-blank cell and that would be your last row or column. 我不认为你能做到这一点,你必须从1000开始循环并向后循环,直到你击中第一个非空白单元格,这将是你的最后一行或列。

You can write a macro to do this in excel which may help but I don't know if you can execute it with PHPExcel. 您可以编写一个宏来在excel中执行此操作,这可能有所帮助,但我不知道您是否可以使用PHPExcel执行它。

$spreadsheet = new Spreadsheet();
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('xls');
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load('file location here');
$worksheet = $spreadsheet->getActiveSheet();
foreach ($worksheet->getRowIterator() AS $row) {
     $cellIterator = $row->getCellIterator();
     $cellIterator->setIterateOnlyExistingCells(FALSE); // This loops through all cells,
     $cells = [];
           foreach ($cellIterator as $cell) {
                 $cells[] = $cell->getValue();
           }
     $rows[] = $cells;
}

//blade html
<table class="table table-hover">
      <thead>
            <tr>
                @foreach($rows[0] as $heading)
                     <th>{{$heading}}</th>
                @endforeach
            </tr>
      </thead>
      <tbody>
             @foreach($rows as $key=>$val)
                   @if(!($key == 0))
                        <tr>
                            @foreach($val as $value)
                                 <td>{{$value}}</td>
                            @endforeach
                        </tr>
                    @endif
             @endforeach
      </tbody>
</table>
```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM