How to print something on every page on page.pdf - node.js

I need to setup an anchor tag on every page. Is that possible?
<a href='#toc'>toc</a>
I tried implementing it like this
async function printPDF(domain,filename){
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setViewport({ width: 600, height: 400 })
await page.goto(domain + '/docs/' + filename + '.html', {waitUntil: 'networkidle0'});
const pdf = await page.pdf({
format: 'A4',
scale : 1,
printBackground : true,
headerTemplate: "<a href='#toc'>toc</a>" ,
displayHeaderFooter : true,
margin: { top: "2cm", bottom: "2cm", left: "2cm", right: "2cm" }
});
await browser.close();
return pdf;
}
But it's not working. Maybe because the header is treated as seperate from the content so it's not detecting the anchor?

Related

Puppeteer not work correctly with handlebars and get only blank page PDF

Hello im working in application that i want to create PDF files using puppeteer and handlbars but it create only blank PDF
Here is my code
File : functions.js
createPDF = async (templateName, data, file_name) => {
const pdfPath = `${process.cwd()}/public/tickets/${file_name}.pdf`;
const filePath = path.join(process.cwd(), "templates", `${templateName}.hbs`);
const html = fs.readFileSync(filePath, "utf-8");
const content = hbs.compile(html);
const htmlContent = content(data);
const options = {
format: "A4",
headerTemplate: "<p></p>",
footerTemplate: "<p></p>",
displayHeaderFooter: false,
margin: {
top: "10px",
bottom: "30px",
},
printBackground: true,
path: pdfPath,
};
const browser = await puppeteer.launch({
args: ["--no-sandbox"],
headless: true,
});
const page = await browser.newPage();
await page.goto(`data:text/html;charset=UTF-8,${htmlContent}`, {
waitUntil: "networkidle0",
});
console.log(await page.content());
await page.pdf(options);
await browser.close();
};
fileContoller.js
exports.myfile = async (req, res, next) => {
const { approved } = req.body;
const getData = await MyTable.findAll({
attributes: [
"id",
"first_name",
"last_name",
"birthday",
"gender",
"address",
"img",
],
where: { approved},
raw: true,
});
for (let i = 0; i < getData.length; i++) {
const createPDFforuser = await functions.createPDF(
"myhbsmockuptemplate",
getData[i],
`${getData[i].id}+${i}`
);
}
}
when i console.log htmlContent it get the html complete and correctly done as i write it
But when i console log awit page.content()
Here i dont get the html as expected it get only few line
<html><head>
<meta charset="utf-8">
<style type="text/css">
.tmp-mockup { font-family: "Staatliches", cursive; color: black;
font-size: 14px; letter-spacing: 0.1em; margin: 25px 0; } .ticket-box {
margin: auto; display: flex; background: </style></head><body></body></html>
Wait for some element in htmlContent after page is loaded.
await page.goto(`data:text/html;charset=UTF-8,${htmlContent}`, {
waitUntil: "networkidle0",
});
await page.waitForSelector('#visible-element')

Node.js Puppeteercannot render pdf export css correctly

I'm trying to get the html output of a website as a pdf with the width and height I specified with Node.js. However, on some sites, it can print without problems, while on some sites, the output is very distorted. I couldn't figure out why. When I turn on the handless feature and examine it, the page is created very smoothly, but in the pdf output, the images are corrupted like the pdf below. Can you please help? Where am I doing wrong?
https://pdfalarm.s3.eu-west-1.wasabisys.com/https%253a%252f%252frun-fix.com%252f30018001652834515056.pdf
const gopdf = async (url, width, height) => {
return new Promise(async (resolve, reject) => {
try {
var name = encodeURIComponent(String(url + width + height + Date.now()) + '.pdf')
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setViewport({ 'width': width, 'height': height });
await page.goto(url, { waitUntil: 'networkidle2' });
const optionsPDF = {
printBackground: true,
width: width + "px",
height: height + "px",
margin: { top: 0, right: 0, bottom: 0, left: 0 }
}
await delay(800)
const pdf = await page.pdf(optionsPDF);
await browser.close();
aws.upl(name, pdf)
.then(res => {
resolve({
status: res.data.Location?true:false,
data: res.data.Location?res.data.Location:false
})
})
} catch (err) {
resolve({
status: false,
data: err
})
}
})
}
If I put a wait time of 800 ms after the page is created, it looks corrupted as in the pdf in the link.

Puppeteer - PDFPrint but pdf is blank

I have a problem with puppeteer and pdf printing.
Everything looks ok, no error code,... but pdf is blank.
and templateHtml is good ! maybe it's an error in functions call await ?
Please help me !
async function createPDF(quotation, quoteurl, quotname){
var templateHtml = fs.readFileSync(path.join(process.cwd(), './templates/quotation2.html'), 'utf8');
//console.log(templateHtml);
var template = handlebars.compile(templateHtml);
//console.log(template);
var html = template(quotation);
//console.log(html);
var pdfPath = path.join(`${quoteurl}`, `${quotname}.pdf`);
console.log(pdfPath)
var options = {
width: '1230px',
headerTemplate: "<p></p>",
footerTemplate: "<p></p>",
displayHeaderFooter: false,
margin: {
top: "10px",
bottom: "30px"
},
printBackground: true,
path: pdfPath
}
const browser = await puppeteer.launch({
//args: ['--no-sandbox'],
headless: true
});
var page = await browser.newPage();
console.log('OH YES');
await page.goto(`data:text/html;charset=UTF-8,${html}`,{ waitUntil: ['domcontentloaded', 'load'] }).then(function (response) {
// page.emulateMedia('screen')
page.pdf({ path: pdfPath
, format: 'letter' })
.then(function (res) {
browser.close();
}).catch(function (e) {
browser.close();
})
})
}
i don't understand why it's not working.
I Change with this content and it works ! but the logo.png doesn't appear in the pdf (or it's in the same folder than html file.
Is there something to add to puppeteer to include image file in the pdf ? (it's declared in html file)
await page.setContent(html,{ waitUntil: ['domcontentloaded', 'load', "networkidle0"] }).then(function (response) {
// page.emulateMedia('screen')
page.pdf({ path: pdfPath,
format: 'A4',
printBackground: true,
margin: {
top: '20px',
bottom: '20px',
right: '20px',
left: '20px' }})
.then(function (res) {
browser.close();
}).catch(function (e) {
browser.close();
})
})

Giving timeout after evaluate in puppeteer is not working

I have a page which contains few visualizations. I have to evaluate and resize the charts. while evaluating, it takes few seconds to resize. the Previously I did this using phantom. I use to give timeout in the callback function and it worked perfectly. I'm trying the same using puppeteer which is not working. Not working in the sense, the resizing did not happen even after the timeout.
sample puppeteer code(not working)
const puppeteer = require('puppeteer');
const fs = require('fs');
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 2048, height: 1024 });
await page.goto("http://localhost:3000", { timeout: 180000 });
await timeout(5000);
page.on('console', msg => console.log('PAGE LOG:', msg.text()));
await page.evaluate(function() {
for (var i = 0; i < $('.react-grid-item').length; i++) {
$('.react-grid-item:eq(' + i + ')').css({
position: 'absolute',
height: '300px',
width: '100%',
top: (i * 300) + 'px',
left: '0px'
})
}
})
.then(function() {
setTimeout(function() {
page.pdf({
path: 'test' + new Date() + '.pdf',
// height: 7777,
// width: 2048,
format: 'a4',
displayHeaderFooter: false,
margin: {
top: "75px",
bottom: "75px"
}
});
// console.log(sum);
}, 5000);
}).catch(function(err) {
console.error(err);
})
})();
using await/async try follow like this:
await page.evaluate((a, b) => {
return a + b
}, 1, 2).then((sum) => {
setTimeout(() => {
console.log(sum)
}, 2000)
})

Puppeteer taking so long to load the page

I am trying to load a URL using Puppeteer and take the screenshot, somehow the page loading is taking too long. Here is my code
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
// headless: false,
args: [
`--window-size=42280,39960`,
// `--shm-size=1gb`,
// `--disable-dev-shm-usage`
]
});
const page = await browser.newPage();
await page.setViewport({
height: 39960,
width: 42280,
});
console.log('Page created');
await page.goto('https://www.google.com');
console.log('page loaded');
await page.screenshot({
path: 'example.png'
});
await browser.close();
})();
Did anyone face the same problem?
The reason of the failure is this:
await page.setViewport({
height: 39960,
width: 42280,
});
Error running your code. Error: Protocol error
(Page.captureScreenshot): Target closed.
Puppeteer can't take a screenshot with that resolution.

Resources