Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download in browser with ajax request

I'm working with AngularJS and I'm trying to generate a PDF in php. This is what I have in my controller.js:

$scope.downloadPDF = function(){     $http.post('/download-pdf', { fid: $routeParams.fid })         .success(function(data, status, headers, config){             console.log("success");         })         .error(function(data, status, headers, config){             console.log("error");         }); }; 

In my php file I have the following to create a PDF with FPDF library:

function download_pdf() {     $id = $_POST['fid'];      $pdf = new FPDF();      $pdf->AddPage();     $pdf->SetFont('Arial','B',16);     $pdf->Cell(40,10,'Hello World!');      header('Content-Type: application/pdf');     header('Content-Disposition: attachment; filename=' . $id . '.pdf');      $pdf->Output('Order123.pdf', 'D'); } 

But the request is responding this instead of open a save dialog to save my pdf.

%PDF-1.3 3 0 obj <> endobj 4 0 obj <> stream x3Rðâ2Ð35W(çr QÐw3T04Ó30PISp êZ*[¤(hx¤æää+çå¤(j*dÔ7W endstream endobj 1 0 obj < endobj 5 0 obj < endobj 2 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << /F1 5 0 R > /XObject << > > endobj 6 0 obj << /Producer (FPDF 1.7) /CreationDate (D:20150611094522) > endobj 7 0 obj << /Type /Catalog /Pages 1 0 R > endobj xref 0 8 0000000000 65535 f 0000000228 00000 n 0000000416 00000 n 0000000009 00000 n 0000000087 00000 n 0000000315 00000 n 0000000520 00000 n 0000000595 00000 n trailer << /Size 8 /Root 7 0 R /Info 6 0 R > startxref 644 %%EOF

I've used the PHPExcel library and this worked:

$objWriter = PHPExcel_IOFactory::createWriter($ea, 'Excel2007');  // We'll be outputting an excel file header('Content-type: application/vnd.ms-excel');  // It will be called Submission on [date_now].xls header('Content-Disposition: attachment; filename="' . $filename . '.xls' . '"');  // Write file to the browser $objWriter->save('php://output'); 

Now how can I make this work for my PDF?

UPDATE:

I've edited my code to this:

$pdf = new FPDF();  $pdf->AddPage(); $pdf->SetFont('Arial','B',16); $pdf->Cell(40,10,'Hello World!');  $filename = DXS_VKGROUP_PLUGIN_LIB_DIR . 'uploads/' . $_POST['fid'] . '.pdf';  $pdf->Output($filename, 'F'); // Save file locally  header('Pragma: public'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Type: application-download'); header('Content-Length: ' . filesize($filename)); header('Content-Transfer-Encoding: binary'); header('Content-Disposition: attachment; filename="' . $filename . '"');  $handle = fopen($filename, 'rb'); fpassthru($handle); fclose($handle); 

The file is saved locally but the download doesn't work. It doesn't get my a dialog to save the pdf. What am I doing wrong?

UPDATE 2

I've now tried to change application-download in application/pdf. He saves the file locally but I don't get a download dialog box.

The response looks like this (when I check Network in Chrome):

%PDF-1.3 3 0 obj <> endobj 4 0 obj <> stream x3Rðâ2Ð35W(çr QÐw3T04Ó30PISp êZ*[¤(hx¤æää+çå¤(j*dÔ7W endstream endobj 1 0 obj < endobj 5 0 obj < endobj 2 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << /F1 5 0 R > /XObject << > > endobj 6 0 obj << /Producer (FPDF 1.7) /CreationDate (D:20150617090832) > endobj 7 0 obj << /Type /Catalog /Pages 1 0 R > endobj xref 0 8 0000000000 65535 f 0000000228 00000 n 0000000416 00000 n 0000000009 00000 n 0000000087 00000 n 0000000315 00000 n 0000000520 00000 n 0000000595 00000 n trailer << /Size 8 /Root 7 0 R /Info 6 0 R > startxref 644 %%EOF

like image 822
nielsv Avatar asked Jun 11 '15 09:06

nielsv


People also ask

How can I download Excel file in AJAX?

Downloading Excel File using AJAX in jQueryInside the DownloadFile JavaScript function, the URL of the File is passed as parameter to the jQuery AJAX function. Inside the jQuery AJAX function, using the XmlHttpRequest (XHR) call, the PDF file is downloaded as Byte Array (Binary Data).

Can AJAX work with web application?

Ajax stands for Asynchronous JavaScript and XML. In essence, Ajax is an efficient way for a web application to handle user interactions with a web page - a way that reduces the need to do a page refresh or full page reload for every user interaction.


1 Answers

UPDATE

The method of using FileSaver.js also doesn't work , there seems to be no way to forcefully invoke the native Save As Dialog via JavaScript alone , only exception being the saveAs execCommand for IE. Check Does execCommand SaveAs work in Firefox?

Include FileSaver.js as dependency in your project

Change the downloadPDF function as follows

 $scope.downloadPDF = function() {     $http.post('/download-pdf', {         fid: $routeParams.fid       }, {         responseType: 'arraybuffer'       })       .success(function(data, status, headers, config) {         // Convert response data to Blob         var file = new Blob([data], {           type: 'application/pdf'         });         // Call the File Saver method to save the above Blob,this will show Save As dialog         saveAs(file, "test.pdf");       })       .error(function(data, status, headers, config) {         console.log("error");       });   }; 

The Blob object will work in most modern browser but there is limited support for IE < 10 , check https://github.com/eligrey/FileSaver.js#supported-browsers for polyfills

Also remove Content-Disposition: attachment and Content-Type: application-download headers as we don't want browser to natively handle the download process

Here is a working demo http://plnkr.co/edit/9r1tehQ94t5vkqZfZuQC?p=preview , it shows GET request to a PDF

like image 119
Prayag Verma Avatar answered Sep 29 '22 14:09

Prayag Verma