С помощью следующего кода я могу прочитать ячейки из файла Excel с помощью PHPExcel.
В настоящее время я вручную определяю, сколько строк и столбцов нужно читать.
Есть ли способ, которым 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 . ' '; echo '</td>'; } echo '</tr>'; } echo '</table>';
Спасибо, Марк, вот полное решение с этими функциями:
$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 . ' '; echo '</td>'; } } echo '</tr>'; } echo '</table>';
$objPHPExcel->setActiveSheetIndex(0)->getHighestColumn();
а также
$objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
или
$objPHPExcel->setActiveSheetIndex(0)->calculateWorksheetDimension();
который возвращает диапазон в виде строки, такой как A1: AC2048
хотя в них включены конечные пустые строки и столбцы.
РЕДАКТИРОВАТЬ
или вы можете использовать итераторы для прокрутки существующих строк и столбцов, чтобы получить каждую ячейку в пределах используемого диапазона рабочих таблиц. См. /Tests/28iterator.php в производственном распределении для примера. Итераторы могут быть установлены так, чтобы игнорировать пробелы.
Из версий 1.7.6 и ниже PHPExcel
можно получить информацию рабочего листа без чтения всего файла:
$objReader = PHPExcel_IOFactory::createReader("Excel2007"); $worksheetData = $objReader->listWorksheetInfo($uploadedfile); $totalRows = $worksheetData[0]['totalRows']; $totalColumns = $worksheetData[0]['totalColumns'];
Вы можете сделать это гораздо меньше чтения ячейки, чем повторять все строки (столбцы).
В моем случае первый столбец является SKU элемента, и он является обязательным.
Если вы ожидаете, что файл имеет много строк, в моем случае он может составлять 100 000 строк или больше, я читаю значение первого столбца в каждых 10 000 строк.
Если ячейка A10000 не пуста, прочитайте A20000 и так далее.
Таким образом, для файла со 100 000 строк мне нужно не более 10 прочтений одной ячейки, чтобы решить, в каком сегменте 10 000 строк файл заканчивается.
Например, скажем, это от 30 000 до 40 000 строк.
Теперь получим среднее значение сверху – 35 000. Одно чтение ячейки A35000 еще больше уменьшит масштаб до 5000 строк. Следующее среднее (и однокамерное чтение) дополнительно уменьшит масштаб до 2500 и так далее.
Примерно вам понадобится около 13-14 однокамерных прочтений, если вы знаете, в которых 10 000 сегментов – это конец файла. Если вы ожидаете, что файл со 100 000 строк добавит максимум 10 ячеек, чтобы определить точный сегмент из 10 000 строк. Это означает, что максимум около 25 ячеек читает файл со 100 000 строк.
Редактирование: если вы ожидаете пустые строки – читайте немного больше ячеек, например, если вы ожидаете не более 1 последовательной пустой строки, каждый раз читайте 2 последовательных ячейки, например A10000 и A10001, один из них должен быть непустым или вы находитесь за пределами файла. Если вы ожидаете не более двух последовательных пустых строк, каждый раз читайте 3 ячейки, например A10000, A10001 и A10002, и так далее.
Я не думаю, что вы можете это сделать, вам нужно будет пройти через от 1000 и вернуться назад, пока вы не нажмете первую непустую ячейку, и это будет ваша последняя строка или столбец.
Вы можете написать макрос для этого в excel, который может помочь, но я не знаю, можете ли вы выполнить его с помощью PHPExcel.
Следуя рассуждениям @ nikolay из ответа выше, я решил сделать первую ячейку каждой строки обязательной. Таким образом, я просто просматриваю каждую ячейку каждой строки, чтобы узнать, сколько строк на самом деле имеют данные, в зависимости от первой строки.
$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;