如何将工作表的列数作为整数(28)而不是Excel字母(“AB”)?

2022-08-30 12:13:42

鉴于:

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

我可以像这样循环访问行,但它非常慢,即在具有具有“EL”列的工作表的3MB Excel文件中,每行大约需要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;
}

当我像这样迭代时,它的速度要快得多(在30秒内大约2000行),但我必须将字母(例如“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”)?


答案 1
$colNumber = PHPExcel_Cell::columnIndexFromString($colString);

从“A”的$colString返回 1,从“Z”返回 26,从“AA”返回 27,依此类推。

和(几乎)反转

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

从 0 的$colNumber返回“A”,从 25 返回“Z”,从 26 返回“AA”,依此类推。

编辑

几个有用的技巧:

工作表类有一个 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 样式的功能

$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++ 提高了


答案 2

这是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;
}

该函数从字符串的背面转到前面以增加列的值。它使用该函数获取字符的数值,然后减去字母值以提供本地列值。最后,乘以当前 26 的幂。ord()


推荐