Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put variables into PhantomJS generated HTML headers for PDF conversion?

I have a huge issue here. I want to auto-generate PDFs files from HTML templates with custom headers and footers, using express.js, phantomjs and EJS.

I don't have any problems putting any "hardcoded" HTML strings in PhantomJS generated headers of footers (they work):

footer: {
    height: "3cm",
    contents: ph.callback(function(pageNum, numPages) {
        return "<div style='padding: .2em; font-size: 10pt;border-top: 1px solid #ccc; color: #999;'> FOOTER <span style='float:right'> Página " + pageNum + " / " + numPages + "</span></div>";
    })

But, whenever I try to customize it programmatically:

var pdfHeader = ejs.compile(fs.readFileSync(path.join('server/components/mail/html-templates/pdf-header.html'), 'utf8'));
    pdfHeader = pdfHeader({info: info});

    header: {
        height: "3cm",
        contents: ph.callback(function(pageNum, numPages) {
            if (pageNum == numPages) {
                return "";
            }
            return pdfHeader;
        })
    },

It fails and gives me this message:

phantom stdout: SyntaxError: Unexpected EOF

How can I put into the header a custom HTML code with some custom data?

like image 423
Inberg Marcano Avatar asked Oct 31 '22 14:10

Inberg Marcano


1 Answers

So there are a couple of things with the phatomjs contents callback.

  1. The function in ph.callback has its own context. So it can't see variables outside of its own scope. See https://github.com/amir20/phantomjs-node/issues/224. The example that @zgotts provided in the Git issue worked for me.

    var headerHtml = ejs.compile(fs.readFileSync(path.join('server/components/mail/html-templates/pdf-header.html'), 'utf8'));
    var createHeader = function(html) {
            return function (pageNum, numPages) {
                //console.log(html);
                console.log('Header set!');
                return '%HTML%';
            }.toString().replace(/%HTML%/, html);
        };
    
        renderSession.createPage()
            .then(function(_page) {
                page = _page;
                var file = 'file.pdf';
    
                page.property('paperSize', {
                    format: 'Letter',
                    header: {
                        height: "3.75cm",
                        contents: renderSession.callback(createHeader(headerHtml))
                    }
                })
            });
    
  2. The second issue that I found was that it wouldn't work if there were line breaks in the ejs file. As a note also, styles don't apply so you will have to add styling inline if there is any.
like image 199
jth_92 Avatar answered Nov 12 '22 16:11

jth_92