簡體   English   中英

單擊按鈕后下載CSV文件

[英]Download CSV file after click button

大家早上好,當用戶單擊“導出CSV”按鈕時,我需要強制下載csv文件,我看到了很多頁面(在這里以及在google上),並嘗試了很多方法,但是一切都對我有用。 我有一個帶有此按鈕的主頁,然后單擊它,將POST請求(帶有Javascript和Ajax)發送到制作CSV文件並從理論上進行文件下載的另一頁。 這是主頁的代碼:

<html>
<head>
<script  type="text/javascript"  src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
</head>
<?php   
    $filter="<button id='exportCSV' >Export CSV</button><br/></div>";
    echo $filter 
?>
<script>

  $(function() {
      $("#exportCSV").click(function(){
          var query="select * from thcu_cabtemphpc order by timetag desc limit 300";
          var table="thcu_cabtemphpc";
          //alert(query+"  "+table);
          //alert(dataString);
          $.ajax({
              type: "POST",
              url: "exportCSV.php",
              data: {cvsExp: query, table:table},
              success: function(result){
                  alert("Export in progress");
                  //$("#export").html(result);

              }
          });
         });
      });
      </script>
</html>

當然,這只是一個測試,我還有另一個主頁,用戶可以在其中選擇查詢和表。 這是ExportCSV.php的代碼

<html>
<body>
<?php

include('connection.php');
function array2csv($bd, $query, $id){
    $sql = mysql_query($query);
    $day = gmdate("d-M-Y");
    $offset   = +2 * 3600; // timezone offset for UTC-13
    $utcTime  = gmdate( 'd.m.Y H:i:s' );
    $milliseconds ="".round(microtime(true) * 1000);
    $val= substr($milliseconds,8,10);
    //echo $val;
    $valor = gmdate( 'd-m-Y_H-i-s-'.$val, time() + $offset );
    $name= $day."_".$id."data_export_".$valor.".csv";


    $fp = fopen($name, 'w');

    while ($res=mysql_fetch_row($sql)) {
        $count = 0;
        foreach ($res as $val) {
            if ($count == 0){
                $data = gmdate("Y-m-d H:i:s", substr(($val/10000000) - 12219292800, 0,10));
                $arr[$count] = $data;
                $count++;
            } else {
                $arr[$count] = $val;
            }

        }
        $delimiter=",";

        fputcsv($fp,$arr,$delimiter);
    }
    //fpassthru($fp);
    fclose($fp);        
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $name . '.csv"');
    header('Content-Length: ' . filesize($name)); 
    echo readfile($name);

}

    if(isset($_POST["cvsExp"])) {
        $query=$_POST["cvsExp"];
        $id=$_POST["table"];
        //download_send_headers("data_export_".gmdate("Y-m-d").".csv");
        array2csv($bd,$query,$id);
        die();
    }
?></body>
</html>

我嘗試這樣的代碼,但不起作用,我嘗試替換application / octet whit text / csv,我嘗試插入echo readfile($ name)或僅插入readfile($ name),但任何方法都可以。 這樣做的結果是在webroot內創建一個文件,效果不好,我想讓瀏覽器下載該文件。 非常感謝。

編輯:我嘗試只執行帶有下載腳本的頁面,並且可以正常工作,問題是當我使用Ajax調用它時!!! 怎么可能? 錯誤在哪里?

我沒有檢查您的內部代碼,但是CSV肯定不能以<html>標記開頭! 您只需要回復CSV內容,刪除除<php>所有標簽。

例如:

<?php

include('connection.php');
function array2csv($bd, $query, $id){
    $sql = mysql_query($query);
    $day = gmdate("d-M-Y");
    $offset   = +2 * 3600; // timezone offset for UTC-13
    $utcTime  = gmdate( 'd.m.Y H:i:s' );
    $milliseconds ="".round(microtime(true) * 1000);
    $val= substr($milliseconds,8,10);
    //echo $val;
    $valor = gmdate( 'd-m-Y_H-i-s-'.$val, time() + $offset );
    $name= $day."_".$id."data_export_".$valor.".csv";


    $fp = fopen($name, 'w');

    while ($res=mysql_fetch_row($sql)) {
        $count = 0;
        foreach ($res as $val) {
            if ($count == 0){
                $data = gmdate("Y-m-d H:i:s", substr(($val/10000000) - 12219292800, 0,10));
                $arr[$count] = $data;
                $count++;
            } else {
                $arr[$count] = $val;
            }

        }
        $delimiter=",";

        fputcsv($fp,$arr,$delimiter);
    }
    //fpassthru($fp);
    fclose($fp);        
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $name . '.csv"');
    header('Content-Length: ' . filesize($name)); 
    echo readfile($name);

}

    if(isset($_POST["cvsExp"])) {
        $query=$_POST["cvsExp"];
        $id=$_POST["table"];
        //download_send_headers("data_export_".gmdate("Y-m-d").".csv");
        array2csv($bd,$query,$id);
        die();
    }
?>

我只是刪除了<html><body>標簽的標題和結尾

HTML標簽

您指定了一種強制下載的方法(並且沒有提供錯誤消息),因此我假設您可以通過瀏覽器正常訪問它。

您首先需要刪除該頁面上的所有HTML標記。 當您echo readfile($name); ,您要下載的結果文件將看起來像這樣:

<html>
<head>
<script  type="text/javascript"  src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
</head>

(YOUR CSV FILE HERE)

</body>
</html>

標頭功能

使用的所有header()函數都應先發送給客戶端, 然后再發送到頁面中的任何其他內容 即使在include connection.php;之前,它也應該位於代碼的最頂層include connection.php; 線。

阿賈克斯

您無法使用Ajax下載文件( 請參閱此處 )。

相反,使用其他參數使其成為對該exportCSV.php文件的GET (如果需要,也可以選擇POST )請求,即:

<a href="exportCSV.php?table=table&query=name_of_the_query">Export CSV</a>

由於是文件下載,因此不會將您重定向到另一個頁面,它只會開始下載文件。

標頭

如果要將php和html結合使用,請始終將邏輯和所有處理放在文件的開頭,因此:

<?php
  header('Content-Type: application/octet-stream');
?>
<html>
</html>

這樣可以防止向瀏覽器發送錯誤的標題。 僅當沒有其他頭發送時, header()函數才有效。

請記住,必須先通過常規HTML標記,文件中的空白行或從PHP發送任何實際輸出,然后調用header()。 (資源)

功能

我需要提及的是,您永遠不要使用POST / GET參數發送SQL查詢! 而是發送一些信息,例如查詢名稱和查詢參數,然后您可以使用它們來正確,安全地構建SQL查詢,即:

function array2scv($queryName, $queryParameters) {
  $queries = [
    'example' = 'SELECT * FROM user WHERE id = ?',
  ];
  $stmt = $mysqli->prepare($queries[$queryName]);
  $stmp->bind_param('i',  $queryParameters['id']);
  $stmp->execute();
  ...
}

然后在該函數中return readfile($name)而不是回顯它。 然后使用exit()代替die() (資源)

這是一個簡單腳本的工作示例:

<?php
// example csv
$url = 'http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv';
function download_file()
{
    // getting content to use in the example
    $content = file_get_contents($url);
    $filename = '/tmp/sample.csv';

    // creating temp file
    $handle = fopen($filename, 'w+');
    fwrite($handle, $content);
    fclose($handle);

    // setting headers
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($filename).'"');
    header('Content-Length: ' . filesize($filename));
    return readfile($filename);
}

if (isset($_GET['export']) && $_GET['export'] === '1') {
    download_file();
    exit();
}

?>
<html>
<body>
<a href="?export=1">Export</a>
    </body>
</html>

我希望這會有所幫助。

看到這是我用於動態下載csv的簡單代碼。

if(isset($_POST['somebutton']))
{
 $filename = "somefilename.csv";
 $fp = fopen('php://output', 'w');

 $query = "select * from thcu_cabtemphpc order by timetag desc limit 300";    
 $result = mysql_query($query);
 for($i=0;$i<=7;$i++)
 {
    $header[] = mysql_field_name($result, $i);
 }

 header('Content-type: application/csv');
 header('Content-Disposition: attachment; filename='.$filename);
 fputcsv($fp, $header);

 $query = "select * from thcu_cabtemphpc order by timetag desc limit 300";    
 $result12= mysql_query($query);

 while($row12 = mysql_fetch_row($result12)) {
  fputcsv($fp, $row12);
 }
exit;
}

這是我用於下載簡單Excel的代碼。 及其正常工作的Fine.put此php到任何地方,您就可以下載csv。

首先,我要感謝所有人的大量回答,今天我找到了一個解決方案,對我來說,它可以正常工作,我在主頁上添加以下內容:

$(function() {
        $('#CSV').click(function(){
            $('#wait-animation').show();
            var where="<?php Print($where) ?>";
            var table="<?php Print($id) ?>";
            //var table="thcu_cabtemphpc";
            alert("Export in progress");
            alert(query);
            document.location.href = 'exportCSV.php?where='+where+'&table='+table;
            $('#wait-animation').hide();
      });
  });

並在導出頁面中:

<?php
include('connection.php');
header("Last-Modified: " . @gmdate("D, d M Y H:i:s",$_GET['timestamp']) . " GMT");
header("Content-type: text/x-csv");
// If the file is NOT requested via AJAX, force-download
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
    header("Content-Disposition: attachment; filename=search_results.csv");
}
$table=$_GET['table'];
$where=$_GET['where'];
$day = gmdate("d-M-Y");
$offset   = +2 * 3600; // timezone offset for UTC-13
$utcTime  = gmdate( 'd.m.Y H:i:s' );
$milliseconds ="".round(microtime(true) * 1000);
$val= substr($milliseconds,8,10);
$valor = gmdate( 'd-m-Y_H-i-s-'.$val, time() + $offset );
$filename= $day."_".$table."data_export_".$valor.".csv";

$fp = fopen('php://output', 'w');

$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='monitoring' AND TABLE_NAME='".$table."'";
$result = mysql_query($query);
while ($row = mysql_fetch_row($result)) {
    $header[] = $row[0];
}   

header('Content-type: application/csv');
header('Content-Disposition: attachment; filename='.$filename);
fputcsv($fp, $header);


$result = mysql_query("select * from ".$id." where ".$where);
while($row = mysql_fetch_row($result)) {
    fputcsv($fp, $row);
}
return $filename;
exit;
?>

非常感謝。 祝你今天愉快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM