Excel Dateien mit dem PHP-ExcelReader lesen

Für ein Projekt im Geschäft muss ich Daten von einer Excel Datei in eine mySQL Datenbank importieren. Das man im Excel nicht einfach sagen kann "Export zu mySQL" ist ja wohl klar. Also muss man das mit einem Script machen, ich benutze dazu PHP.
Das Problem ist ja bekanntlich nur das Auslesen der Daten aus der Excel Datei, das Schreiben in die DB geht mir PHP ja recht einfach von der Hand.

Eine Möglichkeit ist das Speichern der Excel Datei als XML und dann die XML Datei mit PHP zu lesen. Allerdings speichert Excel beim XML Export noch jede Menge zusätzlicher Informationen mit, die man nicht wirklich braucht, die Datei ist dann etwa doppelt so gross wie vorher und das lesen mit PHP Dauert auch ein weilchen.

Eine Alternative ist der PHP-ExcelReader. Damit kann man sehr einfach auf die Daten in Excel Dateien zugreifen. Das alles ohne einen mühsamen XML-Export und andere Verrenkungen. Hier möchte ich ein an einem kleinen Beispiel zeigen, wie man mit dem PHP-ExcelReader eine Excel Datei ausliest.

Als erstes muss man natürlich die ZIP Datei herunterladen und auf den Webserver kopieren. Dann kanns auch schon losgehen. Diese Datei muss nun natürlich auch eingebunden werden.
<?
// Excel Reader einbinden
require_once("excel/reader.php");
?>

Das das ganze eine Klasse ist kann man nun ein neues Objekt erstellen und auch gleich die Datei öffnen.:
<?
// Objekt erstellen, Encoding definieren
$xls=new Spreadsheet_Excel_Reader();
$xls->setOutputEncoding("CP12522");

// Die Datei daten.xls oeffnen
$xls->read("daten.xls");
?>


Da die Excel Dateien mehrere Tabellen (Worksheets) haben, muss man zuerst angeben, von welcher Tabelle man die Daten auslesen will. In diesem Beispiel wird mit einer Schleife jede Tabelle durchgegangen.
<?
// durch die Worksheets gehen
$counter=0;
foreach(
$xls->boundsheets AS $worksheet )
{
    
$sheet=$xls->sheets[$counter];
   
    
// worksheet ist der Zeiger in die Info der Tabelle
    // sheet ist der Zeiger in die Daten der Tabelle

    
$counter++;
}
?>

Mit den beiden Zeigern $worksheet und $sheet ist es nun ein leichtes die gewünschten Daten aus der Datei zu lesen. Nun aber noch ein komplettes Script, welches die Zeilen und Spalten der jeweiligen Tabelle und die Spaltenüberschriften ausgibt.
<?
ini_set
('memory_limit''10M');

// Excel Reader einbinden
require_once("excel/reader.php");

// Objekt erstellen, Encoding definieren
$xls=new Spreadsheet_Excel_Reader();
$xls->setOutputEncoding("CP12522");

// Die Datei daten.xls oeffnen
$xls->read("daten.xls");

// durch die Worksheets gehen
$counter=0;
foreach(
$xls->boundsheets AS $worksheet )
{
    
$sheet=$xls->sheets[$counter];

    
// worksheet ist der Zeiger in die Info der Tabelle
    // sheet ist der Zeiger in die Daten der Tabelle
    
$cols=$sheet['numCols'];
    
$rows=$sheet['numRows'];
    echo 
"<b>Arbeitsblatt ".($counter+1).": ".$worksheet['name']."</b><br />";
    echo 
"hat: ".$rows." Zeilen und ".$cols." Spalten.";

    
// Schleife ueber die Daten der Zeile 1 (bzw. 0
    
$celldata=$sheet['cells'];
    
$headrow=1;
    echo 
"<br /><br /><b>Spaltenueberschriften:</b><br />";
    for(
$x=1;$x<=$cols;$x++)
    {
        echo 
$celldata[$headrow][$x]." : ";
    }

    
$counter++;

    echo 
"<br /><br />";
}
?>


Beachten sollte man aber, dass so ein Script, je nach grösser der Excel Datei, einen grossen Speicher Verbrauch hat. Es macht also Sinn mit ini_set() das Memory-Limit etwas nach oben zu setzten, wenn man die Möglichkeit dazu hat.

Kommentare

Björn 13.02.08 22:48
Gravatar von Björn Hey!
Vielen Dank für die geniale Doku!!!
Habe momentan ein ähnliches Projekt und muss Daten einer
XLS in eine Datenbank bekommen.

