我有一个测试excel文件,我尝试更新一个单元格并重新计算结果,但它不起作用?甚至通过该单元格上的接口明确地设置公式
$prevI11 = $reader->getActiveSheet()->getCell('I11')->getCalculatedValue();
$reader->getActiveSheet()->setCellValue('I11','=G11');
$reader->getActiveSheet()->setCellValue('G11',89.0);
$newformulaI11 = $reader->getActiveSheet()->getCell('I11')->getValue();
$newI11 = $reader->getActiveSheet()->getCell('I11')->getCalculatedValue();
dd($prevI11.'|'.$newformulaI11.'|'.$newI11);
I11的Excel文件中的初始值为 - 2
结果是string(8) "2|=G11|2"
,显然只是加载文件的原始值
答案 0 :(得分:0)
默认情况下,PHPExcel会缓存计算结果,以便在您多次请求同一单元格的计算值时,无需再次重新计算。
这意味着如果您检索单元格的计算值(在您的情况下为I11
),则更改将影响计算的单元格的值并再次检索计算的值,您将检索缓存中的上一个结果,而不是重新计算它。
您可以使用
禁用此缓存行为PHPExcel_Calculation::getInstance($reader)->disableCalculationCache();
或使用
在任何点刷新缓存PHPExcel_Calculation::getInstance($reader)->clearCalculationCache();
修改强>
作为测试方法,PHPExcel计算引擎有一个内置调试器:
// Create new PHPExcel object
$objPHPExcel = new PHPExcel();
// Add some data
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('G11', 2)
->setCellValue('I11', '=G11');
$objPHPExcel->getActiveSheet()->setTitle('Simple');
function testFormula($sheet, $cell) {
$formulaValue = $sheet->getCell($cell)->getValue();
echo 'Formula Value is ' , $formulaValue , EOL;
$expectedValue = $sheet->getCell($cell)->getOldCalculatedValue();
echo 'Expected Value is ' , ((!is_null($expectedValue)) ? $expectedValue : 'UNKNOWN') , EOL;
$calculate = false;
try {
$tokens = PHPExcel_Calculation::getInstance($sheet->getParent())
->parseFormula($formulaValue, $sheet->getCell($cell));
echo 'Parser Stack :-' , EOL;
print_r($tokens);
echo EOL;
$calculate = true;
} catch (Exception $e) {
echo 'PARSER ERROR: ' , $e->getMessage() , EOL;
echo 'Parser Stack :-' , EOL;
print_r($tokens);
echo EOL;
}
if ($calculate) {
try {
$cellValue = $sheet->getCell($cell)->getCalculatedValue();
echo 'Calculated Value is ' , $cellValue , EOL;
echo 'Evaluation Log:' , EOL;
print_r(PHPExcel_Calculation::getInstance($sheet->getParent())
->getDebugLog()->getLog());
echo EOL;
} catch (Exception $e) {
echo 'CALCULATION ENGINE ERROR: ' , $e->getMessage() , EOL;
echo 'Evaluation Log:' , EOL;
print_r(PHPExcel_Calculation::getInstance($sheet->getParent())
->getDebugLog()->getLog());
echo EOL;
}
}
}
$sheet = $objPHPExcel->getActiveSheet();
PHPExcel_Calculation::getInstance($objPHPExcel)
->getDebugLog()->setWriteDebugLog(true);
testFormula($sheet,'I11');
$objPHPExcel->setActiveSheetIndex(0)
->setCellValue('G11', 89.0);
PHPExcel_Calculation::getInstance($objPHPExcel)
->clearCalculationCache();
testFormula($sheet,'I11');
在没有线路的情况下运行它来清除缓存,我得到以下输出
Formula Value is =G11
Expected Value is UNKNOWN
Parser Stack :-
Array
(
[0] => Array
(
[type] => Cell Reference
[value] => G11
[reference] => G11
)
)
Calculated Value is 2
Evaluation Log:
Array
(
[0] => Testing cache value for cell Simple!I11
[1] => Simple!I11 => Evaluating Cell G11 in current worksheet
[2] => Simple!I11 => Evaluation Result for cell Simple!G11 is a floating point number with a value of 2
)
Formula Value is =G11
Expected Value is UNKNOWN
Parser Stack :-
Array
(
[0] => Array
(
[type] => Cell Reference
[value] => G11
[reference] => G11
)
)
Calculated Value is 2
Evaluation Log:
Array
(
[0] => Testing cache value for cell Simple!I11
[1] => Retrieving value for cell Simple!I11 from cache
)
显示第二次检索到单元格I11的计算值时,它不会重新计算但会检索缓存的值
使用清除缓存的行,我得到了
Formula Value is =G11
Expected Value is UNKNOWN
Parser Stack :-
Array
(
[0] => Array
(
[type] => Cell Reference
[value] => G11
[reference] => G11
)
)
Calculated Value is 2
Evaluation Log:
Array
(
[0] => Testing cache value for cell Simple!I11
[1] => Simple!I11 => Evaluating Cell G11 in current worksheet
[2] => Simple!I11 => Evaluation Result for cell Simple!G11 is a floating point number with a value of 2
)
Formula Value is =G11
Expected Value is UNKNOWN
Parser Stack :-
Array
(
[0] => Array
(
[type] => Cell Reference
[value] => G11
[reference] => G11
)
)
Calculated Value is 89
Evaluation Log:
Array
(
[0] => Testing cache value for cell Simple!I11
[1] => Simple!I11 => Evaluating Cell G11 in current worksheet
[2] => Simple!I11 => Evaluation Result for cell Simple!G11 is a floating point number with a value of 89
)
显示缓存被清除,并且计算引擎被迫重新计算公式,同时考虑到单元格G11的新值