PHP-код для перетворення запиту MySQL в CSV [закрито]


128

Який найефективніший спосіб перетворити запит MySQL в CSV в PHP?

Найкраще було б уникати тимчасових файлів, оскільки це зменшує портативність (потрібні шляхи dir та встановлення дозволів файлової системи).

CSV також повинен містити один верхній рядок імен полів.


73
Чому це питання було закрито не конструктивним? Цей тонкий і ідеально зрозумілий.

14
@Alec Оскільки деякі модератори тут є супермодераторами, ви знаєте ... "З супердержавами виходить велика відповідальність!" - Дядько Бен
обмеженість

18
@finitenessofinfinity потужність псує, абсолютна потужність пошкоджує абсолютно. Stackoverflow - відмінний приклад цього.

16
Я голосую за повторне відкриття цього питання!
TN888

9
Через півроку я використовую відповіді на цьому на своєму веб-сайті. Чи можна це повторно відкрити?
Джон

Відповіді:


138
SELECT * INTO OUTFILE "c:/mydata.csv"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM my_table;

( документація для цього знаходиться тут: http://dev.mysql.com/doc/refman/5.0/uk/select.html )

або:

$select = "SELECT * FROM table_name";

$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=your_desired_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";

5
технічно це розділено на вкладки;)
Джон Даутхат

5
Зверніть увагу на використання передніх косої риси з SELECT INTO OUTFILEрівними для Windows.
Йохан

1
Привіт, це добре працює у форматі xls, але якщо я спробую зберегти як файл CSV, він показує всі результати в 1 стовпці. Я хочу зберегти це як файл CSV.
vinod reddy

Серед двох вище, хто з них кращий, безпечніший і чому?
Челла,

