[Erledigt] Problem mit SQL Export in XLS

Begonnen von GerhardSt, 24 März 2008, 15:43:48

⏪ vorheriges - nächstes ⏩

0 Mitglieder und 1 Gast betrachten dieses Thema.

GerhardSt

Hallo,

ich will teile von meiner SQL-Tabelle als Excel-Tabelle zum downloaden anbieten.
Jetzt habe ich das ganze mal mit folgendem Code aus dem Web, an der user-Tabelle getestet.
Nur habe ich damit das Problem, das in der Excel-Tabelle die Sonderzeichen nicht richtig angezeigt werden und irgendwas mit dem header nicht stimmt. Bekomme immer eine Fehlermeldung in der Excel-Datei.
Hat jemand eine Idee, woran das liegt?

Danke, Gerhard

Hier der Code
Zitat<?php

defined('mxMainFileLoaded') or die('access denied');


$select = "SELECT * FROM mxPREFIX_users";

$export = mysql_query ( $select ) or die ( "Sql error : " . mysql_error( ) );

$fields = mysql_num_fields ( $export );

for ( $i = 0; $i < $fields; $i++ )
{
    $header .= mysql_field_name( $export , $i ) . "\t";
}

while( $row = mysql_fetch_row( $export ) )
{
    $line = '';
    foreach( $row as $value )
    {                                           
        if ( ( !isset( $value ) ) || ( $value == "" ) )
        {
            $value = "\t";
        }
        else
        {
            $value = str_replace( '"' , '""' , $value );
            $value = '"' . $value . '"' . "\t";
        }
        $line .= $value;
    }
    $data .= trim( $line ) . "\n";
}
$data = str_replace( "\r" , "" , $data );

if ( $data == "" )
{
    $data = "\n(0) Records Found!\n";                       
}

header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=Mitgliederliste.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";

?>

Musicman75

Schau dir mal das hier an:
http://pear.php.net/package/Spreadsheet_Excel_Writer

xls Dateien werden nicht im Klartext geschrieben, da ist das ganze nicht so einfach, deswegen würde ich dieses Package empfehlen.
Unaufgeforderte Support PMs & Emails werden ignoriert

Immer erst die Boardsuche verwenden und gegebenenfalls einen neuen Threat eröffnen, wenn das Problem noch nicht behandelt wurde!

GerhardSt

Danke Musicman75,

für den Link, sieht sehr vielversprechend aus. Werde ich gleich mal testen!

GerhardSt

@ Musicman75

Dieses Package kann ja ziemlich viel, leider werden in meinem Versuch die Sonderzeichen wieder nicht richtig dargestellt.
Muss man da irgendwo was ändern, oder wo liegt da mein Fehler?

Danke, Gerhard

Musicman75

Keine Ahnung, ich hab das nur bei der Googlesuche gefunden. Getestet hab ich das nicht.

Aber in der Doku dazu steht was drin:
http://pear.php.net/manual/en/package.fileformats.spreadsheet-excel-writer.spreadsheet-excel-writer-worksheet.setinputencoding.php

Also erstmal die Doku wälzen.
Unaufgeforderte Support PMs & Emails werden ignoriert

Immer erst die Boardsuche verwenden und gegebenenfalls einen neuen Threat eröffnen, wenn das Problem noch nicht behandelt wurde!

GerhardSt

#5
Danke, ich dachte du hast es auch im Einsatz!

Dann werde ich mich mal durch die Doku kämpfen ;)

Edit:
Hab´s gefunden!

Für den Fall das es wer andere auch braucht, hier mal ein paar Zeilen:
<?php
require_once 'Spreadsheet/Excel/Writer.php';
$workbook = new Spreadsheet_Excel_Writer();
$workbook->send('test.xls');
$workbook->setVersion(8);
$worksheet =& $workbook->addWorksheet('International worksheet');

$zeile 0;
$spalte 0;
$text "+äü";

