# Daten von MySQL-Datenbank in die Excel-Tabelle importieren



## sharmuur (15. März 2010)

Hallo,

hat jemand vielleicht Erfahrung daten von mysql DB in die Exsel-Tabelle zu importiern. Seit Tagen beschäfige ich mich daran. Habe ich eine menge Siten gegoogelt und verschiedene Methoden gefunden, aber trotzdem es klappt mir nicht. Ich schreibe unten einfach, welche Möglichkeiten ich in meinem Skript ausprobiert habe.

1te Version: bei dem klaptt es einigermaßen, es wird eine exsel tabelle eröffnet, aber die daten sind alle innerhalb einer zeile, wobei es nicht um richitge excel datei handelt

```
$erg=mysql_query($abfrage)
$fields = mysql_num_fields($erg);
for ($i = 0; $i < $fields; $i++) { 
    $header .= mysql_field_name($erg, $i) . "    "; 
 } 
 while($row = mysql_fetch_row($erg)) { 
     $line = ''; 
     foreach($row as $value) {                                              
         if ((!isset($value)) OR ($value == "")) { 
             $value = "    "; 
         } else { 
             $value = str_replace('"', '""', $value); 
             $value = '"' . $value . '"' . "    "; 
         } 
         $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=extraction.xls"); 
 header("Pragma: no-cache"); 
 header("Expires: 0");
```

2te Version:  ich habe das packet 1.7.2.zip von der website php excel auf den server runterladen und entzippt, sodass die ganze classen und php skripte incleded werden können. Bei der Version habe ich keine änderung und keine fehlermeldung. Nicht mal eine leere excel tabelle geöffnet. Habe beim durchsuchen der website irgendwie verstanden, dass das php skript in utf 8 format sein soll, deshalb habe es entsprechend konvertiert. Zur info: der server auf dem mein skript liegt: apache2, ob das Problem daran liegen könnte.


```
error_reporting(E_ALL);	
ini_set('include_path', ini_get('include_path').';../Classes/');
include 'PHPExcel.php';
include 'PHPExcel/Writer/Excel2007.php';
include 'PHPExcel/Writer/Excel5.php';
include 'PHPExcel/IOFactory.php';
$erg=mysql_query($abfrage)
$row = 1;
$objPHPExcel = new PHPExcel();
while ($row = mysql_fetch_array($erg, MYSQL_NUM)) {
   $column = 'A';
   foreach($row as $columnData) {
      $cellRef = $column.$row;
      $objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellRef, $columnData);
      $column++;
   }
   $row++;
}
// Save Excel 2007 file
echo date('H:i:s') . " Write to Excel2007 format\n";
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save(str_replace('.php', '.xlsx', __FILE__));
// Echo done
echo date('H:i:s') . " Done writing file.\r\n";
```

danke voraus
sharmuur


----------



## Frezl (15. März 2010)

Informier dich mal über das CSV-Format. CommaSeparatedValues enthält Tabellendaten im Rohtext, die durch ein Trennzeichen (normalerweise ein ",") strukturiert werden. In deinem PHP-Skript kannst du den Inhalt für die CSV-Datei mittels Schleifen problemlos erstellen. Die speicherst du dann einfach als "tabelle.csv" und öffnest sie in Excel. Excel liest CSV normalerweise ohne Probleme und kann auch CSV schreiben. Allerdings musst du dann drauf achten, dass du das gleiche Trennzeichen wie Excel benutzt!

Weblinks:
http://de.wikipedia.org/wiki/CSV_(Dateiformat)
http://de3.php.net/manual-lookup.php?pattern=csv&lang=de

Grüße, Frezl


----------



## sharmuur (15. März 2010)

danke frezl,

ich schau nach

gruß
sharmuur


----------



## Dr Dau (15. März 2010)

Hallo!



Frezl hat gesagt.:


> Allerdings musst du dann drauf achten, dass du das gleiche Trennzeichen wie Excel benutzt!


Üblicherweise wird ein Semikolon benutzt.
Man kann es aber auch in der Systemsteuerung in den Ländereinstellungen (Zahlen --> Listentrennzeichen) ändern.

Man kann OpenOffice.org auch als Kommandozeilentool nutzen.
Da sollte es doch eigentlich auch möglich sein die CSV-Datei per Kommandozeile (z.B. mittels system()) zu importieren und als Excel-Datei abzuspeichern?!
Ist jetzt nur so ein Gedankengang..... 
Das Problem aber ist dass OpenOffice.org dazu natürlich auf dem Server installiert sein muss.

