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?
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...
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