0

I am struggling with achieving what I want and am not sure if it is possible. I am using CodeIgniter and PHP for my web application. My home view allows users to query a database and the results are generated and displayed in the table form on the page. The user will then review the table and be provided the option of downloading as an xlsx Excel file. I am using an ajax post to send the table data to my PHP controller that will create the Excel file. I also need this to work in all browsers especially Safari, as the client will access the application from Ipads as well as desktop machines.

My home ajax post: (t is the id of the generated table)

$("#btnExport").click(function() {
    $.ajax({
        type: "POST",
        url: '<?php echo base_url();?>index.php/Home/excel',
        datatype: 'html',
        data: {
            'queryData': $("#t").html()},
        success: function (response) {
            alert(response);
        }             
    });
});

My controller function:

public function excel()
{
    $this->load->library('excel');
    $filename = "data";
    $table = $this->input->post('queryData');
    $objPHPExcel = new PHPExcel();
    $tmpfile = time().'.html';
    file_put_contents($tmpfile,$table);
    $objReader = PHPExcel_IOFactory::createReader('HTML');
    $objPHPExcel = $objReader->load($tmpfile);

    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename='.$filename);
    header('Cache-Control: max-age=0');

    $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    $objWriter->save('php://output');       
    unlink($tmpfile);
}

The problem is the handling of the ajax response I've read its impossible to download a file from ajax. Everything I have tried is not working The response is binary encoded data I am assuming is the excel file. Is there a workaround to this problem? I decided on ajax as the table can change dynamically given the current query, and needs to be sent to the server accordingly.Thanks for any assistance.

EDIT In the linked question it is about submitting forms and not triggering a download. I am not submitting any forms, just passing an html table to the PHP to build the Excel file. I fail to see how that is relevant to my problem. Am I misunderstanding?

Sparky
  • 98,165
  • 25
  • 199
  • 285
ees3
  • 105
  • 10
  • Possible duplicate of [jQuery Ajax POST example with PHP](http://stackoverflow.com/questions/5004233/jquery-ajax-post-example-with-php) – Neo Nov 11 '16 at 13:25
  • are you constructing table in controller? –  Nov 11 '16 at 13:28
  • @EaBangalore Yes, the table is being constructed in different functions within the same controller. – ees3 Nov 11 '16 at 13:35

2 Answers2

0

there are 2 possibilities that i know

1. store the constructed table in localStorage of your browser

<div id="myTable">
  <table>
    <tr>
    <th>A</th>
    <th>B</th>
  </tr>
   <tr>
      <td>Value for column A</td>
      <td>Value for column B</td>
  </tr>
 </table>
</div>

// in jquery

        $(document).ready(function(){
           alert('nothing');

            if (typeof(Storage) !== "undefined") {
                // Code for localStorage/sessionStorage.



               var table = $('#myTable').html();

              localStorage.setItem("storedTable",table);



            } else {

                console.log('no support');
                // Sorry! No Web Storage support..
            }

        });

// now you can get the table in the next page like this

var table = localStorage.getItem("storedTable");

2. solution, store them in the $_SESSION like this

  session_start()
  $_SESSION["myTable"]  = $yourConstructedTable

redirect to that page where you want to print

get the table like so

        session_start();
 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');

        $table =   $_SESSION["myTable"];
       unset($_SESSION["myTable"]); // don't forget to unset the session

    // rest of your code
  • sorry for the late yesterday i din't get your response, so today i have posted –  Nov 12 '16 at 05:13
0

Submitting a form is the best you can do to trigger a file download... It's better to create one even if you don't have a form.

var baseUrl = '<?php echo base_url();?>'

var $form = $(`<form method="post" hidden action="${baseUrl}index.php/Home/excel"><textarea name="queryData">`)
$form.find('textarea').val($("#t").html())
$form.appendTo('body').submit()

There is however one alternative to saving ajax responses and that is by creating a link with a object url from a blob response, setting the download attribute and trigger a click (in IE you need to call navigator.saveOrOpenBlob)
There is a good lib out there that is called FileSaver to abstract out all nasty vendor specifics

The way you would use it is by doing this:

fetch(url, {method: 'post', body: data})
.then(res => {
   var cd = res.header.get('Content-Disposition')
   var filename = cd.match(/filename="(.+)"/)[1]

   return res.blob().then(blob => saveAs(blob, filename))
})

But it's not as good as submitting a form and getting a bit of help from a server that can send a Content-Disposition header cuz not all browser (safari mainly) supports download attribute in links...

Endless
  • 34,080
  • 13
  • 108
  • 131