einfache DB-Abfrage via php in csv exportieren
Martini
- php
Hallo,
da mein Provider keine ODBC Verbindung zuläßt muß ich eine einfache Datenbankabfrage (es wird nur ein Feld abgefragt - dafür aber mehrere Tausend Datensätze...) als csv Datei auf meinem lokalen Computer exportieren. - Diese Datei wird dann von einem anderen Programm benötigt und dieses Programm erwartet die Daten als csv Datei im Format "Inhalt";
Habe folgendes probiert, aber da war ich wohl zu blauäugig - bekomme keine Fehlermeldung, aber auch kein Ergebniss...
Daher die Fragen:
Wie muß ich den Content-Type richtig angeben, dass wenn die Abfrage gestartet wird, nach dem speichern gefragt wird?
Wie schreibe ich den Zeilenumbruch richtig \n o. \t oder ganz anders?
Header("Content-Type: application/csv");
$query_text="select feld from table where bedingung";
/--nb.: $myrow["feld"] kann keine Sonderzeichen, Hochkommas oder sonstiges enthalten, sonst wäre es nicht in die DB gespeichert worden...
$result = mysql_query($query_text);
while ($myrow = mysql_fetch_array($result))
{
$name='"';
$name.=$myrow["feld"];
$name.='"';
$name.=';'; //-- habe auch schon $name.=';'; versucht
echo $name.'\n';
}
Wäre klasse wenn ihr mir hier kurz weiterhelfen könntet.
Grüße,
Martin
Hi,
dieses Programm erwartet die Daten als csv Datei im Format "Inhalt";
mit Semikolon am Ende des Datensatzes? Das ist untypisch. Als Trennzeichen zwischen den Feldern eines Datensatzes, okay, aber so?
Wie muß ich den Content-Type richtig angeben, dass wenn die Abfrage gestartet wird, nach dem speichern gefragt wird?
Der übliche MIME-Type für CSV ist, soweit ich auf die Schnelle sehe, "text/csv". Ob deine Browser eine Ressource dieses Typs einfach als Text anzeigen, oder sofort zum Speichern anbieten, ist von der Browserkonfiguration abhängig. Wenn du dem Browser gar keine Information geben willst, so dass er wirklich keine andere Chance hat als die Ressource einfach zu speichern, solltest du den generischen Typ "application/octet-stream" verwenden.
Wie schreibe ich den Zeilenumbruch richtig \n o. \t oder ganz anders?
Normalerweise \n, in manchen Fällen auch \r\n. Ein Tabulator \t ist etwas ganz anderes.
/--nb.: $myrow["feld"] kann keine Sonderzeichen, Hochkommas oder sonstiges enthalten, sonst wäre es nicht in die DB gespeichert worden...
Wenn du da so sicher bist ...
while ($myrow = mysql_fetch_array($result))
{
$name='"';
$name.=$myrow["feld"];
$name.='"';
$name.=';'; //-- habe auch schon $name.=';'; versucht
echo $name.'\n';
}
Sieht arg kompliziert aus. Ich würd's übersichtlicher und kompakter setzen:
echo '"' . $myrow['feld'] . '";' . "\n";
Wobei ich immer noch glaube, dass das Semikolon nicht nötig ist ...
Wäre klasse wenn ihr mir hier kurz weiterhelfen könntet.
Ob das Ausgabeformat deinen Vorstellungen entspricht, kannst du ja leicht überprüfen, indem du den MIME-Type zum Testen auf text/plain änderst. Dann sollte die Ausgabe direkt im Browser angezeigt werden.
Ciao,
Martin
Wie muß ich den Content-Type richtig angeben, dass wenn die Abfrage gestartet wird, nach dem speichern gefragt wird?
Wie schreibe ich den Zeilenumbruch richtig \n o. \t oder ganz anders?Header("Content-Type: application/csv");
Mit
header("Content-type: application/excel");
wird es mir zum Öffnen und zum Speichern angeboten.
... kann keine Sonderzeichen, Hochkommas oder sonstiges enthalten, sonst wäre es nicht in die DB gespeichert worden...
Wenn interessierts bei csv?
... habe auch schon $name.=';'; versucht
...
Wäre klasse wenn ihr mir hier kurz weiterhelfen könntet.
Wobei noch?
Grüße,
Martin
Womit wir schon zu dritt wären, bei drei Beiträgen.
header("Content-type: application/excel");
wird es mir zum Öffnen und zum Speichern angeboten.
Was auch kein Wunder ist.
Wenns denn ein xls-File sein soll, wird wohl application/vnd.ms-excel vernünftiger sein ;) Für CVS-Daten ist text/csv die imho richte Wahl.
Wenns denn ein xls-File sein soll, wird wohl application/vnd.ms-excel vernünftiger sein ;)
Dazu gibts bei der IANA sogar Schriftverkehr mit Microsoft :D
Hi,
und danke an alle.
Und nein, es soll keine Excel File sein - es soll eine einfache csv Datei sein.
Und nein, es soll keine Excel File sein - es soll eine einfache csv Datei sein.
Dann guckst du RFC 4180.
OK,
ich gebe auf....
habe jetzt so ziemlich alle Möglichkeiten durchgespielt ohne vernünftiges Ergebniss.... :-(
Ich bekomme die Daten aber CLRF ; \n ; \r oder was ich auch immer als Linedelimiter nehme wird mir in der CSV Datei als Text ausgegeben.
Brauche wirklich etwas konkretere Hilfe drehe mich ziemlich im Kreis und wäre wirklich dankbar, nicht nur für Tips sondern für konkrete Lösungsvorschläge. Nur weil der b** Provider ODBC Verbindungen nicht zuläßt bin ich jetzt seit 2 Tagen am rumexperimentieren um ein blödes DB-Feld als CSV auszulesen. (Ich weiß ist nicht euer PRoblem, aber der Frust mußte mal raus....)
Die DB ABfrage funktioniert, die Ausgabe nicht... brauche als CSV Datei:
Feld-Name
Daten1
Daten2
etc.
das kann doch nicht so schwer sein, aber ich bekomme es einfach nicht hin....
Hoffe ihr seid so nett und helft mir (auch wenn das Teil hier SElf heißt, aber mit mir selber komme ich nicht mehr weiter)
Grüße,
Martin
Hallo,
OK,
ich gebe auf....
nein, so schnell werfen wir doch nicht den Korn nach der Flinte ... oder wie das heißt.
habe jetzt so ziemlich alle Möglichkeiten durchgespielt ohne vernünftiges Ergebniss.... :-(
Ich bekomme die Daten aber CLRF ; \n ; \r oder was ich auch immer als Linedelimiter nehme wird mir in der CSV Datei als Text ausgegeben.
Du bist dir aber schon darüber im Klaren, worin in PHP der Unterschied zwischen 'einfachen' und "doppelten" Anführungszeichen als Stringbegrenzern besteht? Oder doch nicht ...?
Die DB ABfrage funktioniert, die Ausgabe nicht... brauche als CSV Datei:
Feld-Name
Daten1
Daten2
etc.
Also: Du hast eine Datei, die den Anforderungen entspricht? Dann kann es nicht so schwer sein - du musst doch "nur noch" das gleiche Format mit PHP erzeugen.
Hoffe ihr seid so nett und helft mir (auch wenn das Teil hier SElf heißt, aber mit mir selber komme ich nicht mehr weiter)
Ja klar - dann zeig doch mal, was du bisher herausgefunden hast, und erkläre, warum *du* meinst, dass das eigentlich richtig sein müsste (auch wenn's vielleicht nicht stimmt). So erkennen wir am besten, wo deine Verständnisprobleme liegen.
So long,
Martin
Hallo,
Du bist dir aber schon darüber im Klaren, worin in PHP der Unterschied zwischen 'einfachen' und "doppelten" Anführungszeichen als Stringbegrenzern besteht? Oder doch nicht ...?
Nein, das war mir neu,dachte immer es ist egal ob ich Doppelte oder Einfache nehme solange ich das konsequent durchalte....
Also: Du hast eine Datei, die den Anforderungen entspricht? Dann kann es nicht so schwer sein - du musst doch "nur noch" das gleiche Format mit PHP erzeugen.
Tja sollt man meinen, aber meinereiner steht mit dem Kopf vor der Wand und kommt nicht durch...
Ja klar - dann zeig doch mal, was du bisher herausgefunden hast, und erkläre, warum *du* meinst, dass das eigentlich richtig sein müsste (auch wenn's vielleicht nicht stimmt). So erkennen wir am besten, wo deine Verständnisprobleme liegen.
Ok, here we go:
<?php
require('includes/db_verbindung.php');
header("Content-type: text/csv");
echo '"Feld"\n';
$query_text="SELECT inhalt from tabelle where con='j' order by inhalt ASC";
$result = mysql_query($query_text);
while ($myrow = mysql_fetch_array($result))
{
echo '"'.$myrow["inhalt"].'"\n';
}
?>
Habe beim Header Content-type:text/csv probiert bekomme dann aber die Meldung Datei kann nicht gefunden werden
bei Content-type:text/plain und Content-type: application/excel und Content-type: application/octet-stream gibt er mir das ergebniss wie folgt aus (wird nur bei application/excel zum speichern angeboten - aber in der Datei steht der Inhalt genauso wie bei der Ausgabe am Bildschirm also mit \n etc.):
"Feld"\n"inhalt1"\n"inhalt2"\n"inhalt3" etc.
(bzw. statt \n halt was ich probiere, also auch:
"inhalt1"\r"inhalt2"\r"inhalt3"
"inhalt1"\n\r"inhalt2"\n\r"inhalt3"
"inhalt1"CRLF"inhalt2"CRLF"inhalt3"
Klar könnte ich einfach
echo $name.'<br>'; schreiben und mir das ganze am Bildschirm ausgeben lassen und dann einfach in den Texteditor kopieren und dort als CSV speichern, aber diesen Zwischenschritt möchte ich gerne vermeiden wenn es geht.
Was habe ich übersehen? Wie muß ich die Linedelimiter einfügen, damit die nicht als Textgelesen werden, sondern als Steuerzeichen? Woran liegt es, dass bei text/csv die Datei angeblich nicht gefunden wird, bei den anderen header Angaben aber schon?
Danke für die Unterstützung
Grüße
Martin
Hallo,
Du bist dir aber schon darüber im Klaren, worin in PHP der Unterschied zwischen 'einfachen' und "doppelten" Anführungszeichen als Stringbegrenzern besteht? Oder doch nicht ...?
Nein, das war mir neu,dachte immer es ist egal ob ich Doppelte oder Einfache nehme solange ich das konsequent durchalte....
Nein, das ist nicht egal.
echo '"'.$myrow["inhalt"].'"\n';
Hier schreibst Du den Klartext
\n
in Deine Ausgabe statt eines Zeilenumbruchs.
Du musst unbedingt doppelte Anführungszeichen verwenden, um die Spezialbedeutung "Zeilenumbruch" zu bekommen, genau wie es Dir Martin in der allerersten Antwort auf Deine Frage bereits schrieb:
echo '"' . $myrow['feld'] . '";' . "\n";
Siehe dazu den Handbuchabschnitt zu Zeichenketten:
<zitat>
Hinweis: Unlike the two other syntaxes, variables and escape sequences
for special characters will not be expanded when they occur in single
quoted string s.
</zitat>
lass dazu das überflüssige Semikolon weg und sorge für ein CRLF als Zeilenende, siehe die Box Escaped Characters:
echo '"' . $myrow['feld'] . '"' . "\r\n";
Freundliche Grüße
Vinzenz
Hallo Martin,
hmm, führe ich Selbstgespräche? .oO(?)
Du bist dir aber schon darüber im Klaren, worin in PHP der Unterschied zwischen 'einfachen' und "doppelten" Anführungszeichen als Stringbegrenzern besteht?
Nein, das war mir neu,dachte immer es ist egal ob ich Doppelte oder Einfache nehme solange ich das konsequent durchalte....
nein, eben nicht. In Javascript und HTML schon; in PHP ist das aber ein ganz entscheidender Unterschied!
Also: Du hast eine Datei, die den Anforderungen entspricht? Dann kann es nicht so schwer sein - du musst doch "nur noch" das gleiche Format mit PHP erzeugen.
Tja sollt man meinen, aber meinereiner steht mit dem Kopf vor der Wand und kommt nicht durch...
Mit dem Kopf durch die Wand ist auch ein schlechter Ansatz. Entweder außenrum gehen, oder einen Panzer mieten. ;-)
<?php
require('includes/db_verbindung.php');
header("Content-type: text/csv");echo '"Feld"\n';
HALT! Wie war das mit den unterschiedlichen Sorten von Anführungszeichen?
In einem String, der mit 'einfachen' Anführungszeichen notiert ist, werden keine Escape-Sequenzen für Steuerzeichen interpretiert. Also:
echo ""Feld"\n";
Die zusätzlichen Backslashes sind hier nötig, weil die inneren Anführungszeichen den String nicht begrenzen, sondern Teil davon sein sollen. Daher werden sie mit einem Backslash maskiert.
echo '"'.$myrow["inhalt"].'"\n';
Hier genau dasselbe. Ich hatte nicht umsonst den letzten Teil des Strings nochmal abgetrennt, damit das \n in einem String mit doppelten Anführungszeichen steht.
Habe beim Header Content-type:text/csv probiert bekomme dann aber die Meldung Datei kann nicht gefunden werden
Wann? Wo? Bei welcher Aktion? Da kann ich nicht ganz folgen.
aber in der Datei steht der Inhalt genauso wie bei der Ausgabe am Bildschirm also mit \n etc.):
"Feld"\n"inhalt1"\n"inhalt2"\n"inhalt3" etc.
Kein Wunder. Siehe oben.
"inhalt1"CRLF"inhalt2"CRLF"inhalt3"
Was ist DAS denn? *wunder*
Klar könnte ich einfach
echo $name.'<br>'; schreiben und mir das ganze am Bildschirm ausgeben lassen und dann einfach in den Texteditor kopieren und dort als CSV speichern, aber diesen Zwischenschritt möchte ich gerne vermeiden wenn es geht.
Das wäre ja auch, als wenn ich ein Dokument erst ausdrucken, dann wieder einscannen würde. ;-)
Was habe ich übersehen? Wie muß ich die Linedelimiter einfügen, damit die nicht als Textgelesen werden, sondern als Steuerzeichen? Woran liegt es, dass bei text/csv die Datei angeblich nicht gefunden wird, bei den anderen header Angaben aber schon?
Das mit "Datei nicht gefunden" solltest du bitte nochmal genauer erklären. Nach meinem Verständnis dürfte nur eine der beiden Verhaltensweisen auftreten:
a) Das CSV-Dokument wird als Text im Browser angezeigt
b) Der Browser bietet das Dokument zum Speichern als Datei an
Ich kann nicht erkennen, wo hier der beschriebene Fehler auftreten könnte.
So long,
Martin
Hallo Martin, hallo Vinzenz
tausend Dank für die Hilfe jetzt klappt es (und interessanter weise bekomme ich die Fehlermeldung beim runterladen nicht mehr... war anscheinend gestern abend der Wurm drin....)
Und ich werde mir das mit den Anführungszeichen noch mal in Ruhe ganz genau durchlesen - war mir echt nicht klar....
Danke Danke Danke
Martin
Hallo,
Ich bekomme die Daten aber CLRF ; \n ; \r oder was ich auch immer als Linedelimiter nehme wird mir in der CSV Datei als Text ausgegeben.
warum das so ist, hat Martin Dir ja gesagt und funktionierenden Code gepostet - gleich in der ersten Antwort auf Deine Frage.
Dass Du kein Semikolon am Ende der Zeile haben sollst, hat suit Dir gesagt: Es steht in verlinkter RFC (die zu großen Teilen brauchbar ist - und in mancher Einzelheit an der Realität im deutschsprachigen Raum vorbei geht).
Dass als Zeilentrenner CRLF, zu nehmen ist, hat suit Dir gesagt.
Nur weil der b** Provider ODBC Verbindungen nicht zuläßt
Wenn Provider so etwas nicht zulassen, so ist das durchaus in Ordnung. Es ist eine gute Idee, keinen direkten Zugriff auf Datenbankserver aus dem Internet zuzulassen.
Freundliche Grüße
Vinzenz
header("Content-type: application/excel");
wird es mir zum Öffnen und zum Speichern angeboten.Was auch kein Wunder ist.
Wenns denn ein xls-File sein soll,
Es ist csv und natürlich kann ich beim Öffnen auch ein anderes Programm auswählen.