我有一个Price-List,我喜欢用phpExcel插入行(带有项目价格)。我在Excel文件中有一个公式来计算总计:
=SUMME(E$1:E11)
我使用命令插入行(价格):
$oSheet->insertNewRowBefore( $row + 1, 1 );
渲染后,一切看起来都不错,但公式仍然相同:
=SUMME(E$1:E11)
但它必须是例如(当添加3行时):
=SUMME(E$1:E13)
所以我得到错误的总结果。只计算一个项目而不是所有项目。
如何添加一行,并自动更新公式?和Excel一样吗?
这是我的PHP函数,它取代了Excel文件中的占位符:
$aValueExcel = array();
$aHiddenExcel = array();
$aHiddenExcelRow = array();
define( "HideRow", "HideRow" );
define( "CreatePDF", "CreatePDF" );
define( "Hidden", "Hidden" );
/** Include PHPExcel_IOFactory */
require_once __DIR__ . '/../classes/PHPExcel/IOFactory.php';
/** Ersetzt die Variablen in Platzhaltern <variable> mit den Werten der Global Array-Variable $aValueExcel.
*
* Parameter:
* $sFileTemplate Der Name des Excel-Files, das bearbeitet werden soll.
* $sTitle Dummy Variable.
*
* Globale Variablen
* $aValueExcel Die zu ersetzenden Werte als Assoziatives Array.
* $aHiddenExcel Der Namen der Felder, die nicht angezeigt werden sollen.
* $aHiddenExcelRow Der Namen der Felder, deren ganze Zeile nicht angezeigt werden soll.
*/
function CreateExcel( $sFileTemplate, $sTitle ) {
global $aValueExcel;
global $aHiddenExcel;
global $aHiddenExcelRow;
$sPathTemplate = $GLOBALS['DIR_KUNDEN'] ."/docs/templates/" . $sFileTemplate;
if (!file_exists( $sPathTemplate )) {
exit("File not Found");
}
$objPHPExcel = PHPExcel_IOFactory::load( $sPathTemplate );
$objPHPExcel->setActiveSheetIndex(0);
$oSheet = $objPHPExcel->getActiveSheet();
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
/** Wir definieren welche Spalten durchsucht werden sollen. Für eine Optimierte Geschwindigkeit, machen wir nur die Spalten von A bis Z. */
$chars = array();
$chars[] = "A";
$chars[] = "B";
$chars[] = "C";
$chars[] = "D";
$chars[] = "E";
$chars[] = "F";
$chars[] = "G";
$chars[] = "H";
$chars[] = "I";
$chars[] = "J";
$chars[] = "K";
$chars[] = "L";
$chars[] = "M";
$chars[] = "N";
$chars[] = "O";
$chars[] = "P";
/** Initialisieren. Die letzte nicht leere Spalte festhalten um die Dokumentgrösse richtig einstellen zu können. */
$lastFilledColumnIndex = 0;
$lastFilledRowIndex = 0;
for( $row = 1; $row < 100; $row++ ) {
foreach( $chars as $char ) {
$value = $oSheet->getCell( $char . $row )->getValue();
if( !$value ) continue; /** Leere Zeilen überspringen */
if( array_search( $char, $chars ) > $lastFilledColumnIndex ) {
$lastFilledColumnIndex = array_search( $char, $chars );
}
if( $row > $lastFilledRowIndex ) {
$lastFilledRowIndex = $row;
}
$iCharPos = 0;
$blnOpenTag = false;
$aPlaceholder = array();
$iPlaceholder = 0;
/** Nach Platzhalter suchen */
while( isset( $value[ $iCharPos ] ) ) {
if( $blnOpenTag == true && $value[ $iCharPos ] != ">" ) {
if( !isset($aPlaceholder[ $iPlaceholder ]) ) $aPlaceholder[ $iPlaceholder ] = ""; /** Initialisieren */
$aPlaceholder[ $iPlaceholder ] .= $value[ $iCharPos ];
}
if( $value[ $iCharPos ] == "<" ) {
$blnOpenTag = true;
} elseif( $value[ $iCharPos ] == ">" ) {
$blnOpenTag = false;
++$iPlaceholder;
}
++$iCharPos;
}
/** Ersetzen */
if( count( $aPlaceholder ) > 0 ) {
foreach( $aPlaceholder as $sPlaceholder ) {
if( isset($aValueExcel[ $sPlaceholder ]) ) {
if( is_array( $aValueExcel[ $sPlaceholder ] ) == true ) {
/** Es ist ein Array. Hier werden alle Werte der Reihe nach in das Excel eingefügt und gegebenfalls neue Zeilen erstellt. */
$blnFirst = true;
foreach( $aValueExcel[ $sPlaceholder ] as $rowValue ) {
$charActual = $char;
if( $blnFirst == false ) {
/** Eine neue Zeile einfügen */
$oSheet->insertNewRowBefore( $row + 1, 1 );
++$row;
} else {
$rowOriginal = $row;
}
foreach( $rowValue as $fieldValue ) {
$oSheet->setCellValue( $charActual . $row, utf8_encode( $fieldValue ) );
$charActual = $chars[ array_search( $charActual, $chars ) + 1 ]; /** Einen Buchstaben weitergehen */
}
/** Restliche Werte ausserhalb des Arrays vom Original übernehmen. */
foreach( $chars as $charKey => $charActual2 ) {
if( $charKey < array_search( $charActual, $chars ) ) {
/** Nur die Felder ausserhalb der Array-Daten von der Originalspalte übernehmen. */
continue;
}
/** Wert kopieren */
$valueCell = $oSheet->getCell( $charActual2 . $rowOriginal )->getValue();
if( $valueCell[0] == "=" ) {
/** Es ist eine Formel. Korrigiere die Formel, sodass Sie fortlaufend ist. */
$valueCell = str_replace( $rowOriginal, $row, $valueCell );
}
$oSheet->setCellValue( $charActual2 . $row, $valueCell );
}
$blnFirst = false;
}
} else {
/** Es ist kein Array */
$value = str_replace( "<". $sPlaceholder .">", $aValueExcel[ $sPlaceholder ], $value );
$oSheet->setCellValue( $char . $row, utf8_encode( $value ) );
}
} else {
/** Kein Wert für den Platzhalter gefunden. Wir blenden ihn aus, da wir davon ausgehen dass er nicht gebraucht wird */
$oSheet->setCellValue( $char . $row, "" );
}
if( isset($aHiddenExcelRow[ $sPlaceholder ]) && $aHiddenExcelRow[ $sPlaceholder ] == true ) {
/** Row unsichtbar machen */
$oSheet->getRowDimension( $row )->setVisible( false );
}
elseif( isset($aHiddenExcel[ $sPlaceholder ]) && $aHiddenExcel[ $sPlaceholder ] == true ) {
/** Verstecken */
$styleArray = array(
'font' => array(
'color' => array('rgb' => 'FFFFFF')
));
$oSheet->getStyle( $char . $row )->applyFromArray($styleArray);
}
}
}
}
}
/** Unnötige Zeilen und Spalten ausblenden, damit keine leeren Seiten gedruckt werden. */
for( $row = 1; $row < 100; $row++ ) {
foreach( $chars as $charKey => $char ) {
if( $charKey > $lastFilledColumnIndex ) {
$oSheet->getColumnDimension( $char )->setVisible(false);
}
}
if( $row > $lastFilledRowIndex ) {
$oSheet->getRowDimension( $row )->setVisible(false);
}
}
$oSheet->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
$oSheet->setBreak( $chars[ $lastFilledColumnIndex + 1 ] . "1" , PHPExcel_Worksheet::BREAK_COLUMN );
//$oSheet->setBreak( $lastFilledColumnIndex , PHPExcel_Worksheet::BREAK_ROW );
//$objPHPExcel->getActiveSheet()->setBreak( 'A20' , PHPExcel_Worksheet::BREAK_ROW );
/** Speichern */
$filename = time() ."_". str_replace('.php', '.xlsx', basename( $sPathTemplate ));
$objWriter->save( $GLOBALS['DIR_KUNDEN'] ."/temp/". $filename );
return $filename;
}