How to generate a PDF File (just as a File) using html2pdf - javascript

I am working on a React project.
Here, I am trying to generate a PDF file (invoice) and upload it to Google Drive.
following code shows how I tried to create the file but I could not get the PDF file I needed. I would like to know how to generate the PDF file using html2pdf.js lib.
function createPDF() {
console.log('create PDF function works!');
let element = document.getElementById('report_component');
let opt = {
margin: 1,
filename: 'my-invoice.pdf',
image: {type: 'jpeg', quality: 0.98},
html2canvas: {scale: 2},
jsPDF: {unit: 'in', format: 'a4', orientation: 'portrait'}
};
// New Promise-based usage:
// window.html2pdf().set(opt).from(element).save(); // I do not want to save/download the PDF using the web browser.
// I want to get the PDF file. I tried like this;
let value = window.html2pdf().set(opt).from(element).toContainer().toCanvas().toImg().toPdf().output();
// const blob = new Blob([value], { type: 'application/pdf'});
let file = new File([value], 'my-invoice.pdf', {
type: 'application/pdf',
});
/* Here I try to implement the code to upload the PDF file to Google Drive.
* First I need to get the PDF File. */
console.log(file);
}

If any one searching an answer for this question. here it is;
I wanted to create a report(invoice) using HTML. Below you can find how I designed my invoice.
Note: Please note that I included html2pdf.js as a script in HTML.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Invoice</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
</head>
<body>
<section id="my_invoice">
<!-- I designed the invoice here -->
</section>
</body>
</html>
Most of the existing code tutorials show us to download the generated PDF. Following JavaScript code will help you to download the PDF. When you run this code, browser will open a window and asks where to download this PDF file. Then, you can save the PDF file easily.
let element = document.getElementById('my_invoice');
let opt = {
margin: 1,
filename: 'my-invoice.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
};
// New Promise-based usage:
html2pdf().set(opt).from(element).save();
But my requirement was slightly different. I just wanted to create the PDF file. Then, do something with that file. In my scenario, I wanted to upload that generated PDF file to Google Drive. Following code segment shows how I use html2pdf.js to generate the PDF file(blob). Please note that I used .outputPdf() method to get the blob. For more information, you can refer to the html2pdf.js Worker API documentation.
/** Creates the PDF report document.
* #return Promise: resolves if PDF report generates successfully,
* otherwise rejects. */
function createPDF() {
return new Promise(async (resolve, reject) => {
console.log('create PDF function executed!');
let element = document.getElementById('my_invoice');
let opt = {
margin: 1,
filename: 'my-invoice.pdf',
image: {type: 'jpeg', quality: 0.95},
html2canvas: {scale: 2, useCORS: true},
jsPDF: {unit: 'in', format: 'a4', orientation: 'portrait'}
};
try {
const blob = await window.html2pdf().set(opt).from(element).outputPdf('blob', 'my-invoice.pdf');
resolve(blob);
} catch (e) {
reject(e);
}
});
}
Hope you learnt something. Cheers!

Related

How to show print preview in electron?

I am using Cordova-electron with ReactJS to build a desktop application. we need to implement print-preview in our application instead of showing the default system dialog for printing.
The community says there is no default way to achieve this in electron, we need to do it manually. I used html2pdf.js,jsPDF to generate PDF from the client-side but none of these are giving the exact PDF we need, all have some alignment issues, font issues, and page-break issues, etc. please suggest me a proper solution for this issue.
I am attaching code to generate PDF by using html2pdf.js which I have used
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 1, logging: true, width: '1024', dpi: 100, letterRendering: true },
jsPDF: { unit: 'mm', orientation: 'portrait', format: 'a4' },
pagebreak: { after: '.page-break' }
}
var worker = html2pdf().set(opt).from(componentRef.current).to('pdf').output('blob').then(d => {
console.log('pdf-file', d);
var blob = new Blob([d], { type: "application/pdf" });
console.log('Blob-pdf', blob);
var url = URL.createObjectURL(blob);
var printWindow = window.open(url, '', 'width=800,height=500');
}).catch(d => {
console.error('error in PDF generation', d);
})
Unfortunately, the electron does not have a print preview, you can use nw.js instead of the electron if you want a print preview

Upload a excel file with google drive api