$worksheet->setInputEncoding('utf-8');
$worksheet->write($zeile$spalte$text);
$workbook->close();
?>

GerhardSt

#6
Hallo,

könntet ihr mir bitte nochmal helfen!
Ich habe jetzt versucht das ganze umzuschreiben, nur ich scheitere wieder mal an den richtigen Abfragen der Datenbank.
Die Feldnamen werden noch richtig erstellt, nur beim Inhalt selbst ist irgendwo der Wurm drinn.

Danke, Gerhard

<?php

require_once 'Spreadsheet/Excel/Writer.php';
$workbook = new Spreadsheet_Excel_Writer();
$workbook->send('test.xls');
$workbook->setVersion(8);
$format_bold =& $workbook->addFormat();
$format_bold->setBold();
$worksheet =& $workbook->addWorksheet('International worksheet');

$worksheet->setInputEncoding('utf-8');

//Feldnamen schreiben
$zeile 0;
$spalte 0;
$header "";
$data "";

$select "SELECT * FROM mx[color=red]PREFIX[/color]_users";
$export mysql_query $select ) or die ( "Sql error : " mysql_error( ) );

$fields mysql_num_fields $export );

for ( 
$i 0$i $fields$i++ )
{
$header mysql_field_name$export $i ) . "\t";
$worksheet->write($zeile$spalte$header$format_bold);
$spalte $spalte 1//nächste Spalte
}

//Inhalt schreiben
$zeile 1;
$spalte 0;

while( 
$row mysql_fetch_row$export ) )
{
    foreach( 
$row as $value )
    {                                            
$worksheet->write($zeile$spalte$value);
$spalte $spalte 1//nächste Spalte
        
}
                
$zeile $zeile 1//neue Zeile
                
$spalte 0//wieder in der ersten Spalte anfangen
    
}

if ( 
$data == "" )
{
echo 
"Keine Einträge vorhanden";
}

$workbook->close();

?>


EDIT: Hab mal das Zitat zu nem Code-Bereich geändert. ;)

JoergK

#7
Hoi ;)

Hab Deinen Code mal durchgespielt, allerdings ohne das PEAR-Paket Spreadsheet_Excel_Writer und es wurden alle Daten ausgelesen und mittels Testausgabe auch angezeigt.

Was machst Du denn da eigentlich mit der Variablen "$data"? Sie wird nirgendwo in Deinem Code wirklich genutzt.
Evtl. fehl auch noch der Tabulator als Trenner für die Daten, damit das Spreadsheet-Teil die Daten richtig umsetzt?

Dein Code
<?php

foreach ($row as $value) {
    
$worksheet->write($zeile$spalte$value);
    
$spalte $spalte 1//naechste Spalte
}

?>


Eventuell so?
<?php

foreach ($row as $value) {
    
$data $value "\t";
    
$worksheet->write($zeile$spalte$data);
    
$spalte $spalte 1//naechste Spalte
}

?>



EDIT: Anhang entfernt, weil nicht mehr benötigt. Lösung ist weiter untern. ;)
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hi JoergK, :)

danke für deinen Tip, funktioniert leider auch nicht.
Deine angehängte Zip-Datei kann ich leider nicht testen, die lässt sich nicht öffnen.

Die Variable "$data" stammt noch vom alten Script, das die Sonderzeichen nicht richtig angezeigt, ich hab das einfach ein wenig umgeschrieben ;)

Zur Info zum Script:
Die Daten müssen mit Zeilen und Spaltenangabe extra übergeben werden.
$worksheet->write($zeile, $spalte, $text);

Als Beispiel für die Zelle A2 mit dem Text test
$worksheet->write(0, 1, "test");

Vielleicht hilft das weiter ;)

Danke, für Eure Hilfe, Gerhard

JoergK

Zitat
danke für deinen Tip, funktioniert leider auch nicht.
Schade .. aber war auch nur so'ne Idee ;)

Zitat
Deine angehängte Zip-Datei kann ich leider nicht testen, die lässt sich nicht öffnen.
Probier mal nen anderen Browser ...

