|
var fs = require('fs'); |
|
var system = require('system'); |
|
var webpage = require('webpage'); |
|
|
|
var page = webpage.create(); |
|
|
|
var output = system.stderr; |
|
|
|
page.onConsoleMessage = function(msg, lineNum, sourceId) { |
|
output.writeLine('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")'); |
|
}; |
|
|
|
function logError(source, msg, trace) { |
|
output.writeLine(source + ' ERROR: ' + msg); |
|
trace.forEach(function(item) { |
|
output.writeLine(' ' + item.file + ':' + item.line); |
|
}); |
|
} |
|
|
|
page.onError = function(msg, trace) { |
|
logError('PAGE', msg, trace); |
|
}; |
|
|
|
phantom.onError = function(msg, trace) { |
|
logError('PHANTOM', msg, trace); |
|
phantom.exit(1); |
|
}; |
|
|
|
page.onResourceRequested = function(request) { |
|
output.writeLine('REQUEST: ' + JSON.stringify(request, undefined, 4)); |
|
}; |
|
|
|
var content = fs.read('/dev/stdin'); |
|
var url = system.args[1]; |
|
var sessionId = system.args[2]; |
|
|
|
phantom.addCookie({ |
|
'name': '_session_id', |
|
'value': sessionId, |
|
'domain': 'localhost', |
|
'path': '/', |
|
'httponly': true, |
|
'secure': false |
|
}); |
|
|
|
page.setContent(content, url); |
|
|
|
var paperSize = { |
|
format: 'A4', |
|
margin: { |
|
top: '1cm', |
|
bottom: '1cm', |
|
left: '2cm', |
|
right: '2cm' |
|
} |
|
}; |
|
|
|
// Define PDF header and footer using HTML template elements. |
|
// Example: `<template id="pdf-footer" data-height="1cm">Page <strong>%{pageNum}</strong></template>` |
|
['header', 'footer'].forEach(function(section) { |
|
var template = page.evaluate(function(s) { |
|
var element = document.querySelector('template#pdf-' + s); |
|
return element && { height: element.dataset.height, contents: element.innerHTML, style: element.getAttribute('style') }; |
|
}, section); |
|
if (!template) return; |
|
paperSize[section] = {}; |
|
paperSize[section].height = template.height; |
|
paperSize[section].contents = phantom.callback(function(pageNum, numPages) { |
|
var html = template.contents.replace(/%{pageNum}/g, pageNum).replace(/%{numPages}/g, numPages); |
|
return addPrintStyle(html, template.style); |
|
}); |
|
}); |
|
|
|
function addPrintStyle(html, bodyStyle) { |
|
return '<style media="print">\n' + |
|
'body {' + bodyStyle + '}\n' + |
|
printStyle() + |
|
'</style>\n' + |
|
html; |
|
} |
|
|
|
var cachedPrintStyle; |
|
function printStyle() { |
|
if (!cachedPrintStyle) { |
|
cachedPrintStyle = page.evaluate(function() { |
|
var p = Array.prototype; |
|
return p.filter.call(document.styleSheets, function(s) { |
|
return p.some.call(s.media, function(m) { return m === 'print'; }); |
|
}).map(function(s) { |
|
return p.map.call(s.rules, function(r) { return r.cssText; }).join('\n'); |
|
}).join('\n'); |
|
}); |
|
} |
|
return cachedPrintStyle; |
|
} |
|
|
|
page.paperSize = paperSize; |
|
|
|
function checkReadyState() { |
|
var readyState = page.evaluate(function() { return document.readyState; }); |
|
if (readyState === 'complete') { |
|
onPageReady(); |
|
} else { |
|
setTimeout(checkReadyState); |
|
} |
|
} |
|
|
|
function onPageReady() { |
|
page.render('/dev/stdout', { format: 'pdf' }); |
|
phantom.exit(); |
|
} |
|
|
|
checkReadyState(); |
Hi @Sri-K
I can see that the source files here are a bit short on context. I'll try to elaborate a bit:
All the files are in my example locates in
/lib/phantomjs/
under the Rails root.The idea is that you call
Phantomjs.pd(html, request)
wherehtml
is a string containing the HTML contents of a page, andrequest
is anActionDispatch::Request
instance.It is assumed that the HTML is something that would otherwise have been the response for some URL, so there might be relative references in the HTML to e.g. images. Because of this, we need to pass the URL to Phantomjs. Also, as additional resources needed for the rendering might be protected by authorisation or otherwise be session dependent, we also need to be able to generate a session cookie. Both the session-id and URL can be found on the
request
object, and that's why we pass that to thePhantomjs.pdf()
method.Notice: This has nothing to do with the Prawn gem, which is another approach to PDF generation. See https://github.com/prawnpdf/prawn#should-you-use-prawn
This is more an alternative to Wicked-PDF, which we were using but had some issues with at the time. There might be better options available today for converting HTML to PDF in Ruby.