Данный:
$this->objPHPExcelReader = PHPExcel_IOFactory::createReaderForFile($this->config['file']); $this->objPHPExcelReader->setLoadSheetsOnly(array($this->config['worksheet'])); $this->objPHPExcelReader->setReadDataOnly(true); $this->objPHPExcel = $this->objPHPExcelReader->load($this->config['file']);
Я могу выполнять итерацию по таким строкам, но это очень медленно , т. Е. В трехмерном Excel-файле с листом, который имеет столбцы «EL» , для каждой строки требуется около 1 секунды :
foreach ($this->objPHPExcel->setActiveSheetIndex(0)->getRowIterator() as $row) { $dataset = array(); $cellIterator = $row->getCellIterator(); $cellIterator->setIterateOnlyExistingCells(false); foreach ($cellIterator as $cell) { if (!is_null($cell)) { $dataset[] = $cell->getCalculatedValue(); } } $this->datasets[] = $dataset; }
Когда я повторяюсь так, это значительно быстрее (примерно 2000 строк за 30 секунд), но мне придется преобразовать буквы, например, «EL», в число:
$highestColumm = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); // eg "EL" $highestRow = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow(); $number_of_columns = 150; // TODO: figure out how to get the number of cols as int for ($row = 1; $row < $highestRow + 1; $row++) { $dataset = array(); for ($column = 0; $column < $number_of_columns; $column++) { $dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCellByColumnAndRow($column, $row)->getValue(); } $this->datasets[] = $dataset; }
Есть ли способ получить самый высокий столбец как целое число (например, «28») вместо букв в стиле Excel (например, «AB»)?
$colNumber = PHPExcel_Cell::columnIndexFromString($colString);
возвращает 1 из $ colString 'A', 26 из 'Z', 27 из 'AA' и т. д.
и (почти) обратное
$colString = PHPExcel_Cell::stringFromColumnIndex($colNumber);
возвращает 'A' из $ colNumber 0, 'Z' из 25, AA с 26 и т. д.
РЕДАКТИРОВАТЬ
Несколько полезных трюков:
Существует метод toArray () для класса рабочей таблицы:
$this->datasets = $this->objPHPExcel->setActiveSheetIndex(0)->toArray();
который принимает следующие параметры:
* @param mixed $nullValue Value returned in the array entry if a cell doesn't exist * @param boolean $calculateFormulas Should formulas be calculated? * @param boolean $formatData Should formatting be applied to cell values? * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero * True - Return rows and columns indexed by their actual row and column IDs
хотя он использует итераторы, так что будет немного медленнее
ИЛИ
Воспользуйтесь возможностью PHP наращивать символьные строки Perl Style
$highestColumm = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); // eg "EL" $highestRow = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestRow(); $highestColumm++; for ($row = 1; $row < $highestRow + 1; $row++) { $dataset = array(); for ($column = 'A'; $column != $highestColumm; $column++) { $dataset[] = $this->objPHPExcel->setActiveSheetIndex(0)->getCell($column . $row)->getValue(); } $this->datasets[] = $dataset; }
и если вы обрабатываете большое количество строк, вы можете заметить улучшение производительности ++ $ row над $ row ++
Не уверен, что ваш класс имеет встроенный метод, но вы всегда можете использовать функцию ord () для каждой буквы индексной строки столбца. Разумеется, вам придется вычесть базовое значение «A» и умножить на 26 ^ x для каждой позиции из крайнего правого ряда. Что-то вроде:
$input_string = 'BC'; $base_value = 64; $decimal_value = 26; $column_index = 0; for ($i = 0; $i < strlen($input_string); $i++) { $char_value = ord($input_string[$i]); $char_value -= $base_value; $char_value *= pow($decimal_value, (strlen($input_string) - ($i + 1))); $column_index += $char_value; } echo $column_index;
В основном это сделало бы «BC» равным (2 * 26 ^ 1) + (3 * 26 ^ 0) = 55.
$ input_string – индексная строка столбца, $ base_value – значение ord () 'A' минус 1, а $ decimal_value – значение A0. Должен работать до любого столбца номера. Протестировали. Надеюсь это поможет.
самым простым решением является $ getColumnIndexFromString = PHPExcel_Cell :: columnIndexFromString ($ highColumn);
function getNameFromNumber($num) {//(Example 0 = A, 1 = B) $numeric = $num % 26; $letter = chr(65 + $numeric); $num2 = intval($num / 26); if ($num2 > 0) { return getNameFromNumber($num2 - 1) . $letter; } else { return $letter; } }
getNameFromNumber (0) // return A
Это несколько упрощенная версия ответа dqhendricks. Я добавил к копиям одну функцию, предполагая, что вы введете полную ссылку на ячейку excel (например, «AB12»), а другая, если вы введете только ссылку на колонку (например, «AB»). Оба они возвращают индекс на основе нуля.
Входная ссылка Full Cell Reference
function getIndex ($cell) { // Strip cell reference down to just letters $let = preg_replace('/[^AZ]/', '', $cell); // Iterate through each letter, starting at the back to increment the value for ($num = 0, $i = 0; $let != ''; $let = substr($let, 0, -1), $i++) $num += (ord(substr($let, -1)) - 65) * pow(26, $i); return $num; }
Только входная колонка
function getIndex ($let) { // Iterate through each letter, starting at the back to increment the value for ($num = 0, $i = 0; $let != ''; $let = substr($let, 0, -1), $i++) $num += (ord(substr($let, -1)) - 65) * pow(26, $i); return $num; }
Функция переместится от задней части строки к фронту, чтобы увеличить значение столбца. Он использует функцию ord()
чтобы получить числовое значение символа, а затем вычитает значение буквы, чтобы дать значение локального столбца. Наконец, он умножается на текущую мощность 26.
Я предлагаю преобразовать excel в массив, очистить его от пустых элементов и затем подсчитать количество столбцов:
protected function getColumnsCheck($file, $col_number) { if (strstr($file, ".xls") != false && strstr($file, ".xlsx") != false) { $fileType = PHPExcel_IOFactory::identify($file); $objReader = PHPExcel_IOFactory::createReader($fileType); $objPHPExcel = $objReader->load($file); $columns_empty = $objPHPExcel->getActiveSheet(0)->toArray()[0]; $columns = array_filter($columns_empty); return ($col_number==count($columns)); } return false; }
/** * */ function number_to_alphabet($number) { $number = intval($number); if ($number <= 0) { return ''; } $alphabet = ''; while($number != 0) { $p = ($number - 1) % 26; $number = intval(($number - $p) / 26); $alphabet = chr(65 + $p) . $alphabet; } return $alphabet; } /** * Required PHP 5.6. * @see: http://php.net/manual/en/language.operators.arithmetic.php */ function alphabet_to_number($string) { $string = strtoupper($string); $length = strlen($string); $number = 0; $level = 1; while ($length >= $level ) { $char = $string[$length - $level]; $c = ord($char) - 64; $number += $c * (26 ** ($level-1)); $level++; } return $number; }
Контрольная работа:
for ($x=1; $x<=1000; $x++) { echo 'number_to_alphabet('.$x.') = ',$y = number_to_alphabet($x),'; '; echo 'alphabet_to_number('.$y.') = '.alphabet_to_number($y).'; '; echo PHP_EOL; }