Symfony HTML to PDF with AJAX call

Damien Lebosse
2 min readDec 26, 2020

--

Show a PDF through an AJAX call to Symfony API with dompdf or wkhtmltopdf

I recently had to develop a website with Symfony and React. One of the feature I had to do was to generate a PDF with Symfony and give it back to the front. I found lot of tutorials about dompdf or wkhtmltopdf for symfony but nothing about how to handle the fact that my front wasn’t Twig but React !

With DomPDF

I first gave a try with domPDF which is a very good library if you want to generate quick PDF.

Follow the instructions into their github to install it the way you want.

Then here is the exemple to create a PDF as you might already find on other tutorials :

$domPdf = new Dompdf();$html = $this->renderView('pdf/my_pdf.html.twig');$domPdf->loadHtml($html);
$domPdf->setPaper('A4', 'portrait');
$domPdf->render();
$domPdf->stream('my-pdf.pdf');

Stream will create an answer which is used by the front-end. For example, in JS once you called the API, you will exploit the PDF response :

apiCallToYourRoute.then((res) => {
if (res.data) {
const newBlob = new Blob([res.data], { type: 'application/pdf' });
const downloadUrl = window.URL.createObjectURL(newBlob);
window.open(downloadUrl);
}
});

If you do this you see a PDF opening in your browser with … a white page :(

You just have to change one thing from the previous php code :

$domPdf->stream('transport.pdf', [
'compress' => false,
]);

With wkhtmltopdf

My second try was with wkhtmltopdf because dompdf wasn’t enough for what I wanted to do. I needed to use some CSS 3.0 features for example. I let you to make some research, you will find lot of pros and cons about those both libraries.

You can use knpSnappyBundle or KnpSnappy (with the binary). I used the second method but feel free to do as you want.

$pdf = new Pdf($rootPath.'/vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64');$html = $this->renderView('pdf/my_pdf.html.twig');

$pdf->getOutputFromHtml($html);
return new Response(
$pdf->getOutputFromHtml($html),
200,
array(
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="my-pdf.pdf"',
)
);

And again, you will have an answer which is used by the front-end. The same js code example:

apiCallToYourRoute.then((res) => {
if (res.data) {
const newBlob = new Blob([res.data], { type: 'application/pdf' });
const downloadUrl = window.URL.createObjectURL(newBlob);
window.open(downloadUrl);
}
});

Once more, a PDF will be opened in your browser with … a white page again !

Like we did with dompdf, you need to add a little option so the library doesn’t compress the PDF returned :

$this->pdf->setOptions([
'no-pdf-compression' => true,
]);

Hope this helps you and don’t hesitate to comment and help each other !

--

--

Damien Lebosse
Damien Lebosse

Written by Damien Lebosse

⚡ Full-Stack Engineer / Developer @ ZOL — Lyon, France 🙏🏻 Humanist and Technologist

No responses yet