Save and Render a Webpage with Phantomjs and Node.Js

Save and render a webpage with PhantomJS and node.js

From your comments, I'd guess you have 2 options

  1. Try to find a phantomjs node module - https://github.com/amir20/phantomjs-node
  2. 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();
});

Sample Image

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



Leave a reply



Submit