Liebe Grüße
Björn
Michael 01.05.08 21:02
Gravatar von Michael Sali
Danke ich kann jetzt die Daten aus EXCEL aulesen. Leider bekomme ich beim Datum nur den Decimalwert (39613.5416667) zurück.
Wie kann ich den Wert entweder im richtigem Format lesen ?
Oder wie kann ich den Wert in das richtig Format umwandel ?
Danke für Deine Antwort.
Gruss Michael
david 01.05.08 22:31
Gravatar von david Hallo Michael
Ich kann dir da leider nicht weiterhelfen. Ich hatte schon seit längerem nichts mehr mit dem Excel Reader zu tun und hatte damals das Problem mit dem Datum nicht. Sorry.
Dirk 18.08.08 22:24
Gravatar von Dirk Und das funktioniert? Bisher sondiere ich nur die Möglichkeiten, um Excel irgendwie in PHP einzulesen. Das Skript klingt recht viel versprechend oder anders gesagt es ist das einzige Skript, was ich dazu finde. Es gibt da noch Excel Parser Pro, aber das kostet. Die letzte Version des Excel Readers ist von 2007, welche Excel-Versionen werden denn alles unterstützt?
david 19.08.08 07:56
Gravatar von david Bei mir hat das ganz gut funktioniert. Mit den "alten" .xls Dateien hatte ich keine Probleme, ob es mit den neuen .xlsx funktioniert, weiss ich nicht.
Denfie 20.08.08 15:51
Gravatar von Denfie Mich würde es interessieren, ob es möglich ist die Felder eine andere Codierung zu zuweisen. Denn ich habe das Problem wenn um laute im Text sind, dann wird das leider nicht mit übernommen und ich bekomm irgend ein komisches UTF16 Zeichen zurück. U+D66E oder U+D64E .

Hatte schon mal wer das Problem und kann mir dabei weiter helfen?
EF 22.08.08 13:43
Gravatar von EF @Denfie
Falls du meinst, dass dein XLS Dokument Umlaute enthält, dann achte darauf, diesen Eintrag zu setzen:

$xls->setOutputEncoding("utf-8");

Dann sollte es funktionieren. Wobei ich feststellen musste, dass es z.B. beim Polnischen Zeichensatz Probleme gab und ich die Zeichen nochmal durch utf8_encode jagen musste, bevor es ging.
sbia 04.09.08 13:10
Gravatar von sbia Ich denke da hat der excelreader (reader.php) einen Fehler drin. Sie gehen davon aus, dass Zellen, die nicht UTF16-kodiert sind, nur ASCII enthalten (was mit UTF-8 kompatibel wäre und von daher nicht umkodiert werden müsste). Bei mir (Excel 2003) war es jedoch so, dass Zellen mit Umlauten trotzdem nicht UTF16-kodiert wurden und somit die Zeile
$xls->setOutputEncoding("utf-8");
ohne Wirkung blieb.
Beim eintragen eines Euro-Zeichens geht Excel dann auf UTF16-Kodierung. D.h. ich kann nur spekulieren welche Kodierung die anderen Zellen verwenden. Im CP1252 gibt es m.W. das Euro-Zeichen schon. Bliebe noch der ISO-8859-1, wo es kein Euro-Zeichen gibt. Bei beiden sind die deutschen Umlaute gleich.
Abhilfe kann man schaffen, indem man an den Stellen in reader.php eine Umkodierung einfügt, wo vorher keine Umkodierung stattfand, da die Zelle vermeintlich nur ASCII Zeichen enthält. ASCII ist mit UTF8 kompatibel. CP1252 jedoch nicht.
Pissoir 24.12.08 20:20
Gravatar von Pissoir Hallo,

bei mir kommt immer dieser Fehler:

Fatal error: Maximum execution time of 30 seconds exceeded in /opt/lampp/htdocs/phpExecelReader/Excel/oleread.inc on line 172

weiß da vielleicht jemand weiter?

danke schon mal im voraus.
david 25.12.08 10:24
Gravatar von david Das Problem kann vorkommen, wenn grosse Dateien verarbeitet werden und das Script somit länger als Sekunden läuft. Dann wird es von PHP abgeklemmt, um endlosschleifen oder ähnliches zu vermeiden.
Du kannst aber ganz am Anfang deines Scripts eine Zeile einbauen, damit das Script länger laufen darf.
<? ini_set('max_execution_time'300); ?>

