Storing generated PDF files on the server

b0w3rb0w3r picture b0w3rb0w3r · Apr 23, 2015 · Viewed 31.7k times · Source

Using the jsPDF plugin, I am creating a .pdf file and generating a download based on a button click. I would like to save the file onto my server instead of initiating the download. So when the button is clicked I would like the file to be saved in :

/tmp/uploads/pdf/example.pdf

I am aware I need have to use Jquery.Ajax to post the file to the server. However, looking at the documentation and I didn't see any support for .pdf as a datatype.

My code:

$(document).on("click", "#PDF", function () {
    var table = document.getElementById("result");
    var tbl = window.sessionStorage.getItem("tbl");
    var cols = [],
        data = [];

    function html() {
        var doc = new jsPDF('p', 'pt');
        var res = doc.autoTableHtmlToJson(table, true);
        doc.autoTable(res.columns, res.data);
        doc.save( tbl+".pdf");
    }
    html();
});

Based on this xml document saving example I tried the following:

var pdfDocument = doc.save( tbl+".pdf");
        var pdfRequest = $.ajax({
              url: "/tmp/uploads/pdf",
              processData: false,
              data: pdfDocument
            });

This downloaded the file instead of saving it. How can I save the file?

Answer

Nico picture Nico · Jun 15, 2016

If your PDF contains binary data, you can get into problems if you try to transfer the PDF via string. I used the blob output format of jsPDF with success.

var doc = new jsPDF();
// ... generate pdf here ...

// output as blob
var pdf = doc.output('blob');

var data = new FormData();
data.append('data' , pdf);

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if (this.readyState == 4) {
    if (this.status !== 200) {
      // handle error
    }
  }
}

xhr.open('POST', 'upload.php', true);
xhr.send(data);

Your upload.php can then use the $_FILES array in PHP

<?php
if(!empty($_FILES['data'])) {
    // PDF is located at $_FILES['data']['tmp_name']
    // rename(...) it or send via email etc.
    $content = file_get_contents($_FILES['data']['tmp_name']);
} else {
    throw new Exception("no data");
}
?>