vinay saini
vinay saini

Reputation: 375

TCPDF convert inline SVG with html into PDF

I am using TCPDF to convert html into PDF.

    $pdf = new TCPDF();
    $pdf->SetPrintHeader(false);
    $pdf->SetPrintFooter(false);
    $pdf->AddPage();       

    $html  = '<div>Some random html </div>';        
    $pdf->writeHTML($html, true, false, true, false, '');
    $pdf->Output('/pdf/output.pdf','F');

It works like a charm.

But I have a case when (Dynamic) html has SVG inline code also. So I need to convert this html which has SVG into PDF. But it does not work. Below is my code.

    $pdf = new TCPDF();
    $pdf->SetPrintHeader(false);
    $pdf->SetPrintFooter(false);
    $pdf->AddPage();       

    $html  = '<div>Some random html <div style="width: 100px;"><svg viewBox="10 0 80 80">
    <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:purple" />
    <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" />
    <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" />
    Sorry, your browser does not support inline SVG. 
    </svg></div> </div>';        
    $pdf->writeHTML($html, true, false, true, false, '');
    $pdf->Output('/pdf/output.pdf','F');

So in this case the generated PDF has all the html printed in pdf but in place of SVG it says "Sorry, your browser does not support inline SVG".

Is there any possible way to generate PDF from html containing SVG?

Update I found http://www.pdfy.net/ this website can convert html based svg into PDF. Any idea how they are doing it?

EDIT 1:

Okay Now I found that mPDF have supports for inline SVG. And it has really great support for it. But mPDF have it's own problem of very less support for basic css. For Eg. Position absolute, float are not supported very well.

So again I am back with the same problem with additional requirement. A library which supports conversion of html with inline svg to PDF and it also supports all basic CSS.

Upvotes: 5

Views: 21072

Answers (4)

Raphael Ochsenbein
Raphael Ochsenbein

Reputation: 34

One solution with TCPDF could be, that it is possible to place svg's as source attribute in HTML inlined.

If you look at the example 06 of TCPDF, that's how svg is inlined in $writeHTML: https://github.com/tecnickcom/TCPDF/blob/95c5938aafe4b20df1454dbddb3e5005c0b26f64/examples/example_006.php#L112

With that you could either parse your html string, or change the source to match the syntax that will work in both browser and pdf (see https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web#The_quick_way_).

Example with an SVG in image set as src:

$iconSpecialNeedsWhite = '/system/modules/assets/images/wheelchair-white.svg';
$pdf->writeHTMLCell($w[$i], $h, '', '', '<table cellpadding="6"><tr><td align="center"><img src="'.$iconSpecialNeedsWhite.'" height="12"/></td></tr></table>', 1, 0, 1, true, 'C', true);

Upvotes: 0

Peter
Peter

Reputation: 1348

The best way I think is to use ImageSVG "inside" your HTML code, using the tcpdf method TAG.

For the SVG, here is an example:

 // Create the SVG on a string
$svgString .= "<svg width=\"100\" height=\"100\">";
$svgString .= "<circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"green\" stroke-width=\"4\" fill=\"yellow\" />";
$svgString .= "</svg>";

// Prepare the parameters for the function
$params = $pdf->serializeTCPDFtagParameters(array('@' . $svgString, $x='', $y='', $w='', $h='', $link='http://www.tcpdf.org', $align='', $palign='', $border=1, $fitonpage=false));

// Declare the tag with the name of the function yu want to call and add the parameters
$tcpdf_start1 .= '<tcpdf method="ImageSVG" params="'.$params.'" />';

 // Prepare your HTML code inside of which you just insert the special TAG
$code_html  = "";
$code_html .= "<h1>My first SVG</h1>";
$code_html .= "<table border=\"1\">";
$code_html .= "<tr><td style=\"text-align: center;\">Top</td></tr>";
$code_html .= "<tr><td>".$tcpdf_start1."</td></tr>";
$code_html .= "</table>";

// Basicly produce your PDF with the parameters of your choice.
$pdf->writeHTML($code_html, $ln, $fill, $reseth, $cell, '');

Upvotes: 1

Amzad Khan
Amzad Khan

Reputation: 121

@Soroush

You have missed out only one statement which I am adding in your code, hope that will help, I tested and its working 100%.

    $svgString = '<svg viewBox="10 0 80 80">
    <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:purple" />
    <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" />
    <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" />
    Sorry, your browser does not support inline SVG. 
    </svg>';

    $pdf->ImageSVG('@' . $svgString, $x=15, $y=30, $w='', $h='',         $link='http://www.tcpdf.org', $align='', $palign='', $border=1, $fitonpage=false);  
    $pdf->Write(0, $txt='', '', 0, 'L', true, 0, false, false, 0);
    $pdf->Output('networth-and-cashflow-document.pdf', 'D'); // This will download PDF

Upvotes: 1

Soroush
Soroush

Reputation: 917

Solution #1- Save svg to file

You can save your svg part of your HTML into a file. Then you can add the svg image into your PDF with $pdf->ImageSVG() function as it says here.

$pdf->ImageSVG($file='path/to/testsvg.svg', $x=15, $y=30, $w='', $h='', $link='http://www.tcpdf.org', $align='', $palign='', $border=1, $fitonpage=false);

$pdf->Write(0, $txt='', '', 0, 'L', true, 0, false, false, 0);

Solution #2- Add inline svg

You can store your inline svg into a variable (for example $svgString):

$svgString = '<svg viewBox="10 0 80 80">
<ellipse cx="240" cy="100" rx="220" ry="30" style="fill:purple" />
<ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" />
<ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" />
Sorry, your browser does not support inline SVG. 
</svg>';

Then you can add your $svgString variable to PDF like this:

$pdf->ImageSVG('@' . $svgString, $x=15, $y=30, $w='', $h='', $link='http://www.tcpdf.org', $align='', $palign='', $border=1, $fitonpage=false);

$pdf->Write(0, $txt='', '', 0, 'L', true, 0, false, false, 0);

Upvotes: 12

Related Questions