0

Im trying to send PDF or PNG over email and nothing seems to work. Below is my LAST attemnt, I have read every single article here on SO and nothing sees to work what is suggested, can someone please help? I am using PHPMailer, html2pdf and html2canvas, both of those produce proper documents on click, just sending them to php mailer dos not work. I am getting documents that can not be opened... Below are my last attempts... With file_get_contents method i get 0 sized data.

PDF attempt:

var element = document.getElementById('printableArea');
// var opt = {  
//      filename:     'nalog.pdf'
// };   
html2pdf().from(element).toPdf().output('datauristring').then(function (pdfAsString) {
    pdfcontent = pdfAsString.replace(/&/,"%26").replace(/=/,"%3D");
     var x = new XMLHttpRequest();
     var url = "xxx/mail.php";
     x.open("POST", url, true);
     x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     x.send("data="+pdfcontent);
console.log(pdfcontent);
        });

PHP:

$mail->AddStringAttachment($_POST['data'],"nalog.pdf"); 

PNG attempt:

html2canvas($('#printableArea')[0], {
  width: 1200
}).then(function(canvas) {
    var data = canvas.toDataURL("image/png");
    pdfcontent = data.replace(/&/,"%26").replace(/=/,"%3D");
    var x = new XMLHttpRequest();
    var url = "xxx/mail.php";
    x.open("POST", url, true);
    x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    x.send("data="+pdfcontent);
    console.log(pdfcontent);
});

PHP:

$mail->AddStringAttachment($_POST['data'],"nalog.png"); 

EDIT: To update my question, I have made suggested things from anwser and tryed to debug it and nothing helped. I made PHP file_put_contents() and compere it with console log and it is the same data.

Any other suggestions?

ikiK
  • 6,328
  • 4
  • 20
  • 40
  • Test one thing at a time: Check that the PDF or PNG is valid *before* you try to email it. At the moment you can’t tell where the problem is. – Synchro Apr 24 '20 at 06:49
  • @Synchro Thank you for your input, ill try to debug it and found a source. – ikiK Apr 24 '20 at 13:48
  • Please don't edit faux tags like `[solved]` into the titles of questions. To mark the question solved, accept an answer. – user229044 Apr 24 '20 at 22:38
  • @meagar No problem, first time I did it, come to think of it, never sow tag like that, I see now why . But why removing the rest? – ikiK Apr 24 '20 at 22:40
  • I rolled back your edit; if you want to update the title to make it clearer, feel free to do so. – user229044 Apr 24 '20 at 22:43
  • @meagar OK, thank you, I appreciate it. – ikiK Apr 24 '20 at 23:15

2 Answers2

0

My guess is that the problem occurs during transfer, since URI doesn't deal well with binary data - there could be NUL characters and who knows what else in there, which truncate or mess-up the data. Try sending this data like this instead (as raw text, instead of URL-encoded one):

    var x = new XMLHttpRequest();
    x.open("POST", "xxx/mail.php", true);
    x.setRequestHeader("Content-type", "text/plain; charset=utf-8");
    x.send( new Uint8Array(pdfcontent) );

Then, on the server side, you need to extract this raw data like this:

   $data = file_get_contents('php://input');

Using $_POST won't work, it should be empty.

If this still produces a bad file, then perhaps the problem isn't in the transfer. Try to copy+paste whatever console.log prints out into a file and see if it can be opened (it might not work even if the data is valid, since were working with binary data, but if it does work, then great - at least we can rule out the problem at the source). Then try to save the data on the server side using file-put-contents (https://www.php.net/manual/en/function.file-put-contents.php), and see if that produces a valid file. If it does, then the problem occurs during emailing.

In any case, you should really generate the files on the server side - all this back and forth is terribly inefficient and horribly unsafe. For example, you can use FPDF (http://www.fpdf.org/) to create a PDF file from scratch using PHP and email it right there. Yes, it doubles your output efforts, since you need to produce HTML and PDF separately, but it's well worth it in the long run. Or perhaps you don't need to produce HTML at all in this setup? Do you produce HTML for the sole purpose of emailing it or do you really need to present it to the user as well?

  • Thank your for your input, ill try everything suggested, and to answer, I don't have FPDF library included in my hosting, ill see with my hooters or I can include it myself. And yes, I understand what are you saying, its just because of specific business purposes yes, it should be generated like I implemented it. Problem is some people wont have emails, and it is not mandatory field in a form (owners requirement). – ikiK Apr 24 '20 at 13:52
  • So it needs to be generated on form submit with option to print/download/save as pdf/pic and i wan to mail it right away if email is provided. I know, but this is requirement. Pain in the a... – ikiK Apr 24 '20 at 14:01
  • edit: I see i can include FPDF, ill see about it after trying making this work* – ikiK Apr 24 '20 at 14:14
  • file_get_contents('php://input'); suggested method produced 0 files sized files,. – ikiK Apr 24 '20 at 14:47
  • I made PHP file_put_contents() and compere it with console log and it is the same data :( – ikiK Apr 24 '20 at 14:54
  • "file_get_contents('php://input'); suggested method produced 0 files sized files" -- Then you must have missed something in JavaScript - there is no reason why php://input would be empty if you did it right. ----- "I made PHP file_put_contents() and compere it with console log and it is the same data" -- Have you tried saving the console.log output and see if you get a valid file? Maybe the function that creates this output isn't working properly. – Dimitry Rotstein Apr 24 '20 at 17:54
  • Anyway, if your workflow requires the user to press "submit" button after filling out the form and you can create file content before submission, then you can indeed write the result into the value attribute of some hidden input inside the form (with method='post' and you can also try enctype='multipart/form-data' if necessary), and let it be submitted with the form. That might work better than AJAX, but only if AJAX is the problem, and it shouldn't be. – Dimitry Rotstein Apr 24 '20 at 18:34
  • Yeah i saved both files as pic or pdf, wont open. Same thing. I dont now, when i lunch them on click they both produce proper files and download them. Ill give it one more try, and file_get_contents too. try to see what i can change. But im close to giving up :), I appreciate your time and help. – ikiK Apr 24 '20 at 18:59
  • oh my good! https://github.com/eKoopmans/html2pdf.js/issues/181#issuecomment-494341420 I haven't read this properly, there are few suggestions here for sending it via mail. – ikiK Apr 24 '20 at 19:04
  • Made it! I was moments of giving up :D See my answer. Thanks a lot for sticking around, been a big help for me. – ikiK Apr 24 '20 at 22:30
0

After almost giving up, finally got it to work. Its a combination of few things linked here and suggested. This post on github html2pdf helped a bit also.

I'm posting it here as none of the examples worked for me, took me two days to find what works for me and my interment. Hope it helps someone.

window.onload = function pdfDivload (){
let el = document.getElementById('printableArea');
let opt = {
    margin:       1,
    filename:     'myfile.pdf',
    image:        { type: 'jpeg', quality: 0.98 },
    html2canvas:  { scale: 2 },
    jsPDF:        { unit: 'in', format: 'A4', orientation: 'portrait' }
};

html2pdf().set( opt ).from( el ).toPdf().output('datauristring').then(function( pdfAsString ) {
    let data = {
        'fileDataURI': pdfAsString,
    };
    $.post( "../prog/mail.php", data);
    console.log( data );
} );
};

PHP:

  if (isset($_POST['fileDataURI'])) {

                $pdfdoc         = $_POST['fileDataURI'];

            $b64file        = trim( str_replace( 'data:application/pdf;base64,', '', $pdfdoc ) );
            $b64file        = str_replace( ' ', '+', $b64file );
            $decoded_pdf    = base64_decode( $b64file );
            //file_put_contents( $attachment, $decoded_pdf );

            $mail = new PHPMailer;
            $mail->setFrom( 'xxx@xxx.hr', 'website' );
            $mail->addAddress( 'xxx@gxxx.com', 'OdedTa' );
            $mail->Subject  = 'First PHPMailer Message';
            $mail->Body     = 'Hi! This is my first e-mail sent through PHPMailer.';
            $mail->addStringAttachment($decoded_pdf, "nalog.pdf");
            $mail->isHTML( true );
            $mail->send();
ikiK
  • 6,328
  • 4
  • 20
  • 40