Damit darf das Script 5 Minuten laufen und wird erst dann abgeklemmt.
Ich hoffe, das hilft dir weiter.
pissoir 25.12.08 12:14
Gravatar von pissoir Hallo,

ja danke der Fehler ist jetzt weg.

Ich hab aber jetzt einen neuen Fehler:

Fatal error: Allowed memory size of 262144 bytes exhausted (tried to allocate 77824 bytes) in /opt/lampp/htdocs/test/phpExcelReader/Spreadsheet/Excel/reader.php on line 519

weißt du da vielleicht auch Rat?

Schöne Grüße
david 25.12.08 15:06
Gravatar von david Diese Fehlermeldung kommt, wenn dem Script nicht genug Speicher zur verfügung steht. Das kann man allerdings auch anpassen:
<? ini_set("memory_limit","10M"); ?>
pissoir 25.12.08 16:02
Gravatar von pissoir Hatte ich schon beides, hab mich jetzt entschieden .csvDatein einzulesen und zu verarbeiten.
Aber Dankeschön für die Vorschläge.

Schöne Grüße
rolf 26.12.08 02:10
Gravatar von rolf hi,
ich kriege diesen fehler angezeigt:
Warning: require_once(Spreadsheet/Excel/Reader/OLERead.php) [function.require-once]: failed to open stream: No such file or directory in C:\Programme\xampp\htdocs\laku\data\Excel\Excel\reader.php on line 31

Fatal error: require_once() [function.require]: Failed opening required 'Spreadsheet/Excel/Reader/OLERead.php' (include_path='.;C:\Programme\xampp\php\pear\') in C:\Programme\xampp\htdocs\laku\data\Excel\Excel\reader.php on line 31


Lösung:

In der dort vorhandenen Datei »reader.php« ist etwas sehr merkwürdig, nämlich die Zeile 31:
require_once 'Spreadsheet/Excel/Reader/OLERead.php';

Tatsächlich muss dort die Datei »oleread.inc« eingebunden werden, die in den gleichen Verzeichnis liegt wie die reader.php -- diese Zeile musst Du also ggf. anpassen.
quelle: http://www.selfhtml.de/forum/zeigebeitrag_4_125472_125445_0.php

thx für deine doku, die ist echt super...
ohne diese hätte ich mich net an das tool zuschaffen gemacht...

frohe weihnachten und nen schönes neues jahr
mobile 10.03.09 19:02
Gravatar von mobile Danke, dieser excelreader ist wirklich sehr praktisch.
Bisher musste ich direkt die OpenOffice Anwendung ohne GUI aufrufen, aber mit der OLE ist das natürlich viel eleganter :-)
yAnTar 23.03.09 10:32
Gravatar von yAnTar Danke fuer Loesung mit Error

Fatal error: require_once() [function.require]: Failed opening required 'Spreadsheet/Excel/Reader/OLERead.php' (include_path='.;C:\Programme\xampp\php\pear\') in C:\Programme\xampp\htdocs\laku\data\Excel\Excel\reader.php on line 31.

Das ist wirlkich mehrwuerdig
david 23.03.09 19:56
Gravatar von david Schau mal zwei Kommentare weiter oben. Von rolf:
Lösung:

In der dort vorhandenen Datei »reader.php« ist etwas sehr merkwürdig, nämlich die Zeile 31:
require_once 'Spreadsheet/Excel/Reader/OLERead.php';

Tatsächlich muss dort die Datei »oleread.inc« eingebunden werden, die in den gleichen Verzeichnis liegt wie die reader.php -- diese Zeile musst Du also ggf. anpassen.
quelle: http://www.selfhtml.de/forum/zeigebeitrag_4_125472_125445_0.php
Zwirne 04.04.09 23:05
Gravatar von Zwirne hallo zusammen!

Ich exportiere meine Daten wie auf dieser Site erklärt: http://www.devblog.de/index.php/archives/2005/02/05/25/

Das erstellte File lässt sich mit Excel öffnen, nur wenn ich es mit dem Reader auslesen will, bekomme ich folgenden Fehler: The filename xxx is not readable.

Dieser kommt von folgendem Check in der oleread.inc in Zeile 63:
if (substr($this->data, 0, 8) != IDENTIFIER_OLE)

Öffne ich das File in Excel, kopiere die vorher erstellten Zeilen und speichere das File unter neuem Namen ab funktionierts, weil dann ja durch Excel selbst was im Header geschrieben wird.

Kann mir da jemand weiterhelfen?

Thx
zwirne
Adam 08.05.09 07:33
Gravatar von Adam Hallo,
gibt es eine Möglichkeit für XLSX EXCEL 2007 Dateien.
Ich suche dringend eine.
Andeas Herz 28.05.09 08:43
Gravatar von Andeas Herz Hallo,

eventuell könnte man hierfür auch http://www.dbTube.org verwenden.
Dann muß man den Import nicht selber programmieren sondern ähnlich
wie in visio einfach mit drag&drop modelieren.

Gruß

Andreas
david 28.05.09 15:01
Gravatar von david Danke für den Link Andreas. Das sieht wirklich sehr interessant und simpel aus.
Wobei ich bei komplexeren Importer trotzdem den Excelreader benutzen würde.
engywug 08.06.09 12:18
Gravatar von engywug hi ihr lieben:),
ich habe auch das prob was ich hier bereits gelesen habe.
die zeile 31 in der reader.php... kriege da ne fehlermeldung, egal ob ich auf "oleread.inc" oder auf "oleread.php" verweise...

