使用php和ajax生成并下载CSV文件

9

我有一个php页面,它创建一个CSV文件,然后由浏览器自动下载。这里是一个带有示例数据的版本 - 它运行得很好。

<?php

$cars = array(
  array("Volvo",22,18),
  array("BMW",15,13),
  array("Saab",5,2),
  array("Land Rover",17,15)
  );

// output headers so that the file is downloaded rather than displayed
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=csvfile.csv');

// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');

// output the column headings
fputcsv($output, array('Car', 'Year', 'Miles' ));

//Loop through the array and add to the csv
foreach ($cars as $row) {
    fputcsv($output, $row);
}

?>

我希望能够使用ajax从另一个页面运行此代码,以便用户可以在不离开主页面的情况下生成/下载csv。这是我在主页面上使用的JavaScript。在我的实际页面中,我正在使用通过ajax获取的数据。
$('button[name="exportCSVButton"]').on('click', function() {
    console.log('click');
    $.ajax({
        url: 'exportCSV.php',
        type: 'post',
        dataType: 'html',
        data: {

            Year: $('input[name="exportYear"]').val()
        },
        success: function(data) {
            var result = data
            console.log(result);


        }
    });
});

当我点击按钮触发脚本时,它会运行,但是它并没有将内容保存或下载为 csv 文件,而是将整个内容都打印到了控制台上。有没有什么办法可以实现我想要的效果?而不必真正将文件保存在服务器上并重新打开。

可能是重复问题:https://dev59.com/e2Qo5IYBdhLWcg3wZepg - Alexey
为什么你需要使用Ajax呢?只要在服务器端放置适当的头文件,浏览器就不会被重定向下载。 - charlietfl
在成功函数内导出文件后,请使用window.location.assign('path_to_csv_generated_file'),确保文件位于公共可访问目录中。完成后即可。 - Muhammad Omer Aslam
1
提交表单而不是使用ajax。在发送之前,更新提交事件处理程序中的年份字段。 - charlietfl
1
@MuhammadOmerAslam,为什么使用Ajax尝试会有任何不同呢? - charlietfl
显示剩余7条评论
3个回答

16

我已经通过Ajax下载了CSV文件

PHP代码

    <?php
         function outputCsv( $assocDataArray ) {

            if ( !empty( $assocDataArray ) ):

                $fp = fopen( 'php://output', 'w' );
                fputcsv( $fp, array_keys( reset($assocDataArray) ) );

                foreach ( $assocDataArray AS $values ):
                    fputcsv( $fp, $values );
                endforeach;

                fclose( $fp );
            endif;

            exit();
        }

        function generateCsv(){
            $res_prods = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}products` ", OBJECT );

            $products= [];
            foreach ($res_prods as $key => $product) :
                $product_id = $product->ID;

                $products[$product_id]['product_id'] = $product_id;
                $products[$product_id]['name'] = $product->name;
            endforeach;

            return outputCsv( $products);
      }

jQuery AJAX

jQuery(document).on( 'click', '.btn_generate_product', function(e) {

    var product_id = jQuery(this).data('product_id');

    jQuery.ajax({
        url : "ajaxurl", 
        type: 'POST',
        data: { product_id },
        success: function(data){

              /*
               * Make CSV downloadable
               */
              var downloadLink = document.createElement("a");
              var fileData = ['\ufeff'+data];

              var blobObject = new Blob(fileData,{
                 type: "text/csv;charset=utf-8;"
               });

              var url = URL.createObjectURL(blobObject);
              downloadLink.href = url;
              downloadLink.download = "products.csv";

              /*
               * Actually download CSV
               */
              document.body.appendChild(downloadLink);
              downloadLink.click();
              document.body.removeChild(downloadLink);

        }
    });
});

2
php函数没有返回任何内容。 - Rotimi
2
对我有用,我用自己的数据替换了产品 SQL 和数组。 - trainmania100

2

将console.log(result);替换为文件保存代码。 在这里查看 JavaScript:创建和保存文件

使用简单的代码以浏览器对话框的方式保存文件是最好的方法。

<a href="#" onclick="window.open('exportCSV.php?year=' + $('input[name="exportYear"]').val())" >Download File</a>

这应该被标记为可能重复,而且你可能在抄袭。 - Funk Forty Niner

0

我之前曾经通过创建一个隐藏的iframe并通过javascript将iframe的源设置为一个php文件,该文件会像您的exportCSV.php一样发送适当的头信息和数据来实现此功能。

但是,如果您不喜欢这个想法,您可以使用类似于jQuery文件下载FileSaver.js的库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接