Zitat
Zur Info zum Script:
Die Daten müssen mit Zeilen und Spaltenangabe extra übergeben werden.
$worksheet->write($zeile, $spalte, $text);
Das hatte ich schon so erkannt. ;)

Ich glaub, ich schmeiss mir das Speadsheet-Teil nachher mal auf'en Rechner ... dann seh ich mehr. :BD:
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hi JoergK,

habe jetzt deine index.zip entpackt und getestet, lag am 7zip-Programm mit dem gings nicht.
Mit deiner index.php wird mir alles richtig angezeigt, jetzt müsste das ganze nur noch in eine Excel-Tabelle exportiert werden.
Ich habe gesehen, das du da einiges am Code geändert hast, kann das mit meinem Fehler zusammenhängen, oder ist da wo anders der Wurm drinn.

Danke, Gerhard

JoergK

Hi Gerhard ;)

Also am Cod hab ich Syntax-mäßig nix geändert, ausser an einigen Stellen hab ich einfache statt doppelte Anführungszeichen verwendet (siehe http://www.php-faq.de/q/q-stil-anfuehrungszeichen.html). Ansonsten hab ich nur überflüssige Leerzeichen weggelassen und den Code optisch "lesbarer" gestaltet (siehe http://pear.php.net/manual/de/standards.php). ;)

Wo da der Wurm ist, weiß ich noch nicht, aber den finden wir schon ... hab mir grad erstmal das PEAR::Spreadsheet_Excel_Writer Package lokal auf meinem Xampp installiert. :BD:
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

JoergK

Hehe ... also bei funzt es ...

... nachdem ich das aus dem Code entfernt hab:
if ($data == '') {
    echo 'Keine Eintr&auml;ge vorhanden';
}


Da der echo-Befehl vor dem "$workbook->close();" stand, wurde die Meldung natürlich auch in die Ausgabedatei geschrieben, was zu entsprechendem Zeichenchaos in Excel führte. ;)

Einzig mit deutschen Umlauten gab's noch Probleme, was bedeutet, dass in den betroffenen Feldern nur die Einträge bis zum Auftreten des ersten Umlauts drinne standen.

Hier führte dann die Änderung von
$worksheet->setInputEncoding('utf-8');
in
$worksheet->setInputEncoding('ISO-8859-1');
zum Erfolg.

Ich hab dann noch versucht, nach dem Schliessen der Excel-Dateierzeugung die obige Ausgabe von
if ($data == '') {
    echo 'Keine Eintr&auml;ge vorhanden';
}


mit
if ($data == '') {
    include('header.php');
    OpenTable();
    echo 'Keine Eintr&auml;ge vorhanden';
    CloseTable();
    include('footer.php');
}

als Modulausgabe umzusetzen, was zwar insofern erfolgreich war, dass die Ausgabe nicht in die Exceldatei hineingeschrieben wurde, allerdings wird der Code anscheinend gar nicht mehr ausgeführt oder die Ausgaben verschwinden im Nirwana, jedenfalls wurde der Text nicht im pmx angezeigt.

Anbei meine Testdatei. ;)
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hi JoergK, :)

Zitat von: JoergK am 28 März 2008, 23:42:20
Da der echo-Befehl vor dem "$workbook->close();" stand, wurde die Meldung natürlich auch in die Ausgabedatei geschrieben, was zu entsprechendem Zeichenchaos in Excel führte. ;)

Bei mir kammen da immer Fehlermeldungen, das in Zeilen des Excel-Writer Scripts was nicht stimmt.
Jetzt habe ich deinen Code getestet und er funktioniert. :thumbup:

Das die Meldung "Keine Einträge vorhanden" nicht funktioniert, ist eigentlich nicht schlimm, da die bei mir sowieso nicht leer sein sollte.  ;)

Vielen Dank, für deine Hilfe!

GerhardSt

Hallo,

