• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Php Spreadsheet & PHP 8

flori-software

Neues Mitglied
Hallo zusammen,

hat jemand von euch bereits versucht Excel-Dateien mit PhP Spreadsheet unter PHP 8 zu erstellen? Ich habe PhP Spreadsheet erst vor einem Monat bei mir installiert, ist also aktuell. Scheint bei mir aber unter PHP 8 nicht zu laufen. PhPMyAdmin weint an mehreren Stellen und die Exceldateien, die durch meine Skripte erstellt werden, lassen sich nicht öffnen. Unter PHP 7.4.12 läuft alles perfekt.

Hat jemand andere Erfahrungen als ich gemacht? Vielleicht ist es eine Konfigurationssache? Bin gespannt auf eure Rückmeldungen.

Arek
 
Werbung:
Was hat denn phpMyAdmin mit phpSpreadsheet zu tun?

Wenn sich Dateien nicht öffnen lassen würde ich mal schauen ob das Script Fehler ausgibt. Mal in den error_log schauen.
 
Werbung:
Zunächst mal - ich habe da tatsächlich etwas verwechselt. Es erscheint in phpMaAdmin folgende Fehlermeldung, die mit PhpSpreadsheet nichts zu tun hat:

Deprecation Notice in ./libraries/classes/Di/ReflectorItem.php#82
dot.gif
Method ReflectionParameter::getClass() is deprecated

Backtrace

./libraries/classes/Di/ReflectorItem.php#50: PhpMyAdmin\Di\ReflectorItem->_resolveArgs(
array,
array,
)
./libraries/classes/Di/FactoryItem.php#27: PhpMyAdmin\Di\ReflectorItem->invoke(array)
./libraries/classes/Di/Container.php#62: PhpMyAdmin\Di\FactoryItem->get(array)
./libraries/classes/Di/AliasItem.php#44: PhpMyAdmin\Di\Container->get(
string 'PhpMyAdmin\\Controllers\\Database\\DatabaseStructureController',
array,
)
./libraries/classes/Di/Container.php#62: PhpMyAdmin\Di\AliasItem->get(array)
./db_structure.php#35: PhpMyAdmin\Di\Container->get(
string 'DatabaseStructureController',
array,

)

sowie

Deprecation Notice in ./vendor/twig/twig/src/Node/IncludeNode.php#25
dot.gif
Required parameter $lineno follows optional parameter $only

Backtrace

./vendor/composer/ClassLoader.php#444: include()
./vendor/composer/ClassLoader.php#322: Composer\Autoload\includeFile(string '/Applications/MAMP/bin/phpMyAdmin/vendor/composer/../twig/twig/src/Node/IncludeNode.php')
./vendor/twig/twig/src/TokenParser/IncludeTokenParser.php#33: Composer\Autoload\ClassLoader->loadClass(string 'Twig\\Node\\IncludeNode')
./vendor/twig/twig/src/Parser.php#209: Twig\TokenParser\IncludeTokenParser->parse()
./vendor/twig/twig/src/TokenParser/ForTokenParser.php#51: Twig\Parser->subparse(array)
./vendor/twig/twig/src/Parser.php#209: Twig\TokenParser\ForTokenParser->parse()
./vendor/twig/twig/src/TokenParser/IfTokenParser.php#41: Twig\Parser->subparse(array)
./vendor/twig/twig/src/Parser.php#209: Twig\TokenParser\IfTokenParser->parse()
./vendor/twig/twig/src/Parser.php#122: Twig\Parser->subparse(
NULL,
boolean false,
)
./vendor/twig/twig/src/Environment.php#735: Twig\Parser->parse()
./vendor/twig/twig/src/Environment.php#793: Twig\Environment->parse()
./vendor/twig/twig/src/Environment.php#482: Twig\Environment->compileSource()
./vendor/twig/twig/src/Environment.php#445: Twig\Environment->loadClass(
string '__TwigTemplate_90e7b39835cdc945bc2cc586f171fd696393f183828babffe59b9369e68ba774',
string 'list/unordered.twig',
NULL,
)
./vendor/twig/twig/src/Environment.php#423: Twig\Environment->loadTemplate(string 'list/unordered.twig')
./libraries/classes/Template.php#115: Twig\Environment->load(string 'list/unordered.twig')
./libraries/classes/Config/FormDisplayTemplate.php#79: PhpMyAdmin\Template->render(array)
./libraries/classes/Config/FormDisplay.php#302: PhpMyAdmin\Config\FormDisplayTemplate::displayTabsTop(array)
./libraries/classes/Config/PageSettings.php#174: PhpMyAdmin\Config\FormDisplay->getDisplay(
boolean true,
boolean true,
boolean false,
string 'index.php?db=&table=&server=1&target=&lang=de',
array,
)
./libraries/classes/Config/PageSettings.php#93: PhpMyAdmin\Config\PageSettings->_getPageSettingsDisplay(
,
NULL,
)
./libraries/classes/Config/PageSettings.php#225: PhpMyAdmin\Config\PageSettings->__construct(
string 'Navi',
string 'pma_navigation_settings',
)
./libraries/classes/Navigation/Navigation.php#80: PhpMyAdmin\Config\PageSettings::getNaviSettings()
./libraries/classes/Header.php#440: PhpMyAdmin\Navigation\Navigation->getDisplay()
./libraries/classes/Response.php#266: PhpMyAdmin\Header->getDisplay()
./libraries/classes/Response.php#279: PhpMyAdmin\Response->_getDisplay()
./libraries/classes/Response.php#438: PhpMyAdmin\Response->_htmlResponse()

