0

I have two PHP pages. First one is a form where user inputs data, when submitted second page is created with a div that makes a "invoice". This page has options to save that invoice as PDF or IMG. This page it also sends and email automatically with confirmation.

Id like to send in this email also PDF or image as attachment.

html2canvas.js .png:

function picDiv() { 
html2canvas($('#printableArea')[0], {
  width: 1200
}).then(function(canvas) {
  var a = document.createElement('a');
  a.href = canvas.toDataURL("image/png");
  a.download = 'nalog.png';
  a.click();
});
};

And html2pdf.js to produce pdf:

function pdfDiv() { 
var element = document.getElementById('printableArea');
var opt = { 
    filename:     'nalog.pdf'
};
html2pdf().set(opt).from(element).save();
};

I have read among other things Send Image to server using File input type, html2canvas and jsPDF : send generated pdf as email attachment. Also outside articles like this: Send HTML5 Canvas as Image to Server and html2pdf github post. This last html2pdf github post states following code can be send to email or server but I don't know how to email it. It converts pdf successfully to string.

    html2pdf().from(element).toPdf().output('datauristring').then(function (pdfAsString) {
//send via email.
        });

My php email sending is:

$user = "some email";
$usersubject = "Initium - Vaš online radni nalog";
$userheaders = "From: some email";
$usermessage = "

//some content with php variables and text.

";    
mail($user,$usersubject,$usermessage,$userheaders);

I would be happy if someone would explain how to send PDF OR IMAGE via this code I already have. Keep in mind this is all on same page and this needs to be done on this same page load.

I tried numerous things and ways to do it and got lost as this is new territory for me. Any help is appreciated.

EDIT:

Full working solution is here: https://stackoverflow.com/a/61418366/7158959

Community
  • 1
  • 1
ikiK
  • 6,328
  • 4
  • 20
  • 40

3 Answers3

1

OK, so I'm guessing you need both steps:

Step 1: Send file content from the front-end to the server. Use the following in your JavaScript, right after you get the file content as a string (say, a variable named "pdfcontent"):

    var x = new XMLHttpRequest();
    var url = "<your domain>/mail.php";
    x.open("POST", url, true);
    x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    x.send("data="+pdfcontent);

No need to put this into any HTML element, or whatever - just execute it right after 'pdfDiv' or whichever function creates the file content. Of course, this is just a skeleton code - a real program must include error checking, protection against various attacks, etc, but that's a whole different story. It's also possible that you'll need to format 'pdfcontent' so it could be used as an URI parameter like this.

Step 2: Now your "mail.php" script (or whatever you call it - the one with the "mail" command) has received the file content in $_POST['data'] string. Or perhaps you already have the file content (PDF or whatever) as a binary string on the server side (your question isn't clear about that). Either way, you just need to attach it to the email and send it away. Binary attachments are indeed a pain, so I suggest downloading and installing PHPMailer (https://github.com/PHPMailer/PHPMailer) - it's pretty friendly and easy to install and use. Once you install it, use the following in your PHP script instead of the "mail" command:

    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    require_once "PHPMailer/src/Exception.php";  // directory may be different on your server
    require_once "PHPMailer/src/PHPMailer.php";  // directory may be different on your server

    $mail = new PHPMailer;
    $mail->addAddress(...);   // specify "To" address
    $mail->setFrom(...);   // specify "From" address
    $mail->Subject = ...;   // specify subject line
    $mail->Body    = ...;   // specify email content
    $mail->addStringAttachment(<binary string with file content>, "nalog.pdf");
    $mail->send();

There is more to sending emails than this, if you want to make sure your email reaches its destination and doesn't get stuck in a spam folder or something, but that's a whole different story. Also, if you receive this data via $_POST, then you must validate it properly, or it's just a ticking time bomb. You must also make sure that your script can't be used directly, or anyone can send any spam on your behalf and you'll be in trouble. although I'm not sure how to protect from such an attack under this setup. You might have to rethink your entire architecture and generate file content only on the server and not use AJAX at all for this purpose - too dangerous.

  • Very well write up, i really appreciate it. We are on to something, this is very helpful. I have managed to install everything, and POST is made and mail is sending, its just my applications do not recognize the content. I can not open PDFs, they are not empty tho, they have size. And in console log i can see pdfAsString is populated. Also tried with image and i can se in log: data:image/png;base64,iVBORw0KGgo.... And changed file in mail code to .png but same thing, cant open it. – ikiK Apr 24 '20 at 03:02
  • Also thank you for tips and guidance and I will work on my security and change things, just one step at the time :) , the app is old a week and in making. Need this urgent however... – ikiK Apr 24 '20 at 03:04
  • Sounds like the content gets corrupted somewhere along the way. Try to measure the size of this content in bytes in each step - I'm guessing it gets truncated at some point. If you're indeed using AJAX, then you need to make sure that 'pdfcontent' doesn't include any illegal or special characters (it probably does). "&" and "=" have special meaning in URI, so you should replace them with "%26" and "%3D" respectively before using 'pdfcontent' variable, e.g: pdfcontent = pdfcontent.replace(/&/,"%26").replace(/=/,"%3D"); – Dimitry Rotstein Apr 24 '20 at 03:21
  • Anyway, glad I could help. If you really found my answer useful, please consider upvoting it :-) – Dimitry Rotstein Apr 24 '20 at 03:23
  • Oh yeah I was going to ;) yeah i see this is problem of its own, see some posts here to read up about it, hopefully ill get i to work. Now I know it should work thanks to you. Thankful for your time! – ikiK Apr 24 '20 at 03:27
  • Nothing works for me :( https://stackoverflow.com/questions/61401519/sending-todataurl-data-via-mail Opend new question here if maybe you have some idea... – ikiK Apr 24 '20 at 05:22
0

If you already have a string on the client side, then the easiest way is to use AJAX to send it to server. You can simply create the XMLHttpRequest object directly (look it up, it's pretty simple), or maybe JQuery (which you're apparently using) has an even easier way, not sure, haven't used it in years. Anyway, with AJAX you just send the file content as a string to that PHP script which has the 'mail' command, and that should be it. Tell me if you need a detailed code example.

  • Thank you for replay, I would appreciate a link or two with example. Or even detailed code example, im reading about his for last 24 hours and im lost how to connect all this I have. I have a string yes, but it is generated on same page as my PHP mailing code that is shown above. How can i attach that into same mailing code. All i am finding is huge PHP mailing scripts to send attachments but i don't know how to appaned my string to it. Like i say i am lost. And i don't know how Ajax would help as I already have sending mail via php. – ikiK Apr 24 '20 at 00:39
  • I see how to send this via XMLHttpRequest, so I need to send it to hidden html input field and attach it to email as regular php variable? Somehow im sure that wont work ;( – ikiK Apr 24 '20 at 00:48
0

I found an approach here: https://base64.guru/developers/php/examples

I can now send an email attachment directly using: 'html2pdf.bundle.min.js' with 'jquery.min.js' post to PHP 'PHPMailer'.

All I needed to do was to strip "data:application/pdf;filename=generated.pdf;base64," out from the string before sending to PHP.

cigien
  • 57,834
  • 11
  • 73
  • 112