3

I'm trying to develop a way for users to download a table in CSV format via jQuery/PHP.

  1. My aim is to send the jQuery request to the server using PHP.
  2. PHP then creates the CSV content and returns it.
  3. jQuery then forces the browser to download the content as a CSV file.

I've got 90% working, the last bit is that I need to force the CSV download in the users browser using jQuery.

My PHP script

<?php
class Export {
    public static function tocsv($results = array(), $fields = array(), $filename) {
        $fh = fopen('php://output', 'w');
        ob_start();
        fputcsv($fh, $fields);

        if(!empty($results)) {
            foreach($results as $row) {
                fputcsv($fh, (array) $row);
            }
        }

        $string = ob_get_clean();
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-type: text/csv");
        header("Content-Disposition: attachment; filename=$filename");

        exit($string);
    }
}
?>

My jQuery script

$(function() {
    var btnName;
    $('.button').click(function() {
          btnName = $(this).attr('name');
          btnValue = $(this).attr('value');
    });

    $("#spendReports").submit(function(event) {
        event.preventDefault();
        var formData = $('#spendReports').serializeArray();
        formData.push({ name: btnName, value: btnValue });

        $.post('spendReports.php', formData, function(data)
        {
            var data = $.parseJSON(data);
            $.each(data, function(i, val) {
                var newRow = '<tr><td class="dates-col" data-th="Date">' + data[i]["dates"] + '</td><td data-th="Project name">' + data[i]["project"] + '</td><td data-th="Total budget">' + data[i]["budget"] + '</td><td data-th="Plot numbers">' + data[i]["plots"] + '</td><td data-th="Categories">' + data[i]["categories"] + '</td><td data-th="Day work spent">£' + data[i]["day_work_spent"] + '</td><td data-th="% spend">' + data[i]["day_work_spent_percent"] + '%</td><td data-th="Price work spent">£' + data[i]["price_work_spent"] + '</td><td data-th="% spend">' + data[i]["price_work_spent_percent"] + '%</td><td data-th="Agency work spent">' + data[i]["agency_work_spent"] + '</td><td data-th="% spend">' + data[i]["agency_work_spent_percent"] + '%</td><td data-th="Subcon spent">' + data[i]["subcon_work_spent"] + '</td><td data-th="% spend">' + data[i]["subcon_work_spent_percent"] + '%</td><td data-th="Supervision spent">' + data[i]["supervision_spent"] + '</td><td data-th="% spend">' + data[i]["supervision_work_spent_percent"] + '%</td><td data-th="Total spent">£' + data[i]["total_spent"] + '</td></tr>';
                $("#results > tbody").append(newRow);
            });
        });
    });
});

This is different from Download File Using jQuery as i'm not physically creating a file on the server and therefore do not have a phsical link to send to jQuery.

Community
  • 1
  • 1
V4n1ll4
  • 5,973
  • 14
  • 53
  • 92
  • it's not possible with ajax, the user needs to actually click something. You can simulate it by create an href and then click it with javascript ... or you could just have the user download the file directly without the use of any ajax. – Jonathan May 06 '15 at 15:28
  • @Barmar this is not the same as the link you posted. I am not physically creating the file on the server. I am only returning the CSV contents to jQuery and then want jQuery to force a file download in the browser. – V4n1ll4 May 06 '15 at 15:31
  • 1
    I don't think there's a way for Javascript to do a download by itself. You have to redirect the browser to a URL that returns the download. – Barmar May 06 '15 at 15:35
  • You have to create a file on your server before you can download it I believe – Yann Chabot May 06 '15 at 15:35
  • 1
    @YannChabot It doesn't have to be a file, you can download directly from a script. The browser can't tell the difference. – Barmar May 06 '15 at 15:42

1 Answers1

0

Have a look at this answer: https://stackoverflow.com/a/4551467/563802

In your case it should be something like this:

var uriContent = "data:text/csv," + encodeURIComponent(data);
newWindow=window.open(uriContent, 'newDocument');
Community
  • 1
  • 1
xpereta
  • 692
  • 9
  • 21