点击按钮

时间:2017-10-25 09:14:14

标签: javascript php jquery csv

早上好, 当用户点击“导出CSV”按钮时,我需要强制下载csv文件,我看到很多页面(这里和谷歌)并尝试了很多东西但是任何东西都适合我。 我有一个带有此按钮的主页面,然后单击它将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调用它时!怎么可能?错误在哪里?

5 个答案:

答案 0 :(得分:1)

我没有检查您的内部代码,但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>代码

答案 1 :(得分:1)

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;行之前位于代码的最顶层。

答案 2 :(得分:0)

的Ajax

您无法使用Ajax(see here)下载文件。

相反,请将break(或GET,如果您愿意)请求带有其他参数的POST文件,即:

exportCSV.php

由于它是文件下载,因此无法将您重定向到另一个页面,它只会开始下载该文件。

接头

如果您将php与html结合使用,请始终将逻辑和所有处理放在文件的开头,以便:

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

这样可以防止向浏览器发送错误的标头。 <?php header('Content-Type: application/octet-stream'); ?> <html> </html> 函数仅在未发送其他标头时才有效。

  

请记住,在发送任何实际输出之前,必须通过普通HTML标记,文件中的空行或PHP来调用header()。 (source)

功能

我需要提一下,您应该从不使用header() / POST参数来发送SQL查询!相反,发送一些信息,如查询名称和查询参数,然后您可以使用它们来正确安全地构建SQL查询,即:

GET

然后在该函数中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()(source)

实施例

以下是一个简单脚本的工作示例:

die()

我希望这有帮助。

答案 3 :(得分:0)

看到这是我动态下载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的代码。和它的工作相当精细。在任何地方输入这个PHP,你就可以下载csv。

答案 4 :(得分:0)

首先我要感谢所有人的答案,今天我找到了一个解决方案,对我来说它有用,我在主页中添加了这个:

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

非常感谢。 祝你有愉快的一天。