ich bin´s leider nocheinmal, ich habe meine neue Tabelle jetzt mit Daten gefüllt.
Nur sobald ich einen 63-Zeile einfüge, bekomme ich immer eine defekte Exceldatei.
Diese kann zwar repariert werden, nur dann ist die ganze Formatierung weg.

Woran könnte das liegen?

Danke, Gerhard

JoergK

Moin ;)

ZitatNur sobald ich einen 63-Zeile einfüge, bekomme ich immer eine defekte Exceldatei.

Also ich hab das grad mal getestet ... sowohl mit 64 als auch 99 Einträgen in der Tabelle ... das Resultat ist jeweils eine fehlerfreie Exceltabelle. Haste vielleicht irgendwelche Anführungszeichen (Einfache / Hochkomma, doppelte) in den Testdaten? Dann probier mal, die Daten vor der Übergabe zu entwerten:

<?php

    
foreach ($row as $value) {
        
$worksheet->write($zeile$spaltemxAddSlashesForSQL($value));
        
$spalte++; //naechste Spalte
    
}

?>


Alternativ kannst Du auch mal probieren, bestimmte Zeichen innerhalb der Daten vor der Übergabe in HTML-Codes umzuwandeln:
<?php

    
foreach ($row as $value) {
        
$worksheet->write($zeile$spaltehtmlentities($valueENT_QUOTES));
        
$spalte++; //naechste Spalte
    
}

?>


Zitatwas zwar insofern erfolgreich war, dass die Ausgabe nicht in die Exceldatei hineingeschrieben wurde,
Das muss ich korrigieren ... hab mir die erzeugte Excel-Datei mal in nem Hexeditor angesehen ... die komplette pmx-Ausgabe wird mit in die Datei (quasi hinter die Tabelle) hinein geschrieben. :puzzled: :mad2:
Möglicherweise führt auch das zu gewissen Fehlern.

Aus meiner derzeitigen Sicht bleibt wohl nur, das Script direkt (also nicht als Modul) aufzurufen, so dass die pmx-Ausgaben nicht mit in die Datei hinein gelangen. Das bedeutet allerdings, dass z.B. das Öffnen und Schliessen der DB-Verbindung in dem Script selbst stattfinden muss.

Problem mit diesem PEAR-Package ist, dass es bereits gute 1,5 Jahe alt ist und augenscheinlich die Weiterentwicklung eingeschlafen zu sein scheint.
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Danke JoergK,

ich bin mit meinen Test´s schon ein wenig weiter, und habe dabei festgestellt, das es nicht an Sonderzeichen scheiter. Ich vermute eher irgendeine Speichergrenze. Bei meinem Test, habe ich nur vom 63igsten Datensatz die E-Mailadresse gekürzt und schon gings wieder, dieser funktioniert aber auch komplett, wenn ich dafür einen anderen raus nehme.

Ich habe auch schon versucht mit $workbook->setTempDir('/temp'); die Excel-Tabelle vorher temporär zu speichern, nur bringt das bei mir leider auch nichts.

Woran könnte es liegen :gruebel:

Danke, Gerhard

GerhardSt

#17
P.S. Habe gerade mal eine 1:1 kopie mit Xampp bei mir local getestet, genau der selbe Fehler, das schliesst dann woll meine erste Vermutung wieder aus, das es an einen Speicherproblem liegt.

@JoergK
Zu deinen Code für die HTML Umwandlung, da kommt der Fehler bei mir noch früher.
Wenn alles in die Excel-Tabelle geschrieben wird, könnte man das Problem umgehen in dem man den Teil mit "include" einfügt oder bringt das auch nichts?

Sonst bleibt mir woll nichts anderes übrig als die ganze Tabelle zu löschen und alles nochmal von Hand einzugeben.

JoergK

Hi Gerhard ;)

Mal ne Frage: Muss es eigentlich unbedingt ne "reinrassige" Exceldatei werden?

Weil
a) man könnte auch einfach ne CSV-Datei generieren, die Excel ja genauso importieren / anzeigen kann, oder
b) man könnte die Fähigkeit von Excel (und auch OpenOffice:Calc) nutzen, HTML-Code lesen zu können.

Letzters hab ich grad erfolgreich getestet. :BD:

Wenn Du meine Testdatei noch hast, dann änder mal am Ende den Code im else-Zweig so ab:
<?php

} else {
    
$spalten count($titelzeile);
    
header("Content-type: application/vnd-ms-excel");
    
header("Content-Disposition: attachment; filename=export.xls");
    echo 
'<table border="1"><tr><th>Zeile</th>';
    for (
$i 0$i $spalten$i++) {
        echo 
'<th>' $titelzeile[$i] . '</th>';
    }
    echo 
'</tr>';
    for (
$i 1$i $zeile$i++) {
        echo 
'<tr><td>' $i '</td>';
        for (
$y 0$y $spalten$y++) {
            echo 
'<td>' $data[$i][$y] . '</td>';
        }
        echo 
'</tr>';
    }
    echo 
'</table>';
}

?>
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hi JoergK,

nochmal danke für deine Hilfe. :thumbup:

Zu deiner Testdatei, ich habs mit den Änderungen getestet, sieht super aus, nur geht das ganze bei mir nur bis Datensatz 63.

Ich habe auch nichts dagegen, wenn das ganze eine CSV-Datei wird, nur kann man da auch Formatierungen eingeben?

Aber ich glaube, ich habe jetzt entlich herausgefunden was da bei mir nicht stimmt.
Es liegt an den Zeichen / und - in der Datenbank, ich habe die testweise mal rausgenommen und es funktionierte.
Das Problem ist nur das - Zeichen, das kann ich schlecht löschen oder durch ein anderes ersetzen, da es in den E-Mailadressen vorkommt. Das / dagegen verwende ich nur als Trennung von Vorwahl und Telefonnummer ;)
Gibt´s dafür eine Lösung?

Da ja sogar deine Bildschirmausgabe mit diesen Zeichen, mitten drinnen abgebrochen wird. Schätze ich mal, es ist egal in welches Format ich das ganze auch umwandle, es wird leider nicht funktionieren. ;)

JoergK

Hi Gerhard ;)

Also ich hab hier beim Testen weder mit dem "/" noch dem "-" ein Problem.

Zitat
Da ja sogar deine Bildschirmausgabe mit diesen Zeichen, mitten drinnen abgebrochen wird. Schätze ich mal, es ist egal in welches Format ich das ganze auch umwandle, es wird leider nicht funktionieren. ;)

Hmmm .... da muß bei Dir noch was anderews rumhupen.
Haste mal nen Dump Deiner Testtabelle (CREATE und Daten) für mich?
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

#21
Hallo JoergK,

du hast wie immer recht, irgendetwas stimmt da bei mir mit den Daten in der Tabelle nicht.
Da ich schon mit der Originaltabelle arbeite, habe ich jetzt extra noch eine Testtabelle erstellt, mit so ähnlichen Daten und habe dabei auch darauf geachtet das alle Sonderzeichen die im Original vorkommen auch in der Testtabelle vorkommen.
Was soll ich sagen, die Testtabelle funktioniert :thumbup:
Nur wie bekomme ich jetzt raus, worans da jetzt an der Originaltabelle scheitert? :gruebel:
Hier anhängen kann ich sie leider nicht, da sie sämtliche Adressen, Telefonnummern usw. unsere Mitglieder beinhaltet.
Das kommische daran ist, das wenn ich die Originaltabelle in zwei Teile trenne, beide komplett angezeigt werden, irgendetwas muß da zuviel werden, nur was kann das sein?

Danke für deine Hilfe, Gerhard

P.S. Habe den Fehler gefunden, kaum zu glauben was die ENTER-Taste in der Datenbank für Fehler erzeugen kann. Die export.xls von deiner Datei ist jetzt mal Vollständig. :mad2:

