Dompdf not generating pdf properly from SVG

11,696

Solution 1

This is not a matter of your css or html. Basically this comes down to dompdf rendering your your svg differently then the browser. dompdf is rendering each group/item within the svg xml individually into the displayed image, whereas the browser is defining each group/item as part as the whole image before rendering.

Your best options here are:

  1. using PNG's instead of SVG's
    • this would definitely be the quickest solution if you're dealing with a small number of images, but if you're dealing with many images or auto-generated images this could become time consuming.
  2. altering your SVG XML to fit fit the way dompdf is rendering.
    • this could solve your issue with dompdf rendering, but could lead to issues with browser rendering, and could also be time consuming based on number of images and source.
  3. Opening an issue with dompdf
    • Probably the best long term solution, but the turn around time is unknown.
  4. Alter the dompdf source code to solve your issue

Solution 2

I searched FOREVER until I finally came up with my own solution. I thought I should share in case it could be useful to anyone else. If you are using PHP the best solution to inline SVG images (for me) is to output it using BASE64_ENCODE() on the actual svg, then wrapping it in an image using the src as follows:

$svg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 36 36" class="circular-chart">
    <path class="circle-bg"
          stroke-width="1"
          fill="none"
          stroke="#ddd"
          d="M18 2.0845
             a 15.9155 15.9155 0 0 1 0 31.831
             a 15.9155 15.9155 0 0 1 0 -31.831"
          />
</svg>';

$html = '<img src="data:image/svg+xml;base64,'.base64_encode($svg).'"  width="100" height="100" />';

The only issue you might find is weird dimensions on the actual image. You will have to mess with it on the PDF output to make sure it displays as desired. I needed to remove the width and height of the actual SVG to make sure it was sizing correctly. Again hope this helps!

Solution 3

I have generated some demo PDF with Svg's and it worked fine, you just need to add inline width and height to the image tag like this

<img width="400" src="yourpath/au.svg" />

P.S Do not set width in % just write like this width="400" inline img tag

Solution 4

It works for me:

the magic is base64_encode

Controller:

$qrCode = base64_encode(QrCode::format('png')->size(150)->generate('hello qrcode'));

$pdf->loadView('myfiles.pdf', compact('qrCode'));

view:

<img src="data:image/png;base64, {{ $qrCode }}">
Share:
11,696
тнє Sufi
Author by

тнє Sufi

Updated on June 17, 2022

Comments

  • тнє Sufi
    тнє Sufi almost 2 years

    I am having trouble generating pdf keeping design with SVG content. SVG is linked inside html, and using html to generate pdf. But not working properly.

    This is the code:

    $dompdf = new DOMPDF();
    
    //HTML Content
    $html = <<<EOD
    <html>
        <head>
            <style type="text/css">
                html {
                    margin: 1%;
                    padding: 0;
                }
                .header,
                .footer {
                    width: 100%;
                    text-align: center;
                    position: fixed;
                    font-size: 26px;
                }
                .header {
                    top: 0px;
                }
                .footer {
                    bottom: 18px;
                }
                .center {
                    margin: 0 auto;
                }
                .divTable{
                    display: table;
                    width: 100px;
                    text-align: center;
                    margin: 0 auto;
                }
                .divTableRow {
                    display: table-row;
                }
                .divTableHeading {
                    margin: 0 auto;
                }
                .divTableCell, .divTableHead {
                    display: table-cell;
                    padding: 0 33px;
                }
                .bottom .divTableCell {
                    padding-top: 30px;
                }
                .divTableHeading {
                    display: table-header-group;
                    font-weight: bold;
                }
                .divTableFoot {
                    display: table-footer-group;
                    font-weight: bold;
                }
                .divTableBody {
                    display: table-row-group;
                }
                div.img-border img {
                    border: 2px solid #eb0089;
                }
            </style>
        </head>
        <body>
            <div class="center">
                <div class="divTable top">
                    <div class="divTableBody">
                        <div class="divTableRow">
                            <div class="divTableCell" style="padding-left:0px;"><div class="img-border"><img src="$small_image"></div></div>
                            <div class="divTableCell"><div class="img-border"><img src="$small_image"></div></div>
                            <div class="divTableCell" style="padding-right:0px;"><div class="img-border"><img src="$small_image"></div></div>
                        </div>
                    </div>
                </div>
                <div class="divTable bottom">
                    <div class="divTableBody">
                        <div class="divTableRow">
                            <div class="divTableCell" style="padding-left:0px;"><div class="img-border"><img src="$large_image"></div></div>
                            <div class="divTableCell" style="padding-right:0px;"><div class="img-border"><img src="$large_image"></div></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="footer">
                $customer_title - $customer_order_number
            </div>
        </body>
    </html>
    EOD;
    
    //PDF Options
    $dompdf->set_option( 'dpi' , '300' );
    $dompdf->load_html($html);
    $dompdf->setPaper('A4', 'portrait');
    $dompdf->set_option( 'isRemoteEnabled', true );
    $dompdf->render();
    
    $output = $dompdf->output();
    file_put_contents('path-to-pdf/new.pdf);
    

    Here is the html view (including svg): view here

    This is how the generated pdf looks like: enter image description here

    However, when I use PNG image, it works fine. This is how the generated pdf looks like (using png): enter image description here

    Not sure what I am doing wrong!

  • тнє Sufi
    тнє Sufi about 6 years
    Tried with the inline width and height. Still the same result.
  • Frank
    Frank about 4 years
    Thanks so much !
  • Omer
    Omer about 3 years
    Worked for me in laravel dompdf 😀 thanks
  • Pezhvak
    Pezhvak over 2 years
    for me i had to save the svg file and load it in the img tag in order for it to work in Laravel.