PhpMyAdmin\Response->response()


Hier haben der Ordner Vendor und der Composer bei mir den Eindruck erweckt, es hätte etwas mit Php Spreadsheet zu tun, da dieses über den Composer installiert wurde. Meldungen erscheinen erst, wenn ich in PhpMyAdmin meine Datenbank auswähle.

Dies ist alles also zunächst zweitrangig (da wahrscheinlich keine Verbindung zu meinem Excel-Problem besteht). Wäre dennoch interessant zu wissen, was genau hier das Problem ist - die Angaben in der Deprecation Notice übersteigen mein wissen. Da ich auf dem Mac MAMP 6.3 nutze, welches PHP8 mitbringt, würde ich annehmen, dass hier evtl. manche von MAMP verwendeten Funktionen als veraltet angesehen werden, jedoch zunächst dennoch laufen - sonst würde MAMP dieses Produkt wohl so nicht anbieten.
 
Fakt ist aber - und das ist für mich jetzt das dringendere Problem - dass ich unter PHP8 nach wie vor keine funktionierenden Exceldateien erstellen kann. Fehlermeldungen bekomme ich keine, es wird nach wie vor eine Datei erstellt, nur lässt sie sich mit Excel nicht öffnen - Excel behauptet, die Datei sei beschädigt. Das Skript sieht so aus:

Code:
require '../../bin/vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
use PhpOffice\PhpSpreadsheet\Style\Color;

$datum_von                    = $_GET["datum_von"] ?? "2020-01-01";
$datum_bis                    = $_GET["datum_bis"] ?? "2020-12-31";

$leistungen_arrays = Array();
$leistungen_arrays[0] = unserialize($_SESSION["serialized_data_abgerechnet"]);
$leistungen_arrays[1] = unserialize($_SESSION["serialized_data_nicht_abgerechnet"]);

