0

From PHP Side, I generate XLSX data through PHPExcel. I need to transfer the xlsx data through a JSON data structure, to get status, message information, and exchange data if so. I use base64 encoding to encode the xsl data into a string from the JSON data structure.

Here is the environment :

Server: PHP 5.6.0 / Apache Web Server 2.4.9 / Microsoft Windows 7 SP1

//XLSX data generation
$objWriter  = PHPExcel_IOFactory::createWriter($xls,"Excel2007");
ob_start();
$objWriter->save("php://output");
$xlsData = ob_get_contents();
ob_end_clean();

//xlsData is encoded in "ISO-8859-1"
$xlsData = iconv("UTF-8", "ISO-8859-1", $xlsData);
$xlsData = base64_encode($xlsData);

//JSON data struture. To exchange data between Server side (PHP) and client side (javascript)
$opResult = {status:1, messageType: 2, message = 'XLSX successfully generated', data: null};
$opResult->data = $xlsData;

$opResult = json_encode($opResult);

header("Content-type: application/json; charset=utf-8");
echo $opResult;

From Javascript side, I use php.js function to decode base64 encoding and FileSaver.js to save xlsx data to local file

Client: Javascript provided by Firefox 31.0 / Windows 7 SP1

xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
   if( (xmlHttp.readyState == 4) && (xmlHttp.status == 200)){
     var opResult = JSON.parse(xmlHttp.responseText);
     var xlsData = base64_decode(opResult.data);
     var blob = new Blob([xlsData], {type: "application/octet-stream;charset=utf-8"});
     saveAs(blob, "report.xlsx");
  }
}
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send(params);

The problem :

At PHP side, XLSX file can be opened. At client side the xlsx data file can not be opened by Microsoft Excel. I get error message of corrupt file, ...

Base64 data sent by PHP side and received at javascript side are the same.

Is someone has already met such a problem ? Or is there anyone who used a such mechanism to exchange data between PHP and Javascript ?

Can anyone help me about the following interrogations:

  1. From PHP side :

    1.1 Is encoding to UTF-8 needed?

    Since UTF is the encoding character used at javascript side, I use iconv function, but without success. I obtained an unreadable xlsx file at javascript side

    1.2 Does base64 encoding can be assigned to only one data member of a JSON data structure:

    $opResult->status = 1;
    $opResult->messageType = 2;
    $opResult->message = 'XLSX successfully generated';
    $opResult->data = base64_encode($xlsData);
    

    1.3 Does json_encode function need option parameters?

    //I tried
    json_encode($opResult, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    

    But always having same problem at client side

  2. From Javascript side :

    2.1 I use an old version of base64_decode function , not the last one with decodeURIComponent(..).

    If I use the last base64_encode version, I get an error message : URI malformed.

    2.2 Is FileSaver.js correctly used ?

    var blob = new Blob([xlsData], {type: "application/octet-stream;charset=utf-8"});
    saveAs(blob, "report.xlsx");
    

Thanks you for your help

  • may be worth while reading something like this http://stackoverflow.com/questions/1645847/ajax-binary-response may help though I don't get why you're streaming the file just save it locally and pass a path to the javascript then have the javascript read create link for the user to click to download rather than forcing the download and do it all in php. – Dave Sep 09 '14 at 13:09
  • I need to have error status of operation at PHP side. And I don't want to store the file at PHP side. – mustapha.boularbi Sep 09 '14 at 13:32
  • Can I hope to have any resolution? Or should I close the question? – mustapha.boularbi Sep 11 '14 at 20:19

1 Answers1

3

The subject is closed using a workaround.

From PHP side :

1.1 No need to encode in UTF-8

1.2 binary data is set as URL data

  url = "data:". $mimeType. ";base64,".base64_encode(xlsData);

1.3 no need to pass option parameters to json_encode function.

So the code becomes:

//XLSX data generation
$objWriter  = PHPExcel_IOFactory::createWriter($xls,"Excel2007");
ob_start();
$objWriter->save("php://output");
$xlsData = ob_get_contents();
ob_end_clean();

//JSON data struture. To exchange data between Server side (PHP) and client side (javascript)
$opResult = {status:1, messageType: 2, message = 'XLSX successfully generated', data: null};
$opResult->data = "data:". $mimeType. ";base64,".base64_encode($xlsData);
$opResult = json_encode($opResult);

header("Content-type: application/json; charset=utf-8");
echo $opResult;

From javascript side:

No need to use blob and Filesaver.js API

The code becomes:

xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if( (xmlHttp.readyState == 4) && (xmlHttp.status == 200)){
  var opResult = JSON.parse(xmlHttp.responseText);
  var a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";
  a.href = opResult.data;
  a.click();
  window.URL.revokeObjectURL(opResult.data);
 }
}
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.send(params);