Ein weiterer Vorteil von OpenOffice.org ist der, dass man nicht in der Systemsteuerung rumstellen muss, da man direkt beim öffnen der CSV-Datei ein beliebiges Trennzeichen angeben kann.

Gruss Dr Dau


----------



## sharmuur (21. März 2010)

*Daten aus Datenbank als CSV-Datei ausgeben?*

Hallo,

ich habe ähnliche Frage im Forum gestellt gehabt, aber bin ich leider gar nicht weiter gekommen. Ich habe verschiedene Beispiele gefunden und alles mögliche probiert. Mein Problem ist, dass ich nicht weiß, wie ich die Datensätzte, die durch die sql-Anfrage geliefert werden, nach Zeilen und Spalten auseinander spalte und als csv-datei sowohl zum Download als auch zum Direktöffnen bereit stellen. Hat jemand vielleicht mir weiter helfen? Ich kann wirklich nicht weiter. Ich kann auch nicht nachvollziehem die ganze Funktionen, z.B. $application="text/csv";
  header( "Content-Type: $application" ); 
  header( "Content-Disposition: attachment; filename=$filename"); 
  header( "Content-Description: csv File" ); 
  header( "Pragma: no-cache" ); 
was genau macht. 



```
$erg=mysql_query($abfrage) or die(mysql_error());
while($row=mysql_fetch_array($erg))
```

ich würde mich auf jede Antwort freuen, damit ich endlich Mal weiterkommen kann.

Viele Grüße
sharmuur


----------



## saftmeister (22. März 2010)

Hallo,

ich vermute mal, du bist Inder, auch deiner Rechtschreibung und Grammatik nach zu urteilen. Ich habe von deinem Post nur die Hälfte verstanden. Ich versuche dir zu helfen, aber wenn die Sprachbarriere wirklich ein Problem sein sollte, möchte ich die Empfehlen, deine Frage in einem englischen Forum zu posten. Aber nun zu deiner Frage:

Du hast ja ein MySQL-Query erfolgreich abgesetzt und ein Ergebnis bekommen. Dieses Ergebnis lieferst du richtigerweise an eine Funktion, die aus dem Ergebnis einen Datensatz macht (eigentlich ist das Ergebnis ein Zeiger und du iterierst nur über die Ergebnisliste).

Nachdem du mittels mysql_fetch_array() nun einen Daten in einem assoziativen Array gepackt hast (ein indiziertes wäre genausogut), kannst du einfach mittels implode() eine durch Komma (oder welches Zeichen auch immer) getrennte Zeile daraus machen:


```
$erg=mysql_query($abfrage) or die(mysql_error());
while($row=mysql_fetch_array($erg))
{
  $csvLine = implode( ',', $row );
}
```

Damit hast du die Zeile nun schon mal, und du könntest sie in eine Datei schreiben. Dazu müsstest du die Datei aber vorher zum schreiben öffnen, am besten schon bevor der SQL-Query gesendet wird:


```
/* Datei öffnen und prüfen */
$csv= fopen("mysql-export.csv", "w");
if( !$csv )
{
  die("Konnte Datei zum exportieren nicht öffnen");
}

$erg=mysql_query($abfrage) or die(mysql_error());
while($row=mysql_fetch_array($erg))
{
  $csvLine = implode( ',' , $row );

  /* Neue Zeile anhängen */
  fputs( $csv, "$csvLine\n" );
}

/* Datei schliessen und speichern */
fclose( $csv );
```

Nun hast du die Datei also. Damit sie nun zum User kommt, musst du sie mittels header() an den Browser senden. Das kannst du mit dem Code machen, den du schon selbst gepostet hast:


```
/* Datei öffnen und prüfen */
$csv= fopen("mysql-export.csv", "w");
if( !$csv )
{
  die("Konnte Datei zum exportieren nicht öffnen");
}

$erg=mysql_query($abfrage) or die(mysql_error());
 while($row=mysql_fetch_array($erg))
 {
   $csvLine = implode( ',' , $row );

  /* Neue Zeile anhängen */
  fputs( $csv, "$csvLine\n" );
 }

/* Datei schliessen und speichern */
fclose( $csv );

/* Datei an den Client (User-Browser) schicken */

/* Den (Mime-)Typ der Datei festlegen, damit der User einen Vorschlag bekommt, was mit der Datei zu tun ist */
header( "Content-Type: text/csv" );

/* Die Datei als Anhang des Headers senden, um den "Speichern unter"-Dialog zu ermöglichen */
header( "Content-Disposition: attachment; filename=mysql-export.csv");

/* Eine allgemeine Beschreibung der Datei */
header( "Content-Description: csv File" );

/* Datei-Größe senden, damit der Browser weiß, wie groß der herunterzuladende Inhalt ist */
header( "Content-Length: " . filesize( "mysql-export.csv" ) );

/* Nicht cachen - es ist ein Download */
header( "Pragma: no-cache" );
```


----------



## sharmuur (22. März 2010)

Hallo Saftmeister,

vielen vielen Dank für die Hilfe und Unterstützung. Ich habe es ausprobiert und hatte eine Fehlermeldung: "Der Zugriff auf den Server ein Datei zu speichern wurde verweigert"
Es kann sein, dass der Uni-Server es nicht erlaubt. 
Heute habe eine andere Möglichkeit, die einigermaßen funktioniert, gefunden. Aber ich habe keinen zeilen Umbruch nach dem Ende eines Datensatzes. Vielleicht könntest du mir bitte sagen, wo das Problem liegt? Der Code ist unten.


```
$datenstring='';
while($daten=mysql_fetch_array($erg, MYSQL_ASSOC))
{
$datenstring.=implode(",", $daten)."\n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=extraction.xls");
header("Pragma: no-cache");
header("Expires: 0");
echo $datenstring;
```

Gruß 
sharmuur
Ps: übrigens mein Deutsch ist besser als mein English . Wenn ich auf English schreiben würde, würde man vielleicht gar keinen Satz verstehen. 
Bin schon aus Asien, aber bisschen nördlicher von Indien - hinter Himalaya - von einem Land, was einst das größte Reich der Welt hatte.


----------



## saftmeister (22. März 2010)

Vielleicht brauchst du Windows-Zeilen-Umbrüche. Versuch doch mal das "\n" durch "\r\n" zu ersetzen.

Außerdem empfehle ich dir noch einmal, Content-Length zu verwenden. Der eine oder andere Browser könnte das vielleicht übel nehmen ;-)

Du kannst die Inhaltsgröße so übergeben


```
header( 'Content-Length: ' . strlen($datenstring) );
```


----------



## sharmuur (22. März 2010)

Hallo,

danke. Mit "\r\n" klappt super. Die erste Zeile ist nach hinten gerückt. Kann man das ändern? 

Meinst du, dass ich statt  "echo $datenstring;"  " header( 'Content-Length: ' . strlen($datenstring) );" zur Ausgabe benutze? Wenn ja, es liefert mir keine Werte, sondern eine leere Seite.

Gruß
sharmuur


----------



## saftmeister (23. März 2010)

Was meinst du mit "nach hinten gerückt"?

Die Content-Length ist ein Header, der an den Browser gesendet wird, um diesem zu signalisieren, wie groß die folgenden Nutzdaten sein werden. Das heißt, das du auf jeden Fall die Nutzdaten mit echo ausgeben musst. Aber es ist durchaus sinnvoll, _auch_ dem Browser mit zu teilen, wie viel Bytes er dann laden muss (also als zusätzliche Angabe vor das echo schreiben).


----------



## sharmuur (4. April 2010)

Hallo Saftmeister,

ich habe mich lange Zeit mit anderen Problemen beschäftigt, aber bin wieder zurück zu meinem Skript. Mit 'Content-Length' funktioniert. 
'mit hinten gerückt' meinte ich: wenn ich die dateien mit einer text editor öffne, dann ist die erste Zeile immer 4 spalten nach hinten gerückt. Die unteren Zeilen nicht.

danke nochmal für die Tipps

Grüße
sharmuur


----------



## saftmeister (5. April 2010)

Dann hat deine Ausgabe $datenstring Tabs oder Leerzeichen vorne angehängt. Versuche es doch mal so:


```
echo trim($datenstring);
```


----------



## sharmuur (5. April 2010)

Hallo,
danke für die Antwort.
mit 
echo trim($datenstring); 
habe ich nach wie vor das leerzeichen 

Grüße


----------

