Как получить количество столбцов таблицы в виде целого числа (28) вместо букв Excel («AB»)? - PullRequest
32 голосов
/ 30 декабря 2010

Дано:

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

Я могу перебирать строки, как это, но это очень медленно , то есть в 3-мегабайтном файле 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(); // e.g. "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")?

Ответы [ 7 ]

72 голосов
/ 31 декабря 2010
$colNumber = PHPExcel_Cell::columnIndexFromString($colString);

возвращает 1 из $ colString «A», 26 из «Z», 27 из «AA» и т. Д.

и (почти) обратный

$colString = PHPExcel_Cell::stringFromColumnIndex($colNumber);

возвращает 'A' из $ colNumber 0, 'Z' из 25, 'AA' из 26 и т. Д.

EDIT

Пара полезных трюков:

Для класса рабочего листа есть метод 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

хотя он использует итераторы, поэтому будет немного медленнее

OR

Воспользуйтесь возможностью PHP увеличить строки символов Perl Style

$highestColumm = $this->objPHPExcel->setActiveSheetIndex(0)->getHighestColumn(); // e.g. "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 ++

1 голос
/ 23 декабря 2014

Я предлагаю преобразовать 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;
    }
1 голос
/ 24 февраля 2014

самое простое решение $ getColumnIndexFromString = PHPExcel_Cell :: columnIndexFromString ($ самое высокоеColumn);

1 голос
/ 16 января 2014

Это несколько упрощенная версия ответа dqhendricks. Я добавил в копии одну функцию, предполагающую, что вы вводите полную ссылку на ячейку Excel (например, «AB12»), а другую, предполагающую, что вы вводите только ссылку на столбец (то есть «AB»). Они оба возвращают нулевой индекс.

Ввод полной ссылки на ячейку

function getIndex ($cell) {
    // Strip cell reference down to just letters
    $let = preg_replace('/[^A-Z]/', '', $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.

1 голос
/ 30 декабря 2010

Не уверен, что у вашего класса есть встроенный метод, но вы всегда можете использовать функцию 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. Должен работать до любого номера столбца. Испытали. Надеюсь, это поможет.

0 голосов
/ 15 октября 2017
/**
 * 
 */
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;
}
0 голосов
/ 14 ноября 2012
    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) // вернуть A

...