$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load("../excel/Leistungsstatistik.xlsx");
foreach($leistungen_arrays as $key=>$array_leistungen) {
    // Überschrift
    $spreadsheet->getSheet($key)
                ->setCellValue('A1', "Leistungsstatistik für den Zeitraum ".date_to_datum($datum_von)." bis ".date_to_datum($datum_bis))
                ->getStyle('A1')->getFont()->setSize(18);
    $spreadsheet->getSheet($key)->getStyle('A1')->getFont()->setName('ArialBlack');
    $zeile = 3;

    // Ausgabe der Leistungen unterteilt 1. nach ARtikeln 2. nach Ertragskonto
    $zeilen_summen_per_konto = Array();
    foreach($array_leistungen as $id=>$artikel) {
        // Externe Umsätze werden ausgelassen, da die Leistungsstatistik sich per Definition nur auf die eigenen Umsätze bezieht
        if($id != 0) {
            $volle_artikelbezeichnung = gesuchter_wert($id, "abrechnung_artikel", "text_rechnung");
            $spreadsheet->getSheet($key)
                        ->setCellValue('A'.$zeile, utf8_encode($artikel["artikelbezeichnung"]." / ".$volle_artikelbezeichnung))
                        ->getStyle('A'.$zeile)->getFont()->setSize(18);
            $zeile = $zeile + 2;

            // An dieser Stelle werden die Leistungen noch nach Ertragskonto sortiert
            $konten = leistungen::nach_ertragskonto_ordnen($artikel["leistungen"]);
            foreach($konten as $id_ertragskonto=>$konto) {
                $kontonummer = gesuchter_wert($id_ertragskonto, "kontenplan", "nr");
                $spreadsheet->getSheet($key)
                        ->setCellValue('A'.$zeile, utf8_encode("Konto ".$kontonummer." - ".$konto["ertragskonto"]))
                        ->getStyle('A'.$zeile)->getFont()->setSize(18);
                $zeile++;

                $spreadsheet->getSheet($key)
                            ->setCellValue('A'.$zeile, "Datum")
                            ->setCellValue('B'.$zeile, "Kunde")
                            ->setCellValue('C'.$zeile, "Menge")
                            ->setCellValue('D'.$zeile, "Preis")
                            ->setCellValue('E'.$zeile, "Summe")
                            ->setCellValue('F'.$zeile, "Kostenstelle")
                            ->setCellValue('G'.$zeile, "Rechnung")
                            ->setCellValue('H'.$zeile, "Konto")
                            ->setCellValue('I'.$zeile, "Artikel")
                            ->getStyle('A'.$zeile.':I'.$zeile)->getFont()->setSize(12);
                // Farbiger Hintergrund für die Zeile mit Überschriften
                $spreadsheet->getSheet($key)->getStyle('A'.$zeile.':I'.$zeile)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00BFFF');

                $zeile++;
                $erste_zeile_des_blocks_konto = $zeile;
                foreach($konto["leistungen"] as $leistung) {
                    // Anzeige der einzelnen Leistungen nur wenn gewünscht
                    $menge       += $leistung->menge;
                    $gesamtpreis += $leistung->gesamtpreis;
                    if($key == 0) {
                        // Abgerechnete Leistungen
                        $rechnung_nr = gesuchter_wert($leistung->id_rechnung, "abrechnung_rechnungen".$leistung->id_firma, "rechnung_nr");
                    } else {
                        $rechnung_nr = "Proberechnung";
                    }
                    
                    $spreadsheet->getSheet($key)
                            ->setCellValue('A'.$zeile, date_to_datum($leistung->datum_von))
                            ->setCellValue('B'.$zeile, utf8_encode(kundenname($leistung->id_kunde)))
                            ->setCellValue('C'.$zeile, $leistung->menge)
                            ->setCellValue('D'.$zeile, $leistung->einzelpreis)
                            ->setCellValue('E'.$zeile, $leistung->gesamtpreis)
                            ->setCellValue('F'.$zeile, gesuchter_wert($leistung->id_kostenstelle, "Kostenstellen", "kostenstellen_nr")." ".gesuchter_wert($leistung->id_kostenstelle, "Kostenstellen", "kostenstellen_bezeichnung"))
                            ->setCellValue('G'.$zeile, $rechnung_nr)
                            ->setCellValue('H'.$zeile, gesuchter_wert($leistung->id_ertragskonto, "kontenplan", "nr"))
                            ->setCellValue('I'.$zeile, gesuchter_wert($leistung->id_artikel, "abrechnung_artikel", "artikel"))
                            ->getStyle('A'.$zeile.':I'.$zeile)->getFont()->setSize(12);
                    // Schriftgröße
                    $letzte_zeile = $zeile;
                    $zeile++;
                }
                // Summen der Menge und des Ertrags im jeweiligen Ertragskonto
                $spreadsheet->getSheet($key)
                    ->setCellValue('A'.$zeile, 'Summe der Mengen und Umsatz / Ertragskonto:')
                    ->setCellValue('C'.$zeile, '=SUM(C'.$erste_zeile_des_blocks_konto.':C'.$letzte_zeile.')')
                    ->setCellValue('E'.$zeile, '=SUM(E'.$erste_zeile_des_blocks_konto.':E'.$letzte_zeile.')');
                 // Farbiger Hintergrund für die Zeile mit dem Umsatz / Gesamtmenge per Ertragskonto
                $spreadsheet->getSheet($key)->getStyle('A'.$zeile.':I'.$zeile)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('7FFF00');
                // Die Zeilennummer merken wir uns in einem Array, um am Ende die Formel für die Gesamtsumme zu bilden
                $zeilen_summen_per_konto[] = $zeile;
                $zeile++;
            }
        }
    }
    $formel_summe_jahresumsatz = "=";
    foreach($zeilen_summen_per_konto as $nr=>$row) {
        if($nr == 0) {
            $formel_summe_jahresumsatz .= "E".$row;
        } else {
            $formel_summe_jahresumsatz .= "+E".$row;
        }
    }
    $spreadsheet->getSheet($key)
                    ->setCellValue('A'.$zeile, 'Jahresumsatz')
                    ->setCellValue('E'.$zeile, $formel_summe_jahresumsatz);
    // Farbiger Hintergrund für die Zeile mit dem Jahresumsatz
    $spreadsheet->getSheet($key)->getStyle('A'.$zeile.':I'.$zeile)->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('FFFF00');
}
                