require_once 'Spreadsheet/Excel/Reader/oleread.inc';

kann es sein das ich da was verpeilt habe?:)
thx
david 08.06.09 15:49
Gravatar von david Existiert denn eine Datei Namens oleread.inc oder .php im Ordner Spreadsheet/Excel/Reader/?
engywug 08.06.09 19:24
Gravatar von engywug ja klar die inc existiert... der ganze pfad war falsch..

require_once 'oleread.inc';

liegt ja im selben ordner wie die reder.php... habe zum test mal ne xls hochgeladen, mit folgendem ergeb.

Arbeitsblatt 1: Tabelle1
hat: 37 Zeilen und 17 Spalten.

Spaltenueberschriften:
: : : : : : : : : : : : : : : : :

Arbeitsblatt 2: Tabelle2
hat: 0 Zeilen und 0 Spalten.

Spaltenueberschriften:


Arbeitsblatt 3: Tabelle3
hat: 0 Zeilen und 0 Spalten.

Spaltenueberschriften:

jedenfalls keine fehlermeldung mehr und richtig gezählt hatter auch;)
lans38 29.07.09 15:08
Gravatar von lans38 hallo ich nutze
$xl_reader->setOutputEncoding("utf-8");

aber leider werden umlaute weiterhin als hyroglyphen ausgegeben.

weiss hier jemand bescheid, wie mit Umlauten zu verfahren ist??
Mike 30.07.09 15:39
Gravatar von Mike Hallo

Funktioniert bestens! Ausser etwas, habe versucht im Code etwas zu finden, aber leider ohne Erfolg:

Ein Datum wird um einen Tag verschoben übernommen! Also der 30.7.09 wird zum 31.7.09 und der 31.7.09 zum 1.8.09 usw.

Es muss in den Zeilen 922-1000 in reader.php liegen, aber da wage ich mich nicht ran.

Weiss jemand eine Lösung?

Danke und Gruss
Mike 30.07.09 15:50
Gravatar von Mike Habe doch etwas rumprobiert und bin rascher fündig geworden als gedacht

Zeile 970:
$utcValue = round(($utcDays+1) * SPREADSHEET_EXCEL_READER_MSINADAY);

ändern zu

$utcValue = round(($utcDays) * SPREADSHEET_EXCEL_READER_MSINADAY);

Was das genau soll kann ich leider nicht erklären, es geht jetzt jedenfalls...
lans38 12.08.09 16:52
Gravatar von lans38 der excel_reader hat wohl probleme mit zuvor in excel definerten funktionen. also einfache summenberechnungen mitelwerte und. so. das dumme ist nun, dass das ganze worksheet verschoben lesbar ist oder gar nicht mehr lesbar ist. Weiss da jemand rat? kann man feldgrenzen beim einlesen angeben.??


ps: mein problem mit umlauten hab ich so gelöst:
$k = iconv("ISO-8859-1//IGNORE", "UTF-8", $xl_reader->sheets[0]['cells'][$i][$j]);
Frederik 21.08.09 04:19
Gravatar von Frederik das skript hat einen wirklich exzessiven speicherbedarf bei mir. selbst bei einem limit von 300M läuft es noch nicht. wesentlich besser läuft da diese weiterentwicklung http://code.google.com/p/php-excel-reader/
grumi 14.09.09 20:16
Gravatar von grumi An welcher Stelle im Skript kann man den Eintrag in eine MySQl Tabelle machen und wie sieht der Code dazu aus?

lg grumi

