Question

I am working on a Symfony 1.4 project. I need to make a PDF download link for a (yet to be) generated voucher and I have to say, I am a bit confused. I already have the HTML/CSS for the voucher, I created the download button in the right view, but I don't know where to go from there.

No correct solution

OTHER TIPS

Use Mpdf to create the pdf file
http://www.mpdf1.com/

+1 with wkhtmltopdf

I'd even recommand the snappy library. If you use composer, you can even get the wkhtmltopdf binaries automatically

Having used wkhtmltopdf for a while I've moved off it as 1) it has some serious bugs and 2) ongoing development has slowed down. I moved over to PhantomJS which is proving to be much better in terms of functionality and effectiveness.

Once you've got something like wkhtmltopdf or PhantomJS on your machine you need to generate the HTML page and pass that along to it. I'll give you an example assuming you use PhantomJS.

Initially set what every request parameters you need to for the template.

$this->getRequest->setParamater([some parameter],[some value]);

Then call the function getPresentation() to generate the HTML from a template. This will return the resulting HTML for a specific module and action.

$html = sfContext::getInstance()->getController()->getPresentation([module],[action]);

You'll need to replace the relative CSS paths with a absolute CSS path in the HTML file. For example by running preg_replace.

$html_replaced = preg_replace('/"\/css/','"'.sfConfig('sf_web_dir').'/css',$html);

Now write the HTML page to file and convert to a PDF.

$fp = fopen('export.html','w+');
fwrite($fp,$html_replaced);
fclose($fp)
exec('/path/to/phantomjs/bin/phantomjs /path/to/phantomjs/examples/rasterize.js /path/to/export.html /path/to/export.pdf "A3");

Now send the PDF to the user:

$this->getResponse()->clearHttpHeaders();
$this->getResponse()->setHttpHeader('Content-Description','File Transfer');
$this->getResponse()->setHttpHeader('Cache-Control','public, must-revalidate, max-age=0');
$this->getResponse()->setHttpHeader('Pragma: public',true);
$this->getResponse()->setHttpHeader('Content-Transfer-Encoding','binary');
$this->getResponse()->setHttpHeader('Content-length',filesize('/path/to/export.pdf'));
$this->getResponse()->setContentType('application/pdf');
$this->getResponse()->setHttpHeader('Content-Disposition','attachment; filename=export.pdf');

$this->getResponse()->setContent(readfile('/path/to/export.pdf'));
$this->getResponse()->sendContent();

You do need to set the headers otherwise the browser does odd things. The filename for the generated HTML file and export should be unique to avoid the situation of two people generating PDF vouchers at the same time clashing. You can use something like sha1(time()) to add a randomised hash to a standard name e.g. 'export_'.sha1(time());

Use wkhtmltopdf, if possible. It is by far the best html2pdf converter a php coder can use.

And then do something like this (not tested, but should be pretty close):

public function executeGeneratePdf(sfWebRequest $request) 
{
    $this->getContext()->getResponse()->clearHttpHeaders();

    $html = '*your html content*';
    $pdf = new WKPDF();
    $pdf->set_html($html);
    $pdf->render();

    $pdf->output(WKPDF::$PDF_EMBEDDED, 'whatever_name.pdf');

    throw new sfStopException();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top