1
Я схиляюсь до того, що другий варіант є більш безпечним, оскільки `SELECT INTO OUTFILE вимагає, щоб користувач mysql мав доступ до файлової системи для зміни файлів, що є великим ризиком.
Jeepstone

91

Ознайомтеся з цим питанням / відповіддю . Це більш стисло, ніж у @ Geoff's, а також використовує вбудовану функцію fputcsv.

$result = $db_con->query('SELECT * FROM `some_table`');
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
$headers = array();
for ($i = 0; $i < $num_fields; $i++) {
    $headers[] = mysql_field_name($result , $i);
}
$fp = fopen('php://output', 'w');
if ($fp && $result) {
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="export.csv"');
    header('Pragma: no-cache');
    header('Expires: 0');
    fputcsv($fp, $headers);
    while ($row = $result->fetch_array(MYSQLI_NUM)) {
        fputcsv($fp, array_values($row));
    }
    die;
}

1
У вас немає заголовків стовпців.
Паоло Бергантіно,

15
У випадку, якщо хтось інший такий дурний, як я, не замінюйте php://outputфактичне ім’я файлу і не намагайтеся закрити його fcloseв кінці: це не справжній файл, а лише псевдонім вихідного потоку. У будь-якому випадку ця відповідь спрацювала для мене ідеально, дякую Jrgns!
J.Steve

@ J.Steve Моє задоволення :)
Jrgns


1
mysql_num_fields () не працює для мене, і заголовки не створюються. Ця функція застаріла чи щось таке?
Даг

20

Подивіться на документацію щодо синтаксису SELECT ... INOT OUTFILE.

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

18

Оновлення рішення @jrgns (з невеликими синтаксичними розбіжностями).

$result = mysql_query('SELECT * FROM `some_table`'); 
if (!$result) die('Couldn\'t fetch records'); 
$num_fields = mysql_num_fields($result); 
$headers = array(); 
for ($i = 0; $i < $num_fields; $i++) 
{     
       $headers[] = mysql_field_name($result , $i); 
} 
$fp = fopen('php://output', 'w'); 
if ($fp && $result) 
{     
       header('Content-Type: text/csv');
       header('Content-Disposition: attachment; filename="export.csv"');
       header('Pragma: no-cache');    
       header('Expires: 0');
       fputcsv($fp, $headers); 
       while ($row = mysql_fetch_row($result)) 
       {
          fputcsv($fp, array_values($row)); 
       }
die; 
} 

Чомусь $ fp мені повертає помилкове значення.
Volatil3

Для сучасного MySQL ви можете використовувати: $ headers [] = mysqli_fetch_field_direct ($ результат, $ i) -> ім'я;
Бен в Каліфорнії

І змінити інші функції mysql_ на функції mysqli_.
Бен в Каліфорнії

6

Якщо ви хочете, щоб завантаження пропонувалося у вигляді завантаження, яке можна відкрити безпосередньо в Excel, це може працювати для вас: (скопійовано зі старого мого неопублікованого проекту)

Ці функції налаштовують заголовки:

function setExcelContentType() {
    if(headers_sent())
        return false;

    header('Content-type: application/vnd.ms-excel');
    return true;
}

function setDownloadAsHeader($filename) {
    if(headers_sent())
        return false;

    header('Content-disposition: attachment; filename=' . $filename);
    return true;
}

Цей посилає CSV в потік, використовуючи результат mysql

function csvFromResult($stream, $result, $showColumnHeaders = true) {
    if($showColumnHeaders) {
        $columnHeaders = array();
        $nfields = mysql_num_fields($result);
        for($i = 0; $i < $nfields; $i++) {
            $field = mysql_fetch_field($result, $i);
            $columnHeaders[] = $field->name;
        }
        fputcsv($stream, $columnHeaders);
    }

    $nrows = 0;
    while($row = mysql_fetch_row($result)) {
        fputcsv($stream, $row);
        $nrows++;
    }

    return $nrows;
}

Ця функція використовує вищевказану функцію для запису CSV у файл, заданого ім'ям $ file

function csvFileFromResult($filename, $result, $showColumnHeaders = true) {
    $fp = fopen($filename, 'w');
    $rc = csvFromResult($fp, $result, $showColumnHeaders);
    fclose($fp);
    return $rc;
}

І ось тут відбувається магія;)

function csvToExcelDownloadFromResult($result, $showColumnHeaders = true, $asFilename = 'data.csv') {
    setExcelContentType();
    setDownloadAsHeader($asFilename);
    return csvFileFromResult('php://output', $result, $showColumnHeaders);
}

Наприклад:

$result = mysql_query("SELECT foo, bar, shazbot FROM baz WHERE boo = 'foo'");
csvToExcelDownloadFromResult($result);

1
Дякую Джону за дуже корисний код. Довелося змінити рядок для функції csvFromResult. замість while ($ row = mysql_fetch_row ($ результат)) {fputcsv ($ stream, $ row); $ рядків ++; }, мені довелося використовувати while ($ row = mysql_fetch_row ($ результат)) {$ data [] = $ row; // fputcsv ($ stream, $ row); // $ рядки ++; } foreach ($ дані як $ d) {fputcsv ($ stream, $ d); }. ще раз дякую за такий чудовий код.
codingbbq

3
// Export to CSV
if($_GET['action'] == 'export') {

  $rsSearchResults = mysql_query($sql, $db) or die(mysql_error());

  $out = '';
  $fields = mysql_list_fields('database','table',$db);
  $columns = mysql_num_fields($fields);

  // Put the name of all fields
  for ($i = 0; $i < $columns; $i++) {
    $l=mysql_field_name($fields, $i);
    $out .= '"'.$l.'",';
  }
  $out .="\n";

  // Add all values in the table
  while ($l = mysql_fetch_array($rsSearchResults)) {
    for ($i = 0; $i < $columns; $i++) {
      $out .='"'.$l["$i"].'",';
    }
    $out .="\n";
  }
  // Output to browser with appropriate mime type, you choose ;)
  header("Content-type: text/x-csv");
  //header("Content-type: text/csv");
  //header("Content-type: application/csv");
  header("Content-Disposition: attachment; filename=search_results.csv");
  echo $out;
  exit;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.