如何在phpExcel中插入行,正确的动态公式?

时间:2016-05-11 13:56:36

标签: excel sum phpexcel formula

我有一个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;
}

0 个答案:

没有答案