Red Taz
Red Taz

Reputation: 4179

Render HTML with images using PhantomJS

I am trying to create a PDF from HTML text using PhantomJS (version 1.9.7). I've written a very simple script (made more complicated by error callbacks etc.)

phantom.onError = function(msg, trace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    system.stdout.write(msgStack.join('\n'));
    phantom.exit(1);
};

var page = require('webpage').create();
page.viewportSize = { width: 800, height: 600 };
page.paperSize = { format: 'A4', orientation: 'portrait', margin: '1cm' };
page.onResourceRequested = function(requestData, networkRequest) {
    console.log('Request (#' + requestData.id + '): ' + JSON.stringify(requestData));
};
page.onResourceReceived = function(response) {
    console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response));
};
page.onResourceError = function(resourceError) {
    console.log('Unable to load resource (#' + resourceError.id + 'URL:' + resourceError.url + ')');
    console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};
page.onError = function(msg, trace) {
    var msgStack = ['ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
        });
    }
    console.error(msgStack.join('\n'));
};

page.content = "<html><body><b>test</b><img src=\"http://www.google.co.uk/images/srpr/logo11w.png\" alt=\"\" border=\"0\" /></body></html>";
page.render('tmp.pdf');
setTimeout(function() {
    phantom.exit();
}, 5000);

I set up the page, assign the simple HTML string to the content property and render it to a PDF.

This script doesn't produce any output.

I've narrowed the problem down to the <img> element, when that is removed a PDF is generated as expected. I can see from the callback functions that the image is requested, a response is received, and there are no errors reported. I've tried rendering to a PNG which also yields no output.

I've explored the possibility of this being a proxy issue, however the raserize.js example works without any problems.

Upvotes: 2

Views: 9852

Answers (1)

Cybermaxs
Cybermaxs

Reputation: 24556

You have to call render when the page is fully loaded. Remember that loading a page via page.open or page.content is always async.

Change your code to this

page.content = "<html><body><b>test</b><img src=\"http://www.google.co.uk/images/srpr/logo11w.png\" alt=\"\" border=\"0\" /></body></html>";
setTimeout(function() {
    page.render('tmp.pdf');
    phantom.exit();
}, 5000);

Upvotes: 8

Related Questions