Save and render a webpage with PhantomJS and node.js
From your comments, I'd guess you have 2 options
- Try to find a phantomjs node module - https://github.com/amir20/phantomjs-node
- Run phantomjs as a child process inside node - http://nodejs.org/api/child_process.html
Edit:
It seems the child process is suggested by phantomjs as a way of interacting with node, see faq - http://code.google.com/p/phantomjs/wiki/FAQ
Edit:
Example Phantomjs script for getting the pages HTML markup:
var page = require('webpage').create();
page.open('http://www.google.com', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var p = page.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML
});
console.log(p);
}
phantom.exit();
});
Rendering Current Page With PhantomJS
If I correctly understood your question.
Example:
[main.js]
const dashboardToPdfCtrl = require("./controllers/phantom/pdf");
router.route("/api/dashboard/phantom").post(dashboardToPdfCtrl.createPdf);
router.route("/api/dashboard/phantom/html")
.post(dashboardToPdfCtrl.createDashboard);
When the user clicks on the "button" you can validate the USER according to the architecture of your application.
[pdf.js]
exports.createPdf= async (req, res) => {
if (!req.user || !req.user.sub) {
return res
.status(401)
.send({ message: 'No authorization token was found' });
}
const instance = await phantom.create();
const page = await instance.createPage();
const settings = {
operation: "POST",
encoding: "utf8",
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify({
user: req.body.userId,
anyDataYouNeedToRender: req.body.anyDataYouNeedToRender
})
};
//POST request to /api/dashboard/phantom/html
await page.open(
`${process.env.HOST}:${
process.env.PORT
}/api/dashboard/phantom/html`,
settings
);
//Save the content of /public/dashboard/dashboard.html with received data to pdf
const pageSaved = await page.render(
path.resolve(`./public/dashboard/file.pdf`)
);
if (pageSaved) await instance.exit();
}
exports.createDashboard = (req, res) => {
res.render(
path.resolve("./public/dashboard/dashboard.html"),
{ user: req.body.user,
anyDataYouNeedToRender: req.body:anyDataYouNeedToRender
}
);
};
Is that what you were looking for? I want to help you, feel free to ask detalization.
P.S. As friends told before in comments, it will be great if you give us more information to understend you goal.
phantomjs - render HTML to PDF
I'd suggest rewrite to page.open
a file:
var page = require('webpage').create();
var args = require('system').args;
var fs = require('fs');
function getFileUrl(str) {
var pathName = fs.absolute(str).replace(/\\/g, '/');
// Windows drive letter must be prefixed with a slash
if (pathName[0] !== "/") {
pathName = "/" + pathName;
}
return encodeURI("file://" + pathName);
};
page.paperSize = {
format : 'A4',
orientation : 'portrait',
margin : {
top : '1cm',
left : '1cm',
bottom : '1cm',
right : '1cm'
}
};
page.open(getFileUrl(args[1]), function(){
page.render(args[2]);
phantom.exit();
});
getFileUrl
is from this answer
phantomjs // render webpage from give dom
Have a look at casperjs' bbcshot.js
code sample, it does quite exactly what you're asking for.
Generating PDF of a Web Page
Its very clear that pdf is generated before document ready
Very true, so it is necessary to wait until after scripts are loaded and executed.
You linked to an answer that uses phantom node module.
The module was upgraded since then and now supports async/await functions that make script much much more readable.
If I may suggest a solution that uses the async/await version (version 4.x, requires node 8+).
const phantom = require('phantom');
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
(async function() {
const instance = await phantom.create();
const page = await instance.createPage();
await page.property('viewportSize', { width: 1920, height: 1024 });
const status = await page.open('http://www.chartjs.org/samples/latest/charts/pie.html');
// If a page has no set background color, it will have gray bg in PhantomJS
// so we'll set white background ourselves
await page.evaluate(function(){
document.querySelector('body').style.background = '#fff';
});
// Let's benchmark
console.time('wait');
// Wait until the script creates the canvas with the charts
while (0 == await page.evaluate(function(){ return document.querySelectorAll("canvas").length }) ) {
await timeout(250);
}
// Make sure animation of the chart has played
await timeout(500);
console.timeEnd('wait');
await page.render('screen.pdf');
await instance.exit();
})();
On my dev machine it takes 600ms to wait for the chart to be ready. Much better than to await timeout(3000)
or any other arbitrary number of seconds.
Related Topics
Angular 2: How to Detect Changes in an Array? (@Input Property)
Chrome Extension - How to Get Http Response Body
Can You Determine If Chrome Is in Incognito Mode via a Script
What Advantages Does Using (Function(Window, Document, Undefined) { ... })(Window, Document) Confer
Javascript: How to Validate Dates in Format Mm-Dd-Yyyy
Failed to Load C++ Bson Extension
Get and Set a Single Cookie with Node.Js Http Server
How to Convert Raw JavaScript Object to a Dictionary
Http Status Code 401 Even Though I'm Sending Credentials in the Request
How to Sequentially Run Promises with Q in JavaScript
Access JavaScript Nested Objects Safely
How to Implement a Stack and a Queue in JavaScript
Is There a Good JavaScript Minifier
Getting Blob Data from Xhr Request
Which Characters Are Valid/Invalid in a JSON Key Name
Keyword 'Const' Does Not Make the Value Immutable. What Does It Mean