2

In Laravel 8 app I make pdf file with browsershot and it mostly works ok for me, except case my data contains several pages, I have 2 problems :

  1. I do not see header which I define with footer (code below) : https://i.stack.imgur.com/nujuf.jpg

  2. I see last line of any page is cut off : https://i.stack.imgur.com/63o1k.jpg

I do it with code passing into control html content and generated filename:

        $filename_to_save = $option_output_filename . '.' . $option_output_file_format;
        $save_to_file     = 'generate_profile_card_' . Session::getId() . '_' . $filename_to_save;

        $today_date = getCFFormattedDate(Carbon::now(config('app.timezone')));
        $site_name  = config('app.name', '');

        $footerHtml = '<div class="card-text d1" style="background-color: #ffffff !important; width: 100%; margin : 0 !important;">
            <table style="width: 100%; font-family: \'system-ui\'; font-size: 12px !important; padding : 20px 0 0 0 !important; margin: 0 !important;
                color:#101010 !important; ;" >

                <tbody>';
        $footerHtml .= '
                <tr>
                    <td style="width:100%; border:0; border-top: 8px solid #c1c1c1; padding: 0; WWmargin: 21px 32px 2px 32px !important;" colspan="3">
                        <table style="width:100%;  ">
                            <tr>
                                <td style="width:30%;" class="d-2">
                                    Printed on: ' . $today_date . '
                                </td>
                                <td style="width:30%; " >
                                    <span class="pageNumber"></span><span>out of</span><span class="totalPages"></span>
                                </td>
                                <td style="width:40%;" >
                                    ' . $site_name . '
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
';

        $footerHtml .= '            </tbody></table>
        </div>';

        if (strtolower($option_output_file_format) == 'pdf') {
            Browsershot::html(htmlspecialchars_decode($this->requestData['adCardContent']))
                       ->showBrowserHeaderAndFooter()
                       ->headerHtml('<div style="height:280px !important; background : maroon !important; ">Ad Card</div>')
                       ->footerHtml($footerHtml)
                       ->showBackground()
                       ->margins(20, 10, 20, 10)
                       ->setOption(
                           'addStyleTag', // I inject some tailwindcss classes
                           json_encode([
                               'content' => '

.d1 {
    --tw-border-opacity: 1;
    border-color: rgba(220, 38, 38, var(--tw-border-opacity));
    border-width: 2px;
}

.d2 {
    --tw-border-opacity: 1;
    border-color: rgba(245, 158, 11, var(--tw-border-opacity));
    border-width: 4px;
}



    h3 {
       font-size: 32px;
       padding:4px;
    }
    h4 {
       font-size: 24px;
        padding:3px;
    }

.md:h-4/6 {
    height: 66.666667%;
}

.sm:h-4/5 {
    height: 80%;
}

.text-left {
    text-align: left;
}
.shadow-lg {
    --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}

.p-2 {
    padding: 0.5rem;
}
.px-6 {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
}
.py-4 {
    padding-top: 1rem;
    padding-bottom: 1rem;
}

.mb-5 {
    margin-bottom: 1.25rem;
}

.max-h-screen {
    max-height: 100vh;
}
.justify-between {
    justify-content: space-between;
}

.card-text {
    background : maroon !important;
    border: 4px dotted red !important;
}

.pageNumber {
    background : yellow !important;
}

.totalPages {
    background : blue !important;
}

.flex-col {
    flex-direction: column;
}
.flex {
    display: flex;
}

.modal_container {
    color: green !important;
    border-radius: 0.5rem;
    border-width: 2px;
    padding: 0.5rem;
    border: 4px dotted blue !important;
}


.overflow-y-auto {
    overflow-y: auto;
    border: 4px dotted green !important;
}


.float-left {
    float: left;
}

.big_badge {
    border-color: rgba(209, 213, 219, var(--tw-border-opacity));
    border-radius: 0.5rem;
    border-bottom-width: 2px;
    display: flex;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 2.25rem;
    margin: 0.5rem;
    padding: 0.75rem;
}

.mt-3 {
    margin-top: 0.75rem;
}

.pt-3 {
    padding-top: 0.75rem;
}'
                           ])
                       )
                       ->save($save_to_file);
            \Response::download(
                $save_to_file,
                $save_to_file,
                array('Content-Type: application/octet-stream', 'Content-Length: ' . $option_output_file_format)
            );

            return response()->download($save_to_file, $filename_to_save)->deleteFileAfterSend(true);

in composer.json :

"laravel/framework": "^8.12",
"spatie/browsershot": "^3.40",

How can it be fixed ?

MODIFIED : I still have these problems with pdf generating : I uploaded example on live server. Please open http://tads-back.my-demo-apps.tk/admin/ads/2/edit at login page credentials are already filled. Just click Login By the link above modal page will be opened and please click on “Generate" button. By default pdf file will be generated with problem I show in printscreens of my topic. I used this library with bootstrap 4.5 and did not have such problems. Also in the description of https://github.com/spatie/browsershot I did not see any errors description with page footer.

I my code I show how I set tailwind classes in

->setOption('addStyleTag'
    ...

    

Maybe tailwind has some rendering features which I missed?

Thanks!

mstdmstd
  • 2,195
  • 17
  • 63
  • 140
  • 1st please put your html code in a view and pass it to package. try return the view see if it renders ok in browser. – MHIdea May 31 '21 at 14:15
  • Did you try to generate pdf by given link? In modal dialog there is rendering html and in generated pdf ALL is rendered ok, except 2 points I wrote above – mstdmstd May 31 '21 at 14:55
  • 1
    check this file's header and footer: https://drive.google.com/file/d/12kd6gXYSAqp91NVYGUndh7uRH4gXIpVF/view?usp=sharing Is it what you want? – MHIdea Jun 01 '21 at 19:06
  • Yes, I really need very similar. How this page was generated and what it has in common with my laravel's app problem ? – mstdmstd Jun 02 '21 at 14:33
  • That seems not the point. I do not have problems with rendering page in html with tailwind. But I have problems when browsershot libray render this page. Did you see browsershot library? – mstdmstd Jun 03 '21 at 09:57

1 Answers1

4

browsershot uses puppeteer package. According to puppeteer, footer and header are different htmls. So if you've included any css library like tailwindcss or bootstrap in the main page you intend to save, it doesn't mean they will be loaded for footer and header. in case of tailwindcss, you need to make sure any css classes used in footer and header are included in production build as postcss will eliminate unused classes to reduce final build assets.

To get a correct positioning and sizing you need to play with margins in browsershot and also correct styling of footer and header. As an example you need to increase vertical margin for this footer and font size in footer:

footer.blade.html:

<style>
    * {
        box-sizing: content-box;
    }

    footer {
        width: 100%;
        border: 1px solid yellowgreen;
        display: flex;
        flex-direction: row;
    }

    footer>div {
        color: blue;
        width: 100%;
        height: 20px;
        font-size: 10rem;
        text-align: center;
    }
</style>
<footer>
    <div>
        Printed on: {{$today_date}}
    </div>
    <div>
        {{$site_name}}
    </div>
    <div>footer</div>
</footer>

Then load footer html and use it with correct margins:

    $footerHtml =  view('footer', compact(['today_date', 'site_name']))->render();
        Browsershot::html($content)
            ->showBrowserHeaderAndFooter()
            ->headerHtml(view('header')->render())
            ->footerHtml($footerHtml)
            ->showBackground()
//->margins(20, 10, 20, 10) doesn't work with above footer html.
            ->margins(30, 10, 30, 10)
            ->save($save_to_file);

MHIdea
  • 806
  • 3
  • 8
  • You suppose that content in in footerHtml must be wrapped with “
    ...
    >” ? Could you please point where from this rule ? I did not find anything... I tried to make it (and modified ->margins(30, 10, 30, 10) ), but anyway I got problems with last line in footer: https://imgur.com/a/cKpv7yR
    – mstdmstd Jun 06 '21 at 03:33
  • @mstdmstd It doesn't have to be footer tag. It can be div. Did you test vertical margin to bigger values like 60 or 100? – MHIdea Jun 06 '21 at 11:21
  • Sure, I tried to change vertical margin - the sane problem that last line is cut off, just as on my last pritscreen – mstdmstd Jun 06 '21 at 14:29
  • As you saw my sample file, it was ok with above method. So to check your case more info is needed. Let me know how we can check. There must be something wrong somewhere. – MHIdea Jun 07 '21 at 18:50