7

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

Zbynek
  • 5,673
  • 6
  • 30
  • 52

2 Answers2

8

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.

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:

Community
  • 1
  • 1
Alex Johnson
  • 1,504
  • 13
  • 20
  • thanks, the issue seems to be bootstrap css. Some styles are printed, but some are ignored. – Zbynek Dec 10 '15 at 09:48
  • Can you tell which classes and styles from Bootstrap are being applied? That would tell me a little more on how to fix the problem. I know Bootstrap isn't always known for being print-friendly. Here's a related thread on printing from bootstrap: http://stackoverflow.com/questions/12302819/how-to-create-a-printable-twitter-bootstrap-page – Alex Johnson Dec 10 '15 at 14:52
  • 2
    the grid system does not get applied - `row` and `col-xx-y` – Zbynek Dec 10 '15 at 15:25
  • Thanks - solved it. What helped was to replace `col-md-` for `col-xs-` classes, as suggested by the SO post. Include it in your answer and I will accept it as solution. – Zbynek Dec 10 '15 at 15:55
  • Glad to hear! Printing with Node.js and Phantom can be tricky, so I'm glad you worked it out. I've updated my original answer to include the solution that you discovered. I've also included my previous suggestions, just in case future users with similar problems/symptoms come to this question through Google. – Alex Johnson Dec 10 '15 at 17:10
1

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

Vencendor
  • 132
  • 1
  • 4