Noch eine Frage zu Excel-Writer - kann man bei der Ausgabe der einzelnen Zelle ein Unicode UTF 8 Format festlegen?
Igo 17.11.09 14:29
Gravatar von Igo Funktioniert bei mir soweit ganz gut,
ist wirklich praktisch, aber wenn in der Zelle A1 so etwas drin steht:

=C4

und in Zelle C4 "Brot" drin steht,
dann wird mir beim Auslesen von A1 weder "Brot" noch "=C4" angezeigt sondern einfach NULL...

gibt es dazu eine Lösung?
Andreas Herz 08.04.10 13:25
Gravatar von Andreas Herz Hallo,

falls man auch mal einen Kunden die Möglichkeit geben
möchte Excel Dateien zu importieren, felxibel ohne Programmieren, dann
sollte man mal einen Blick auf http://www.dbTube.org werfen.

Da "modeliert" man seinen Excel Import graphisch.

Lieben Gruß

Andreas Herz
Stephan Fischer 29.04.10 13:19
Gravatar von Stephan Fischer Umlaute

require_once 'Excel/reader.php';



// ExcelFile($filename, $encoding);

$data = new Spreadsheet_Excel_Reader();



// Set output Encoding.

$data->setUTFEncoder('iconv');
$data->setOutputEncoding('UTF-8');

$data->read('dsl.xls');
Hendrich 24.08.10 14:08
Gravatar von Hendrich Es gibt noch einen Fehler beim Einlesen von Zeiten. Bei mir wird aus 00:48:08 nach Xls-Reader 00:48:07.

Suche:
$secs = floor($numValue * SPREADSHEET_EXCEL_READER_MSINADAY) - $hours * 60 * 60 - $mins * 60;

Ersetze:
$secs = round($numValue * SPREADSHEET_EXCEL_READER_MSINADAY) - $hours * 60 * 60 - $mins * 60;
Thomas 17.11.10 14:31
Gravatar von Thomas Ein schönes kleines Tutorial, Danke dafür!
Manu 03.05.11 12:47
Gravatar von Manu Hi,
aber wie komme ich denn hier an die einzelnen Daten in den Spalten / Zeilen (also Zellen) heran?
david 03.05.11 14:13
Gravatar von david @Manu: Kurz zusammengefasst so:
<?
require_once("excel/reader.php"); 
$xls=new Spreadsheet_Excel_Reader(); 
$xls->setOutputEncoding("CP12522"); 
$xls->read("daten.xls"); 
$sheet=$xls->sheets[0]; 
$daten=$sheet["cells"];
?>
oder halt das Beispiel oben etwas genauer studieren.
Nanil 09.09.11 14:14
Gravatar von Nanil Servus
Also ... erst mal gracias für das Script / Tutorial
Aber auch ich bin an einem Problem angeeckt.

Und zwar wollte ich einige Prozentzahlen aus der xls-Datei auslesen. Nur bekomme ich nicht den gewünschten Wert zurück sondern immer 0%
Habe dann in der Datei nachgesehen und bemerkt, dass dort jene Spalte als Format "Prozent" angegeben ist.
Das erklärt zwar, warum mir die Ausgabe gleich das %-Zeichen mitliefert - aber mit dem Zahlenwert könnte ich mehr anfangen ;-)

Is da ne Lösung in Sichtweite? ^^
Volker 13.02.12 13:41
Gravatar von Volker Hallo,
ich muss Daten aus einer Excel 2010 Tabelle lesen.
Ich erhalte folgende Meldung: "...dateiname.xls is not readable".
Hat jemand eine Idee? Es würde mir sehr viel helfen.

Danke, Volker
Volker 13.02.12 13:58
Gravatar von Volker Hallo,
ich muss Daten aus einer Excel 2010 Tabelle lesen.
Ich erhalte folgende Meldung: "...dateiname.xls is not readable".
Hat jemand eine Idee? Es würde mir sehr viel helfen.

Danke, Volker
Chris 08.03.12 18:00
Gravatar von Chris dreckstool ! von absoluten deppen programmiert. funktioniert hinten und vorne nicht. und braucht gigabyteweise ram.
diego 08.10.12 17:53
Gravatar von diego @chris: dann programmier was besseres und versuche im Netz ein wenig sachlicher aufzutreten. Finde so Kommentare schäbig. Immerhin ist da \"Tool\" umsonst (auch wenns eher eine Bibliothek ist und kein Tool)

Kommentieren

Name:
Mail:
Homepage:
4+4=? (Spamschutz)