问题
Long story short
With knp-snappy-bundle
I can't generate a header in the PDF, while I can actually generate a footer.
Is it a bug, a feature, or I'm doing something wrong?
Details
1. Environment
I'm testing the knp-snappy-bundle
, I've also installed the wkhtmltopdf
binary from h4cc
. This is part of my composer.json
:
"h4cc/wkhtmltopdf-amd64": "^0.12.3",
"knplabs/knp-snappy-bundle": "^1.5",
The resulting binary of wkhtmltopdf
says this:
$ vendor/bin/wkhtmltopdf-amd64 --version
wkhtmltopdf 0.12.3 (with patched qt)
2. Without headers or footers, it works
I've setup a controller that uses the knp-snappy-bundle
and it works:
This is my PdfController
:
public function downloadPdfAction( string $docName ) : Response
{
$pdf = $this->getPdf( $docName );
return new PdfResponse( $pdf, $this->getFilename( $docName ) );
}
private function getPdf( string $docName ) : string
{
$html = $this->renderView( 'AppBundle:documents:' . $docName . '.pdf.twig' );
$options = [];
$generator = $this->getPdfGenerator();
$pdf = $generator->getOutputFromHtml( $html, $options );
return $pdf;
}
private function getPdfGenerator() : Pdf
{
$generator = $this->get( 'knp_snappy.pdf' );
return $generator;
}
It basically:
- Has a
downloadPdf
action that- Gets a PDF document by its name, passed in as a parameter. In this example we'll use
'helloWorld'
.
- Gets a PDF document by its name, passed in as a parameter. In this example we'll use
- Returns a new
Response
created with the content of the PDF, using thePdfResponse
class in the bundle.
- Returns a new
- To get the PDF
- it renders a view with the
twig
engine.
- it renders a view with the
- gets the service (splitted into another function
getPdfGenerator()
).
- gets the service (splitted into another function
- uses the service to
getOutputFromHtml()
with no options passed-in.
- uses the service to
This is my helloWorld.pdf.twig
:
<html>
<body>
<div class="pdfPageBody">
<h1>
Hello, World!
</h1>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</body>
</html>
And here it is the resulting PDF, exactly as expected:
3. With headers and footers, it fails!
So I now add the header and footer. To do so, I just add a couple of twigs, render the HTMLs into a couple of variables, and pass them in into the options of the Pdf renderer:
private function getPdf( string $docName ) : string
{
$html = $this->renderView( 'AppBundle:documents:' . $docName . '.pdf.twig' );
$header = $this->renderView( 'AppBundle:documents:header.pdf.twig' );
$footer = $this->renderView( 'AppBundle:documents:footer.pdf.twig' );
$options = [
'header-html' => $header,
'footer-html' => $footer,
];
$generator = $this->getPdfGenerator();
$pdf = $generator->getOutputFromHtml( $html, $options );
return $pdf;
}
The header and footer are identical one to each other, except for the contained text:
This is my header.pdf.twig
:
<html>
<body>
<div style="border: 5px dashed crimson; color: maroon; background-color: darksalmon">
This is a header
</div>
</body>
</html>
And the footer.pdf.twig
:
<html>
<body>
<div style="border: 5px dashed crimson; color: maroon; background-color: darksalmon">
This is a footer
</div>
</body>
</html>
And wow!!! The footer gets rendered but the header does not!!
This is what I get:
To be noted in the image:
- There is "something" in the header. I can see the text of the page content like "clipped".
- The footer does not fully render, as it hides all the bottom border-lines, and the text base-line is aligned to the bottom edge of the page.
Soooo, hence my question!!
- What should I do to get the header rendered as well?
- Should'nt it be that I could see the header rendered in the PDF with this simple setup? Why does it not appear?
回答1:
Solved!
Well, it seems that wkhtmltopdf
is really strict to consider the doctype and it does weird things if not.
Inspired here: https://stackoverflow.com/a/28343079/1315009
So, I changed all the twigs to include <!DOCTYPE html>
:
helloWorld.pdf.twig
<!DOCTYPE html>
<html>
<body>
<div class="pdfPageBody">
<h1>
Hello, World!
</h1>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</body>
</html>
header.pdf.twig
<!DOCTYPE html>
<html>
<body>
<div style="border: 5px dashed crimson; color: maroon; background-color: darksalmon">
This is a header
</div>
</body>
</html>
footer.pdf.twig
<!DOCTYPE html>
<html>
<body>
<div style="border: 5px dashed crimson; color: maroon; background-color: darksalmon">
This is a footer
</div>
</body>
</html>
Final result
I finally got this:
It happens to have:
- The header, with no weird clipping on the body
- The footer.
Hope to help!
来源:https://stackoverflow.com/questions/47583622/how-do-i-set-header-and-footer-in-a-pdf-from-html-with-knp-snappy-bundle