CSS issues with html-pdf

2019-08-29 04:26发布

I want to use html-pdf to save a quote made with sails, ejs, and angular into a pdf to send it to the customer.

An .ejs file (view folder) and its assign .js controller (assets folder) allows the user to create the quote, select the customer, add products, and finally calculate the total of the quote. All the data are bound with angular. I use bootstrap.min.css and importer.css files for my CSS and mostly the Bootstrap grid for my display.

When to quote is ready, I have a 'save as PDF' button, which removes (with ng-if) all the sections that the customer does not need to see on its quote, and my assets controller calls an api controller which generates the PDF.

Here is my assets/js/controller code :

$scope.printPdf = function() {

    $http.post('/page/create-pdf', {
        printView: document.getElementById('printPdfSection').innerHTML,
        quoteNumber: $scope.createdQuote.createdAt,
    })
    .then(function onSuccess(sailsResponse){
        console.log('PDF CREATED');
    })
    .catch(function onError(sailsResponse){
        console.error('PDF ERROR :', sailsResponse);
    });
};

And here is my api/controllers code :

printPdf: function(req, res) {

    var pdf = require('html-pdf');
    var moment = require('moment');
    var fs = require('fs');

    var quoteNumber = moment(req.param('quoteNumber')).format('YYMMDDHHmm');
    var html = req.param('printView');
    var options = { 
        format: 'Letter', 
        border: {
            "top": "1in",            // default is 0, units: mm, cm, in, px
            "right": "1in",
            "bottom": "1in",
            "left": "1in"
        },
        base: req.protocol + '://' + req.get('host'),
    };

    pdf.create(html, options).toFile('./assets/pdfs/'+ quoteNumber +'.pdf', function(err, res) {
        if (err) return console.log(err);
        console.log(res);
    });
}

I have a picture which shows up OK so the base option should be able to get my css but it isn't... Any ideas ?

EDIT :

Well it's ok I fixed it. I'm sending my CSS before my html and now it work.

        var myCSS = '<link rel="stylesheet" href="/styles/bootstrap.min.css"><link rel="stylesheet" href="/styles/importer.css">';

        $http.post('/page/create-pdf', {
            printView: myCSS + document.getElementById('printPdfSection').innerHTML,
...

I do have 2 issues now...

1- The Grid is showing ok but my div tags has a border and background colour and they are not showing, I think I saw something about @media but I never used it so I don't really know what is wrong here.

2- All being fine (pictures and grid layout display) in the PDF, I added the id="pageHeader" in my div tag of the section I'd like to use as header. I tried it out and now the section is not showing the image nor the grid display... My html is showing right in my browser, so do I have to do something else with the pageHeader id for it not to mess my CSS ?

1条回答
Luminary・发光体
2楼-- · 2019-08-29 05:04

I can help you out with your first issue. "@media print" is a CSS tag that applies only when a document is sent to be printed, basically what you can see on your print preview on your browser. The PDFs created by html-pdf are considered like that, as a printable document rather than an HTML document.

I fixed this by going to the bootstrap.css file and manually edit it myself. You just need to find the @media print tag that has a "*" tag right below it.

It looks like this:

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

There, you can see that it sets the background-color and color as !important to the whole document. Remove the universal (*) tags and you'll be able to use your own custom CSS for backgrounds and font-colors.

查看更多
登录 后发表回答