// set the header first, so the result will be treated as an xlsx file
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

// make it an attachment so we can define filename
header('Content-Disposition: attachment;filename="Leistungsstatistik.xlsx"');

// create IOFactory object
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
 
Hast du in den error_log geschaut ob wirklich keine Fehler auftauchen?

Du kannst alternativ auch die letzten 4 Zeilen auskommentieren und schauen ob Fehler dargestellt werden. Wenn defekte Dateien erstellt werden ist es fast immer so, dass Fehler in der Ausgabe sind, die dann mit in die Datei geschrieben werden und diese dann zerschiessen.
 
Werbung:
Welche Versionen von phpmyadmin und phpspreadsheet nutzt Du?

Bei phpmyadmin gibt es ein Issue was genau deinen Fehler beschreibt und dort steht auch mit welcher Version des gefixt ist: https://github.com/phpmyadmin/phpmyadmin/issues/16519

Bei der Excel-Datei: schau sie dir mal im Quellcode mit Notepad++ oder so an. Da könnte ggfs. mitten drin eine PHP-Meldung stehen.
 
Es war tatsächlich so, dass das Skript den Fehler in die Exceldatei geschrieben und somit diese unbrauchbar gemacht hat. Fehler behoben, vielen Dank!

Wenn der Fehler mit phpMyAdmin bekannt ist, kann ich erstmal entspannt bleiben. DSie Version kann ich ohnehin nicht selber wählen - lokal nutze ich das, was in MAMP ist, auf dem Webspace das, was der Webspaceanbieter dort installiert hat.

Danke für eure Hilfe und einen schönen Sonntag!
 
Werbung:
Das wird sicherlich kommen, wenn ich von einem Verwalteten Webspace auf einen eigenen Server umziehe. Im Augenblick ist der verwaltete Webspace jedoch sowohl die kostengünstigere als auch die bequemere Lösung. Da habe ich immerhin tägliches DB-Backup, Virenschutz etc alles inklusive. Auf einem eigenen Server / virtuellem Server ist all das natürlich auch möglich, dann aber muss ich mich selber darum kümmern - macht Arbeit - und davon habe ich ohnehin genug! :-)
 
Man muss doch keinen eigenen Server haben, um sich selber eine phpMyAdmin-Version zu installieren. Das geht auf jedem Webspace, es sei denn, du hättest noch nicht mal einen FTP-Zugang.
 
Zurück
Oben