PHPExcel插入数组公式
PHPExcel insert array formula
我要插入这个数组公式:
{=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))}
但是当我使用时:
$sheet->getCell("C1")->setValue("{=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))}");
不行,我查了文档,还是没找到。
我找不到任何答案,所以我通过 PHPExcel 为自己制定了一个解决方案:
in /PHPExcel/Cell.php
在 switch($pDataType)
的第 251 行添加:
case PHPExcel_Cell_DataType::TYPE_FORMULA_ARRAY:
$this->_value = (string)$pValue;
break;
in /PHPExcel/Cell/DataType.php
添加这个常数:
const TYPE_FORMULA_ARRAY = 't';
最后 /PHPExcel/Writer/Excel2007/Worksheet.php
我在第 1095 行开始的开关中添加了这个:
case 't': // Array Formulae
$objWriter->startElement('f');
$objWriter->writeAttribute('t', 'array');
$objWriter->writeAttribute('ref', $pCellAddress);
$objWriter->writeAttribute('aca', '1');
$objWriter->writeAttribute('ca', '1');
$objWriter->text($cellValue);
$objWriter->endElement();
if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
if ($this->getParentWriter()->getPreCalculateFormulas()) {
$calculatedValue = $pCell->getCalculatedValue();
if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
} else {
$objWriter->writeElement('v', '0');
}
} else {
$objWriter->writeElement('v', '0');
}
}
break;
然后我使用了这样的函数:
$sheet->getCell("C1")->setValueExplicit("=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))", PHPExcel_Cell_DataType::TYPE_FORMULA_ARRAY);
当我创建 excel 文件时一切正常!
因为在搜索 PHPExcel 的后继者 PHPSpreadsheet 时仍然会出现这个 question/answer,我想补充一点,后者支持内置的数组公式。只需像往常一样分配公式并设置类型-数组的属性:
$attrs = $sheet->getCell("C1")->getFormulaAttributes();
$attrs['t'] = 'array';
$sheet->getCell("C1")->setFormulaAttributes($attrs);
这是我使用 PhpSpreadsheet 插入数组公式的修复方法。
我对功能做了一些改动 'writeCellFormula'
(PhpSpreadsheet\Writer\Xlsx\Worksheet.php)
用法:
$sheet = $spreadsheet->getActiveSheet();
$attrs = $sheet->getCell("C1")->getFormulaAttributes();
$attrs['t'] = 'array';
$sheet->getCell("C1")->setFormulaAttributes($attrs);
$sheet->setCellValue("C1",'=SUM(A1:A3*B1:B3)');
预期输出: {=SUM(Q1:Q3*R1:R3) }
private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell): void
{
$attributes = $pCell->getFormulaAttributes();
if ($attributes['t']=='array')
{
$pCellAddress = $pCell->getCoordinate();
$objWriter->startElement('f');
$objWriter->writeAttribute('t', 'array');
$objWriter->writeAttribute('ref', $pCellAddress);
//$objWriter->writeAttribute('aca', '1');
//$objWriter->writeAttribute('ca', '1');
$objWriter->text(substr($cellValue, 1));
$objWriter->endElement();
return;
}
$calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue;
if (is_string($calculatedValue)) {
if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) {
$this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue);
return;
}
$objWriter->writeAttribute('t', 'str');
}
elseif (is_bool($calculatedValue) ) {
$objWriter->writeAttribute('t', 'b');
$calculatedValue = (int) $calculatedValue;
}
$objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
self::writeElementIf(
$objWriter,
$this->getParentWriter()->getOffice2003Compatibility() === false,
'v',
($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#')
? StringHelper::formatNumber($calculatedValue) : '0'
);
}
我要插入这个数组公式:
{=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))}
但是当我使用时:
$sheet->getCell("C1")->setValue("{=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))}");
不行,我查了文档,还是没找到。
我找不到任何答案,所以我通过 PHPExcel 为自己制定了一个解决方案:
in /PHPExcel/Cell.php
在 switch($pDataType)
的第 251 行添加:
case PHPExcel_Cell_DataType::TYPE_FORMULA_ARRAY:
$this->_value = (string)$pValue;
break;
in /PHPExcel/Cell/DataType.php
添加这个常数:
const TYPE_FORMULA_ARRAY = 't';
最后 /PHPExcel/Writer/Excel2007/Worksheet.php
我在第 1095 行开始的开关中添加了这个:
case 't': // Array Formulae
$objWriter->startElement('f');
$objWriter->writeAttribute('t', 'array');
$objWriter->writeAttribute('ref', $pCellAddress);
$objWriter->writeAttribute('aca', '1');
$objWriter->writeAttribute('ca', '1');
$objWriter->text($cellValue);
$objWriter->endElement();
if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
if ($this->getParentWriter()->getPreCalculateFormulas()) {
$calculatedValue = $pCell->getCalculatedValue();
if (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {
$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));
} else {
$objWriter->writeElement('v', '0');
}
} else {
$objWriter->writeElement('v', '0');
}
}
break;
然后我使用了这样的函数:
$sheet->getCell("C1")->setValueExplicit("=SUM(IF(FREQUENCY(IF(T9:T977=1,MATCH(U9:U977,U9:U977,0)),ROW(U9:U977)-ROW(U9)+1),1))", PHPExcel_Cell_DataType::TYPE_FORMULA_ARRAY);
当我创建 excel 文件时一切正常!
因为在搜索 PHPExcel 的后继者 PHPSpreadsheet 时仍然会出现这个 question/answer,我想补充一点,后者支持内置的数组公式。只需像往常一样分配公式并设置类型-数组的属性:
$attrs = $sheet->getCell("C1")->getFormulaAttributes();
$attrs['t'] = 'array';
$sheet->getCell("C1")->setFormulaAttributes($attrs);
这是我使用 PhpSpreadsheet 插入数组公式的修复方法。 我对功能做了一些改动 'writeCellFormula' (PhpSpreadsheet\Writer\Xlsx\Worksheet.php)
用法:
$sheet = $spreadsheet->getActiveSheet();
$attrs = $sheet->getCell("C1")->getFormulaAttributes();
$attrs['t'] = 'array';
$sheet->getCell("C1")->setFormulaAttributes($attrs);
$sheet->setCellValue("C1",'=SUM(A1:A3*B1:B3)');
预期输出: {=SUM(Q1:Q3*R1:R3) }
private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $pCell): void
{
$attributes = $pCell->getFormulaAttributes();
if ($attributes['t']=='array')
{
$pCellAddress = $pCell->getCoordinate();
$objWriter->startElement('f');
$objWriter->writeAttribute('t', 'array');
$objWriter->writeAttribute('ref', $pCellAddress);
//$objWriter->writeAttribute('aca', '1');
//$objWriter->writeAttribute('ca', '1');
$objWriter->text(substr($cellValue, 1));
$objWriter->endElement();
return;
}
$calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $pCell->getCalculatedValue() : $cellValue;
if (is_string($calculatedValue)) {
if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) {
$this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue);
return;
}
$objWriter->writeAttribute('t', 'str');
}
elseif (is_bool($calculatedValue) ) {
$objWriter->writeAttribute('t', 'b');
$calculatedValue = (int) $calculatedValue;
}
$objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue));
self::writeElementIf(
$objWriter,
$this->getParentWriter()->getOffice2003Compatibility() === false,
'v',
($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#')
? StringHelper::formatNumber($calculatedValue) : '0'
);
}