简体   繁体   English

单击按钮后下载CSV文件

[英]Download CSV file after click button

Good morning all, I need to force download csv file when the user click the button "Export CSV" , i see a lot of page (here and with google) and try a lot of thing but anything is working for me. 大家早上好,当用户单击“导出CSV”按钮时,我需要强制下载csv文件,我看到了很多页面(在这里以及在google上),并尝试了很多方法,但是一切都对我有用。 I have one main page with this button and clicking it send a POST request (with Javascript and ajax) to another page who made the csv file and theoretically do the download of the file. 我有一个带有此按钮的主页,然后单击它,将POST请求(带有Javascript和Ajax)发送到制作CSV文件并从理论上进行文件下载的另一页。 This is the code of the main page: 这是主页的代码:

<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>

Of course this is just a test, i have another main page where the user can select the query and the table. 当然,这只是一个测试,我还有另一个主页,用户可以在其中选择查询和表。 This is the code of ExportCSV.php 这是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>

I try the code like this and doesn't work, i try to substite application/octet whit text/csv, i try to insert echo readfile($name) or only readfile($name) but anything work. 我尝试这样的代码,但不起作用,我尝试替换application / octet whit text / csv,我尝试插入echo readfile($ name)或仅插入readfile($ name),但任何方法都可以。 The result of this is create a file inside the webroot and it's not good, i would like the the browser download the file. 这样做的结果是在webroot内创建一个文件,效果不好,我想让浏览器下载该文件。 Thanks a lot. 非常感谢。

EDIT: I try to execute only the page with the download script and it's work, the problem is when i call it with ajax!!! 编辑:我尝试只执行带有下载脚本的页面,并且可以正常工作,问题是当我使用Ajax调用它时!!! How it's possible? 怎么可能? Where is the error? 错误在哪里?

I did not check your inner code, but surely CSV cannot start with <html> tag! 我没有检查您的内部代码,但是CSV肯定不能以<html>标记开头! You need to reply only CSV content, remove all tags but <php> . 您只需要回复CSV内容,删除除<php>所有标签。

For example: 例如:

<?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();
    }
?>

I just removed heading and trailing <html><body> tags 我只是删除了<html><body>标签的标题和结尾

HTML Tags HTML标签

You specified you need a way to force the download (and there are no error messages provided) so I'm going to presume you can access it fine via the browser. 您指定了一种强制下载的方法(并且没有提供错误消息),因此我假设您可以通过浏览器正常访问它。

You'll need to firstly remove any HTML tags you have on that page. 您首先需要删除该页面上的所有HTML标记。 When you echo readfile($name); 当您echo readfile($name); , the resulting file you want downloaded will look a bit like this: ,您要下载的结果文件将看起来像这样:

<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 Functions 标头功能

Any header() functions used should be sent to the client before anything else in the page; 使用的所有header()函数都应先发送给客户端, 然后再发送到页面中的任何其他内容 it should be at the very top of your code even before your include connection.php; 即使在include connection.php;之前,它也应该位于代码的最顶层include connection.php; line. 线。

Ajax 阿贾克斯

You can't download a file using Ajax ( see here ). 您无法使用Ajax下载文件( 请参阅此处 )。

Instead, make it a GET (or POST if you like) request to that exportCSV.php file with additional parameters, ie: 相反,使用其他参数使其成为对该exportCSV.php文件的GET (如果需要,也可以选择POST )请求,即:

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

Since it's a file download it won't redirect you to another page, it will just start downloading the file. 由于是文件下载,因此不会将您重定向到另一个页面,它只会开始下载文件。

Headers 标头

If you're combining php with html, always put the logic and all the processing at the beginning of the file, so: 如果要将php和html结合使用,请始终将逻辑和所有处理放在文件的开头,因此:

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

That will prevent sending wrong headers to the browser. 这样可以防止向浏览器发送错误的标题。 The header() function is effective only if none of the other headers were sent. 仅当没有其他头发送时, header()函数才有效。

Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. 请记住,必须先通过常规HTML标记,文件中的空白行或从PHP发送任何实际输出,然后调用header()。 (source) (资源)

Function 功能

I need to mention, that you should NEVER use POST / GET parameters to send SQL queries! 我需要提及的是,您永远不要使用POST / GET参数发送SQL查询! Instead, send some informations like query name, and query parameters that you can then use to build the SQL query properly and safely, ie.: 而是发送一些信息,例如查询名称和查询参数,然后您可以使用它们来正确,安全地构建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();
  ...
}

Then return readfile($name) in that function instead of echoing it. 然后在该函数中return readfile($name)而不是回显它。 And exit() instead of die() . 然后使用exit()代替die() (source) (资源)

Example

Here is a working example of a simple script: 这是一个简单脚本的工作示例:

<?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>

I hope that this helped. 我希望这会有所帮助。

See this is my simple code for download csv dynamically. 看到这是我用于动态下载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;
}

This is my code for download simple Excel. 这是我用于下载简单Excel的代码。 and its working Quite Fine.put this php anywhere and you'll able to download csv. 及其正常工作的Fine.put此php到任何地方,您就可以下载csv。

First thing i would say thanks to all for lot of answers, today i find a solution and for me it work, i add in the main page this: 首先,我要感谢所有人的大量回答,今天我找到了一个解决方案,对我来说,它可以正常工作,我在主页上添加以下内容:

$(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();
      });
  });

and in the export page: 并在导出页面中:

<?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;
?>

Thanks a lot. 非常感谢。 Have a nice day. 祝你今天愉快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ReactJS:单击按钮下载 CSV 文件 - ReactJS: Download CSV File on Button Click 从网站点击按钮自动下载每日csv文件 - Automate daily csv file download from website button click 下载本地文件,点击按钮 - download a local file, on button click 在按钮上下载文件单击jquery - Download file on button click jquery 有没有办法使用Python从“网站按钮点击”下载csv文件? - Is there any way to download csv file from “website button click” using Python? 如何在javascript中单击按钮在cordova移动应用程序中创建和下载csv文件 - How to create and download csv file in cordova mobile app with button click in javascript How to implement download CSV file in Spring Boot, JSP, JavaScript, MySQL database on button click? - How to implement download CSV file in Spring Boot, JSP, JavaScript, MySQL database on button click? Angular 2下载带有身份验证的.CSV文件点击事件 - Angular 2 download .CSV file click event with authentication 单击按钮无法在laravel ajax中下载文件 - Unable to download file in laravel ajax on button click 在Button Click上从textarea下载文本文件 - Download a text file from textarea on Button Click
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM