Hi, A while ago i searched the forum to create a PDF in Wix. but i came up empty handed... Now i found a way to generate a PDF using the Embed HTML frame and jsPDF.
This only works for premium users.
add this HTML/JS Code to an embed HTML frame
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.6/jspdf.plugin.autotable.min.js"></script>
<script src="https://smtpjs.com/v3/smtp.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ejs@3.1.5/ejs.min.js"></script>
</head>
<table id= "theBody">
<span class="table"></span>
</table>
<script type="text/javascript">
//Needed to change image to PDF format string
function getDataUri(url)
{
return new Promise(resolve => {
var image = new Image();
image.setAttribute('crossOrigin', 'anonymous'); //getting images from external domain
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
//next three lines for white background in case png has a transparent background
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff'; /// set white fill style
ctx.fillRect(0, 0, canvas.width, canvas.height);
canvas.getContext('2d').drawImage(this, 0, 0);
resolve(canvas.toDataURL('image/jpeg'));
};
image.src = url;
})
}
//To have the right PDF format
var splitRegex = /\r\n|\r|\n/g;
jsPDF.API.textEx = function (text, x, y, hAlign, vAlign) {
var fontSize = this.internal.getFontSize() / this.internal.scaleFactor;
// As defined in jsPDF source code
var lineHeightProportion = 1.15;
var splittedText = null;
var lineCount = 1;
if (vAlign === 'middle' || vAlign === 'bottom' || hAlign === 'center' || hAlign === 'right') {
splittedText = typeof text === 'string' ? text.split(splitRegex) : text;
lineCount = splittedText.length || 1;
}
// Align the top
y += fontSize * (2 - lineHeightProportion);
if (vAlign === 'middle')
y -= (lineCount / 2) * fontSize;
else if (vAlign === 'bottom')
y -= lineCount * fontSize;
if (hAlign === 'center' || hAlign === 'right') {
var alignSize = fontSize;
if (hAlign === 'center')
alignSize *= 0.5;
if (lineCount > 1) {
for (var iLine = 0; iLine < splittedText.length; iLine++) {
this.text(splittedText[iLine], x - this.getStringUnitWidth(splittedText[iLine]) * alignSize, y);
y += fontSize * lineHeightProportion;
}
return this;
}
x -= this.getStringUnitWidth(text) * alignSize;
}
this.text(text, x, y);
return this;
};
// when a message is received from the page code
window.onmessage = (event) => {
console.log("event started")
download()
};
//Sending an email
function sendEmail(pdfBase64) {
Email.send({
SecureToken : "xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx", //Secure token made in SMTPJS.com
To : "youremail@provider.com",//Email to send to, or multiple "xxx@xxx.xx,xxx@xxx.xx"
From : "email used on SMTPJS",//Email the mail should be sending from
Subject : "SUBJECT OF THE EMAIL",//Subject of the mail
Body : `
This is the body of the message,
Using HTML you can style it as you need.
Using `` to use HTMl over multiple lines
`,
Attachments : [
{
name : "documentname.pdf", //Name of the pdf
data : pdfBase64 //datauristring
}
]
}).then(
message => alert("Ur email has been sended.")
);
}
async function download() {
var lineHeight = 5;
var logo = 'https://upload.wikimedia.org/wikipedia/en/thumb/7/76/Wix.com_website_logo.svg/311px-Wix.com_website_logo.svg.png'
var pdf = new jsPDF('p');
var myImage = await getDataUri(logo);
pdf.setFontType('normal')
pdf.setFontSize(10)
pdf.setTextColor(7, 12, 168)
pdf.text(10,10,"More info") //X,Y,text
pdf.text(10,10+(lineHeight*1),"About JSPDF")
pdf.text(10,10+(lineHeight*2),"Can be found")
pdf.text(10,10+(lineHeight*3),"at https://mrrio.github.io/jsPDF/examples/basic.html")
pdf.text(10,10+(lineHeight*4),"Or at the documentation website")
pdf.text(10,10+(lineHeight*5),"https://artskydj.github.io/jsPDF/docs/jsPDF.html")
pdf.addImage(myImage,'png',10,10+(lineHeight*6),155,60) // converted image,X,Y,WIDTH,HEIGHT
//var pdfpdfBase64 = pdf.output("datauristring")
//sendEmail(pdfpdfBase64)
//pdf.output("datauri")
pdf.save("test.pdf");
};
</script>
</html>
2.
Add a button to your page and add the following code.
$w("#yourhtmlelementname").postmessage("")
To send mails,
Go to SMTPJS
Scroll down to Security and press Encrypt SMTP Credentials
Fill in the form and press generate secure token.
Use that token in the sendMail function
Configure it as needed and use the following lines to send the mail.
var pdfBase64 = pdf.output("datauristring")
sendEmail(pdfBase64)
When using the postmessage you can add data to it.
to run different functions in the HTML frame
$w("#yourhtmlelementname").postmessage("sendmail") // or "download" or "opennewwindow"
var todo = ""
window.onmessage = (event) => {
todo = event.data // event.data = postmessage data
};
if(todo === "sendmail"){
var pdfpdfBase64 = pdf.output("datauristring")
sendEmail(pdfpdfBase64) // Sends the Email
} else if(todo === "download"){
pdf.save("test.pdf"); // saves the PDF
} else if (todo === "opennewwindow"){
pdf.output("dataurlnewwindow") // Opens the PDF in a new window
}
Output example:
Hope this will help some people.
If there are any questions ,
Feel free to ask,
I created a table where i take the data to the htmlframe.
And add in a new selfmade table.
Kind regards, kristof.
Could you share where you added the code to the html comp to create a table and how your sending the data to it. I've been at it for a couple days and realized after all that time that I didn't actually need to create a html table to make the pdf from. I've been able to successfully create a blank pdf but I'm having issues getting my data into it.
Hello, Kristof. Thank you for the detailed post! I'm having trouble with jspdf myself - I am just experimenting right now so have made my code very, very simple. But Wix is throwing a strange error. I was wondering if you have come across this before?
Whilst your code is much more thorough than my small experiment, the only difference of import I can see is that you included the package and dependencies in a <script> tag, instead of downloading the npm package and importing it. Is it possible I am missing a dependency?