Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PhantomJS: external CSS is ignored in rendered pdf

I am using nodejs with phantom module to generate pdf from html.

First, I read html template and populate it with data and than render it as pdf. I would like bootstrap css to be used to style the page, however styling is inored whatsoever in resulting pdf file.

here is my javascript code:

var phantom = require('phantom');

var htmlTemplate;

fs = require('fs')
fs.readFile('template.html', 'utf8', function (err,data) {

  var htmlTemplate = populateTemplate(data, body)

    phantom.create(function(ph){
      ph.createPage(function(page) {

          page.set("paperSize", { 
            format: "A4", 
            orientation: 'portrait', 
            margin: '1cm' 
          });  

          page.setContent(htmlTemplate, "", function(){
              page.render("../userdata/test.pdf", function(){
                console.log("page rendered");
                ph.exit();
              }); 
          });

      })
    });

});

and the html template (simplyfied) looks like this:

<!DOCTYPE html>
<html>
    <head>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.5/paper/bootstrap.min.css", rel="stylesheet">
        <meta charset="utf-8">
    </head>
    <body>

        <div class="container">
            <h1>Title</h1>
            <%NAME%>
        </div>   
    </body>
</html> 

All the markup is rendered to page, but no styling. Even if I use local css file or include style in <style> element in the head, the results are the same

like image 804
Zbynek Avatar asked Dec 09 '15 15:12

Zbynek


2 Answers

If some of Bootstrap's styles are being applied, but not others, you can assume that it's a conflict with the Bootstrap CSS library and printing. Certain classes, especially the grid classes such as col-md- don't always properly scale or render on a printed page. If you're having trouble getting the correct grid layout to print, you could try fixing these classes. For example:

  • Replace every col-md-6 to col-xs-6.

Thanks to user Sonam for pointing this out.

I'd also recommend taking a look at the rest of this thread on how to create printable Twitter Bootstrap page.

However, if NO bootstrap styles are being applied, the source of the problem is likely somewhere between loading the page's content, and converting that page into a .pdf document. In my experience, it's always a little tricky to debug PDF rendering libraries, since it's hard to see where in the flow your process is going wrong. There are a few things you could try:

You might be calling .render() before the page has loaded the external resources (aka bootstrap). Take a look at this similar question about rendering PDFs in Phantom. The solution might be to add a timeout/delay to ensure the page's external CSS has been loaded.

  • page.set('content') dosen't work with dynamic content in phantomjs

I should add - there are a few other reason's that might cause the Phantom.js rendered page to fail to load in external resources. Make sure you've got Phantom.js set up correctly, especially the localToRemoteUrlAccessEnabled key. See the below StackOverflow question for reference:

  • Phantom-node module unable to load external resources
like image 182
Alex Johnson Avatar answered Oct 27 '22 01:10

Alex Johnson


When you render PDF, PhantomJs use css rules for "@media print"

in Bootstrap exist rules for "@media print"

@media print{
  *,
  *:before,
  *:after {
    color: #000 !important;
    text-shadow: none !important;
    background: transparent !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
  }

....

this css rules can overwrite you css rules, make ignore any background, any font color and more other.

I fixed this situation making copy of bootstrap css file without "@media print"section

like image 41
Vencendor Avatar answered Oct 26 '22 23:10

Vencendor