3

I'm using jsPDF to create a pdf on client side and it's working fine by using pdf.save('document.pdf');. Now I'm trying to send an email along with PDF as an attachment by using AJAX and Zend_Mail function on the back end, but it doesn't work!

Well, I've tried pdf.output();, pdf.output('blob'); and also tried to pass pdf.output('datauristring'); but facing different issues.

First of all, I've converted HTML into png by using domtoimage and the code for it is below:

domtoimage.toPng(node)
    .then(function (dataUrl) {
        /* This function is used to generate or send output of the pdf to the back end */
        createCalendarPdf(dataUrl);
    })
    .catch(function (error) {
        alert('Oops, something went wrong! ' + error);
    }
);

For downloading the PDF on a client side, I've simply used and it works

pdf.save('document.pdf');

For sending blob or base64 string I'm having difficulties.

First Approach

Code below to change the PDF output into blob object url

BLOB Object URL

Creating a blob object url for the PDF

var binaryImg = pdf.output();
var length = binaryImg.length;
var arrayBuffer = new ArrayBuffer(length);
var uintArray = new Uint8Array(arrayBuffer);

for (var i = 0; i < length; i++) {
    uintArray[i] = binaryImg.charCodeAt(i);
}

var currentBlob = new Blob([uintArray], {type: 'application/pdf'});

var createdBlobUrl = URL.createObjectURL(currentBlob);

# Output looks like this
blob:http://example.com/ff471a1c-702j-453d-01g0-d6a26l901bvz

AJAX Request

Using FormData

var fd = new FormData();
fd.append('file', createdBlobUrl);

$.ajax({
    type: 'POST',
    url: functionUrl,
    data: fd,
    processData: false,
    contentType: false,
    async: false
}).done(function(data) {
    console.log(data);
});

So, I'm not sure how to get content from the blob object URL in Zend or simple PHP. So I tried file_get_contents($this->_params['file']) but it didn't work!

Second Approach

Tried to pass pdf.output(); or pdf.output('datauristring'); but couldn't receive the result on the back end side because of the length of the string. As I said earlier that I've changed the HTML template into PNG first then creating a PDF out of it. So, that's why the web inspector stuck in between the process and then have to kill the page completely.

Already increased the max_post_size and other stuff already in php.ini

Zend_Mail Function

$mail = new Zend_Mail();

$attachment = $mail->createAttachment($pdfFile);
$attachment->type = 'application/pdf';
$attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT;
$attachment->encoding = Zend_Mime::ENCODING_BASE64;
$attachment->filename = 'document.pdf';

$mail->setBodyHtml($html);
$mail->setFrom($emailFrom, 'Adeel');
$mail->addTo($emailTo, 'ABC');
$mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
$mail->setSubject($subject);

// send email
$mail->send();

So, in short I just wanted to know how can I get content from the blob object url, if there is any possible way or how to pass base64 string to the back end and parse it in PHP.

I've already spent few days on finding the solution for this issue, but couldn't find one, or maybe I've done something wrong here.

Adeel
  • 2,901
  • 7
  • 24
  • 34

1 Answers1

0

I have used html2pdf library which combines canvas and jspdf so am sure the working will still be the same or roughly similar.

Step 1 I create the pdf and set the output of datauristring to be a blob

async function printer() {
  var worker = html2pdf();
  await worker.from(document.querySelector('#element'));
  let myPdf = await worker.outputPdf('datauristring', 'mypdf.pdf');
  
  //this converts the uri to blob
  var preBlob = dataURItoBlob(myPdf);
  var file = new File([preBlob], "namefile.pdf", {type: 'application/pdf'});
   
  // sends the message to api
  sendFile(file);
}

// Below is the function to convert the uri string to blob

 function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
       var byteString;
       if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
       else
          byteString = unescape(dataURI.split(',')[1]);
    
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
    
        return new Blob([ia], {type:mimeString});
    }

I then have the actual function to send the email to an API. I have used fetch due to non-familiarity with AJAX:

 async function sendFile(userFiles) {
       let filePaths;
       let formData = new FormData();
       formData.append("file", userFiles);
       let response = await fetch('mailer.php', {
           method: 'POST',
           body: formData
       });
        
       filePaths = await response.json();
       return filePaths;
    }
Elvis Ben
  • 1
  • 1