Nur mit dem Excel-Writer Script funktionierts trotzdem nicht. Mach aber nichts, den dein Code erzeugt ja auch eine schöne XLS-Datei :thumbup:

Danke! :genie:

JoergK

Hi Gerhard ;)

Supi, dass es nu funzt. :thumbup:

Zitat
Nur mit dem Excel-Writer Script funktionierts trotzdem nicht.
Wenn das irgendwo abbricht, ist da wohl immer noch nen "falsches" Zeichen in der DB drin.
Aber unaghängig davon fällt mir eh noch nen Grund ein, das PEAR-Package nicht zu verwenden: Solange Du es nur auf Deinem Server / Hosting einsetzt (insdtalliern kannst), ist alles ok. Was jedoch, wenn Du Dein Script mal veröffentlichst? Bei den wenigsten Hostern dürfte das PEAR-Package installiert sein und ist für die meisten Hosting-Kunden wohl auch nicht nachträglich installierbar. Daher dürfte die "einfache" Variante mit dem HTML-Output eh die "bessere" Lösung sein.

Zitat
Mach aber nichts, den dein Code erzeugt ja auch eine schöne XLS-Datei :thumbup:

Gern geschehen. :BD:
Aber die Idee stammt nicht von mir, sondern die hab ich über Google gefunden: http://www.devblog.de/index.php/archives/2005/02/05/25/
Will mich ja nicht mit fremden Federn schmücken. ;)
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hallo JorgK :)

ZitatWenn das irgendwo abbricht, ist da wohl immer noch nen "falsches" Zeichen in der DB drin.
Aber unaghängig davon fällt mir eh noch nen Grund ein, das PEAR-Package nicht zu verwenden: Solange Du es nur auf Deinem Server / Hosting einsetzt (insdtalliern kannst), ist alles ok. Was jedoch, wenn Du Dein Script mal veröffentlichst? Bei den wenigsten Hostern dürfte das PEAR-Package installiert sein und ist für die meisten Hosting-Kunden wohl auch nicht nachträglich installierbar. Daher dürfte die "einfache" Variante mit dem HTML-Output eh die "bessere" Lösung sein.

Danke für den Hinweis, aber das Teil sollte nur für meine Page sein und nichts öffentliches werden. ;)
Kannst du mir vielleicht noch einen Tip geben, wie man solche Fehler in der Datenbank leichter findet, ich will ja nicht das ich später damit nochmal Probleme bekomme.

JoergK

Zitat
Kannst du mir vielleicht noch einen Tip geben, wie man solche Fehler in der Datenbank leichter findet, ich will ja nicht das ich später damit nochmal Probleme bekomme.

Am saubersten bzw. effektivsten wohl mittels RegEx ... aber darin bin ich absoluter Laie bis Unkundiger. ;)
Gruß,
Jörg


Nobody is perfect ... so don't call me Nobody

GerhardSt

Hallo, :)

ich habe jetzt endlich den Fehler gefunden!
Es ist kein Datenbankfehler, sondern eine von vielen Begrenzungen des Excel-Writers.
Einige davon findet man in der Workbook.php ;)
Leider sind die einzelnen Funktionen etwas ungenau Beschrieben, aber ich habe es bereits geschaft eine Zeile mehr zu erzeugen, bevor das Script abbricht.
Schade das es da keine Fehlermeldung gibt, wie "Abruch wegen ...".

GerhardSt

Hallo, :BD:

für alle die soetwas mal brauchen, das Problem mit dem Excel-Writer ist gelöst. :cul:
Es lag wirklich an der Workbook.php, die hat ein paar nicht so nützliche Grenzen drinnen.

Näheres dazu findet ihr hier

Und die richtige Workbook.php könnt ihr hier downloaden

Damit funktioniert´s und darum kann dieser Thread hier geschlossen werden.

Nochmal danke an JoergK, für den super Link und die zahlreichen Tips  :thumbup:

Gruß Gerhard