6

I am using PHPExcel to read an excel template, populate the data, and ask the user to download the file.

generate_excel.php

$objPHPExcel = PHPExcel_IOFactory::load("./template.xlsx");
//populate data ...
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');

When I open generate_excel.php directly from the browser, the result file is downloaded. But if I make an ajax call to the generate_excel.php, I don't get the download prompt. Using chrome developer tools, I can see from the Network tab that the ajax call was successfully completed and a bunch of random characters is seen in the response data. I'm assuming that is the excel object.

Does anyone know how I can achieve the download excel feature using ajax? I don't want to refresh the page. When the user clicks on the "export" button, there should be an ajax call to the php file and prompt the user to download.

Thanks!

Toby Allen
  • 10,997
  • 11
  • 73
  • 124
John Ng
  • 869
  • 3
  • 15
  • 28
  • 1
    I am not sure about php but if it works the same way as asp.net then when you have the file returned, your page does not actually reload. So, it doesn't really matter if it's ajax or not. – reggaemahn Jun 27 '13 at 18:53

5 Answers5

9

I looked for ways to pass JSON data with ajax to PHP and return an excel file (MySQL and PHPExcel) for the user to save. I looked around and put some pieces together, hope it can help someone:

jQuery:

$("#exportBotton").on("click",function(event) {
event.preventDefault();
// create json object;
str_json = JSON.stringify({"key01":val01, "key02":val02, "key03":val03});
        $.ajax({
              type: "post",
              data: str_json,
              url: "../../includes/dbSelect_agentFormExport.php",
              dataType: "json",
              success: function(output){
                          // output returned value from PHP t
              document.location.href =(output.url);
            }
       });
});

PHP:

 $str_json = file_get_contents('php://input');
 $objPHPExcel = new PHPExcel();
 // here i populated objPHPExcel with mysql query result.....

 function saveExcelToLocalFile($objWriter){
    // make sure you have permission to write to directory
    $filePath = '../tmp/saved_File.xlsx';
    $objWriter->save($filePath);
    return $filePath;
}

 $objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
 $response = array(
     'success' => true,
     'url' => saveExcelToLocalFile($objWriter)
 );
 echo json_encode($response);
 exit();
maozx
  • 319
  • 4
  • 5
  • I tried to open Excel directly from the AJAX call but without success. there is problem with the MIME type Then I tried your approach saving the file to the server and giving the url to main page. It worked directly. You made my day. Thanks alots. – Ydakilux May 09 '14 at 09:10
  • its helpful lot – sradha Aug 23 '19 at 06:45
8

Not everything should be done with AJAX. Sometimes plain old HTML is more suitable for a job. I guess your button has a tag? Why won't you do something like this

<a href="generate_excel.php" target="_blank">Export to Excel</a>

in your HTML? Note the target="_blank" part. It's there to make sure your page is not reloaded.

For input you can use construct

<form action="generate_excel.php" target="_blank"><input type="button">...whatever</form>
David Jashi
  • 4,490
  • 1
  • 21
  • 26
5

Here is an example of how to download a file using an AJAX call:

var xhr = new XMLHttpRequest();
xhr.open("GET", "path/to/file.ext", true);
xhr.responseType = "blob";
xhr.onload = function(e) {
   if (xhr.status === 200) {
      var a = document.createElement("a");
      a.href = URL.createObjectURL(xhr.response);
      a.download = "file.ext";
      a.style.display = "none";
      document.body.appendChild(a);
      a.click();
   }
};
xhr.send();
Debajit Mukhopadhyay
  • 4,072
  • 1
  • 17
  • 22
3

Found a way to do this, although I'm not sure if this is an ideal approach.

I added a hidden iframe in the page. When the ajax call returns, it returns the url of the created data. I used javascript to redirect the iframe to that url which automatically triggers the download action.

John Ng
  • 869
  • 3
  • 15
  • 28
0

You can try this way:

  1. Send a Jquery AJAX POST request with the data that is to be used to generate excel report, and store that data in a session variable. Return an arbitrary string like 'success' as the response.
  2. If the output of the above AJAX call is 'success', then do a GET request to another URL in your application, that reads the data from session (stored in the first step, else throw an error), prepares an excel file out of that data, and forces the download of that excel file to the browser.
shasi kanth
  • 6,987
  • 24
  • 106
  • 158