I'm having a problem with the google drive API.
I'm trying to upload an excel file with this API, but it's not working. Even copying the google API documentation doesn't work.
Here is a sample of my code:
#Get('teste')
async teste(){
const keys = require(path.resolve('src', 'files', 'api', 'keys'))
const client = new google.auth.JWT(
keys.client_email,
null,
keys.private_key,
['https://www.googleapis.com/auth/drive.metadata.readonly']
)
client.authorize((err, tokens) =>{
if(err){
console.log(err)
return;
} else{
this.gdrun(client)
}
})
}
gdrun(client){
const drive = google.drive({version: 'v3', auth: client});
var fileMetadata = {
name: 'My Report',
mimeType: 'application/vnd.google-apps.spreadsheet'
};
var media = {
mimeType: 'application/vnd.ms-excel',
body: require(path.resolve('src', 'files', 'excel', 'solargroup.xlsx'))
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file: any) {
if (err) {
// Handle error
console.error(err);
} else {
console.log('File Id:', file.id);
}
});
}
I received this error:
I believe your goal as follows.
You want to upload a file (XLSX file) to Google Drive of the service account.
You want to achieve this using the service account with googleapis for Node.js.
From your script, I thought that you might wanted to upload a XLSX file as Google Spreadsheet by converting.
Modification points:
When you want to upload a file to Google Drive, in this case, please use the scope of https://www.googleapis.com/auth/drive instead of https://www.googleapis.com/auth/drive.metadata.readonly.
When you want to upload XLSX file as the XLSX file, the mimeType is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.
When you want to upload a file, body: require(path.resolve('src', 'files', 'excel', 'solargroup.xlsx')) cannot be used. In this case, please use body: fs.createReadStream(path.resolve('src', 'files', 'excel', 'solargroup.xlsx')). I thought that your error message might be due to this.
When you want to retrieve the file ID of the uploaded file, please modify file.id to file.data.id.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
const client = new google.auth.JWT(
keys.client_email,
null,
keys.private_key,
['https://www.googleapis.com/auth/drive.metadata.readonly']
)
To:
const client = new google.auth.JWT(
keys.client_email,
null,
keys.private_key,
['https://www.googleapis.com/auth/drive'] // Modified
)
And also, please modify your gdrun() as follows.
gdrun(client){
const drive = google.drive({ version: "v3", auth: client });
var fileMetadata = {
name: "My Report",
mimeType: "application/vnd.google-apps.spreadsheet",
};
var media = {
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // Modified
body: fs.createReadStream(path.resolve('src', 'files', 'excel', 'solargroup.xlsx')), // Modified
};
drive.files.create(
{
resource: fileMetadata,
media: media,
fields: "id",
},
function (err, file) {
if (err) {
console.error(err);
} else {
console.log("File Id:", file.data.id); // Modified
}
}
);
}
In this case, please use const fs = require("fs").
Result:
When above script is run, the following result is obtained.
File Id: ###fileId###
Note:
Your script uploads a XLSX file to Google Drive of service account as Google Spreadsheet. In this case, you cannot directly seen the uploaded file at your Google Drive. Because the Google Drive of the service account is different from your Google Drive. When you want to see the uploaded file at your Google Drive, please create a folder on your Google Drive and share the created folder with the email of the service account. And then, please upload the file to the shared folder. By this, you can see the uploaded file on your Google Drive with your browser. For this, please modify fileMetadata as follows.
var fileMetadata = {
name: "My Report",
mimeType: "application/vnd.google-apps.spreadsheet",
parents: ["### folderId ###"], // Please set the folder ID of the folder shared with the service account.
};
In above script, the maximum file size is 5 MB. Please be careful this. When you want to upload a file more than 5 MB, please use resumable upload. Ref
References:
Upload file data
Files: create

jspdf create empty file

I am trying to do from my dynamic HTML(where I am taking data in tables and just text from DB), by using jspdf return just empty file pdf.
<script>
$("#btn-print").click(() => {
var pdf = new jsPDF();
pdf.addHTML(document.section, function () {
pdf.save("report.pdf");
});
});
</script>
It would be better to use html2pdf which uses combination of html2canvas,jsPDF and has multiple options for a rich pdf conversion of web page
using a sample table (used static data but should work same for dynamic too)
function genPDF() {
var element = document.getElementById('pdfContent');
var opt = {
margin: 1,
filename: 'myfile.pdf',
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
// New Promise-based usage:
html2pdf().from(element).set(opt).save();
}
See working example here
Do not forget to include cdn links
Hit GeneratePDF Button to download as pdf and check in downloads location

how to send pdf as a file as form-data to server

I have little knowledge on promises ,
What i have been doing is to convert html to pdf , thankfully html2pdf works great ,
Now where I was stuck is getting the pdf as a file and post to server with form-data
I have somehow found to get pdf encoded string from here
But it is a promise and i have a function as :
genPDF:function(){
var element = document.getElementById('canvasId');
var opt = {
filename: 'nobutton.pdf',
image: { type: 'jpeg', quality: 0.98 },
// html2canvas: { scale: 2 },
};
html2pdf().from(element).set(opt).toPdf().output('datauristring').then(function (res) {
var blobString = res;
console.log(blobString);
});
}
But here it doesn't log at first time , but then the function is called again and then logs , why is that ?? could i get it for the first time the function called ?
Can some one help me how to get the pdf from html2pdf as a file so that can append it to form-data , any help is really appreciated , Thanks :)
#Sophie - here is the asnyc version as discussed in the comments.
async genPDF() {
var element = document.getElementById('canvasId');
var opt = {
filename: 'nobutton.pdf',
image: { type: 'jpeg', quality: 0.98 },
// html2canvas: { scale: 2 },
};
let blobString = await html2pdf().from(element).set(opt).toPdf().output('datauristring');
console.log(blobString);
}

html2pdf freeze UI

Hi i'm using html2pdf on my React project and i'm going through problems when i try to generate the pdf document.
The problem is that in Android/desktop the UI freeze for a while (time that take to generate pdf file) and then the download work fine. In iphone the UI freeze and never recover, i can't interact with others components like a table or a combo, it only recover if I close the explorer and reopen and when I do that the pdf file appears in the screen with the right format and look.
Here is what i'm doing:
const PdfDownloader = (props) => {
const exportToPDF = (fileName) => {
let opt = {
margin: 0.5,
filename: `${fileName}.pdf`,
image: {type: 'jpeg', quality: 0.98},
html2canvas: {scale: 2},
jsPDF: {unit: 'in', format: 'letter', orientation: 'portrait'}
};
html2pdf().set(opt).from(pdfContainerRef.current).save();
}
return (
<div>
<Button className={styles["max-width-initial"]} block
onClick={() => exportToPDF('my_crazy_file')}>
Descargar PDF
</Button>
</div>
)
}
I have no idea what i'm doing wrong, or if something missing in my code or i'm in front of a bug.

Categories