【问题标题】:Export to CSV via PHP通过 PHP 导出为 CSV
【发布时间】:2011-05-14 01:28:31
【问题描述】:

假设我有一个数据库....有没有办法可以通过 PHP 将数据库中的内容导出到 CSV 文件(和文本文件 [如果可能])?

【问题讨论】:

标签: php csv


【解决方案1】:
<?php 
      
          // Database Connection
          include "includes/db/db.php";
           
          
              $query = mysqli_query($connection,"SELECT * FROM team_attendance JOIN team_login ON   
   team_attendance.attendance_user_id=team_login.user_id where   
   attendance_activity_name='Checked-In' order by   
   team_attendance.attendance_id ASC"); // Get data from Database from  
   demo table
           
           
              $delimiter = ",";
              $filename = "attendance" . date('Ymd') . ".csv"; // Create file name
               
              //create a file pointer
              $f = fopen('php://memory', 'w'); 
               
              //set column headers
              $fields = array('ID', 'Employee Name', 'Check In Time', 'Check Out Time', 'Date');
              fputcsv($f, $fields, $delimiter);
               
              //output each row of the data, format line as csv and write to file pointer
              while($row = $query->fetch_assoc()){
                   $date=date('d-m-Y',$row['attendance_date']);
                  $lineData = array($row['attendance_id'], $row['user_name'], $row['attendance_time'],   
   $row['check_out_time'],$date);
                  fputcsv($f, $lineData, $delimiter);
              }
               
              //move back to beginning of file
              fseek($f, 0);
               
              //set headers to download file rather than displayed
              header('Content-Type: text/csv');
              header('Content-Disposition: attachment; filename="' . $filename . '";');
               
              //output all remaining data on a file pointer
              fpassthru($f);
              ?>

【讨论】:

    【解决方案2】:

    我个人使用此函数从任何数组创建 CSV 内容。

    function array2csv(array &$array)
    {
       if (count($array) == 0) {
         return null;
       }
       ob_start();
       $df = fopen("php://output", 'w');
       fputcsv($df, array_keys(reset($array)));
       foreach ($array as $row) {
          fputcsv($df, $row);
       }
       fclose($df);
       return ob_get_clean();
    }
    

    然后您可以让您的用户使用以下方式下载该文件:

    function download_send_headers($filename) {
        // disable caching
        $now = gmdate("D, d M Y H:i:s");
        header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
        header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
        header("Last-Modified: {$now} GMT");
    
        // force download  
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
    
        // disposition / encoding on response body
        header("Content-Disposition: attachment;filename={$filename}");
        header("Content-Transfer-Encoding: binary");
    }
    

    使用示例:

    download_send_headers("data_export_" . date("Y-m-d") . ".csv");
    echo array2csv($array);
    die();
    

    【讨论】:

    • 在本地服务器上它正在工作,但在远程服务器上它显示一个包含内容的新页面并且没有下载窗口(对不起我的英语)
    • 错误可能有多种原因,最简单的查找方法是查看您的 apache error.log 文件。
    • 您需要在echo array2csv(); 之后拨打die(); 电话,将编辑我的答案。确保在页面中输出内容之前生成 csv。
    • @ring0 我想把过去的日期放在标题中会禁用页面缓存,看看第二个例子php.net/manual/en/function.header.php
    • 为您的浏览器提供 mime 类型,因此您将获得下载模式,而不是当前窗口中呈现的 csv。
    【解决方案3】:

    适用于超过 100 行,如果您在标题中指定文件的大小 在你自己的类中简单地调用 get() 方法

    function setHeader($filename, $filesize)
    {
        // disable caching
        $now = gmdate("D, d M Y H:i:s");
        header("Expires: Tue, 01 Jan 2001 00:00:01 GMT");
        header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate");
        header("Last-Modified: {$now} GMT");
    
        // force download  
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header('Content-Type: text/x-csv');
    
        // disposition / encoding on response body
        if (isset($filename) && strlen($filename) > 0)
            header("Content-Disposition: attachment;filename={$filename}");
        if (isset($filesize))
            header("Content-Length: ".$filesize);
        header("Content-Transfer-Encoding: binary");
        header("Connection: close");
    }
    
    function getSql()
    {
        // return you own sql
        $sql = "SELECT id, date, params, value FROM sometable ORDER BY date;";
        return $sql;
    }
    
    function getExportData()
    {
        $values = array();
    
        $sql = $this->getSql();
        if (strlen($sql) > 0)
        {
            $result = dbquery($sql); // opens the database and executes the sql ... make your own ;-) 
            $fromDb = mysql_fetch_assoc($result);
            if ($fromDb !== false)
            {
                while ($fromDb)
                {
                    $values[] = $fromDb;
                    $fromDb = mysql_fetch_assoc($result);
                }
            }
        }
        return $values;
    }
    
    function get()
    {
        $values = $this->getExportData(); // values as array 
        $csv = tmpfile();
    
        $bFirstRowHeader = true;
        foreach ($values as $row) 
        {
            if ($bFirstRowHeader)
            {
                fputcsv($csv, array_keys($row));
                $bFirstRowHeader = false;
            }
    
            fputcsv($csv, array_values($row));
        }
    
        rewind($csv);
    
        $filename = "export_".date("Y-m-d").".csv";
    
        $fstat = fstat($csv);
        $this->setHeader($filename, $fstat['size']);
    
        fpassthru($csv);
        fclose($csv);
    }
    

    【讨论】:

      【解决方案4】:

      我建议parsecsv-for-php 解决嵌套换行符和引号引起的一些问题。

      【讨论】:

        【解决方案5】:

        就像@Dampes8N 说的:

        $result = mysql_query($sql,$conecction);
        $fp = fopen('file.csv', 'w');
        while($row = mysql_fetch_assoc($result)){
            fputcsv($fp, $row);
        }
        fclose($fp);
        

        希望这会有所帮助。

        【讨论】:

          【解决方案6】:

          仅作记录,连接比fputcsv 甚至implode 快得多(我是认真的);而且文件更小:

          // The data from Eternal Oblivion is an object, always
          $values = (array) fetchDataFromEternalOblivion($userId, $limit = 1000);
          
          // ----- fputcsv (slow)
          // The code of @Alain Tiemblo is the best implementation
          ob_start();
          $csv = fopen("php://output", 'w');
          fputcsv($csv, array_keys(reset($values)));
          foreach ($values as $row) {
              fputcsv($csv, $row);
          }
          fclose($csv);
          return ob_get_clean();
          
          // ----- implode (slow, but file size is smaller)
          $csv = implode(",", array_keys(reset($values))) . PHP_EOL;
          foreach ($values as $row) {
              $csv .= '"' . implode('","', $row) . '"' . PHP_EOL;
          }
          return $csv;
          // ----- concatenation (fast, file size is smaller)
          // We can use one implode for the headers =D
          $csv = implode(",", array_keys(reset($values))) . PHP_EOL;
          $i = 1;
          // This is less flexible, but we have more control over the formatting
          foreach ($values as $row) {
              $csv .= '"' . $row['id'] . '",';
              $csv .= '"' . $row['name'] . '",';
              $csv .= '"' . date('d-m-Y', strtotime($row['date'])) . '",';
              $csv .= '"' . ($row['pet_name'] ?: '-' ) . '",';
              $csv .= PHP_EOL;
          }
          return $csv;
          

          这是从十行到上千行的几个报表优化的结论。这三个示例在 1000 行下运行良好,但在数据更大时失败。

          【讨论】:

            【解决方案7】:

            附在此处的预制代码。您可以通过复制和粘贴代码来使用它:

            https://gist.github.com/umairidrees/8952054#file-php-save-db-table-as-csv

            【讨论】:

              【解决方案8】:

              您可以使用此命令导出日期。

              <?php
              
              $list = array (
                  array('aaa', 'bbb', 'ccc', 'dddd'),
                  array('123', '456', '789'),
                  array('"aaa"', '"bbb"')
              );
              
              $fp = fopen('file.csv', 'w');
              
              foreach ($list as $fields) {
                  fputcsv($fp, $fields);
              }
              
              fclose($fp);
              ?>
              

              首先你必须将数据从mysql服务器加载到一个数组中

              【讨论】:

              • 或者,您可以在标准的 fetch assoc 循环中执行 fputcsv() 并将其直接从返回的结果中删除。
              • @DampeS8N,+1 表示在句子中使用“plop it down straight out”。
              • 这是从 fputcsv 的 PHP 手册中复制的,没有注明出处
              猜你喜欢
              • 2012-05-08
              • 2014-03-22
              • 1970-01-01
              • 2011-12-04
              • 2013-08-30
              • 2017-06-24
              • 1970-01-01
              相关资源
              最近更新 更多