如何使用knp-snappy-bundle从HTML设置PDF的页眉和页脚?

问题描述:

使用knp-snappy-bundle时,我无法在PDF中生成页眉,而实际上可以生成页脚.

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?

我正在测试knp-snappy-bundle,我还安装了h4cc中的wkhtmltopdf二进制文件.这是我的composer.json:

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",

wkhtmltopdf的结果二进制文件表示:

The resulting binary of wkhtmltopdf says this:

$ vendor/bin/wkhtmltopdf-amd64 --version
wkhtmltopdf 0.12.3 (with patched qt)

2. 没有页眉或页脚,它可以正常工作

我已设置使用knp-snappy-bundle正常工作的控制器:

2. Without headers or footers, it works

I've setup a controller that uses the knp-snappy-bundle and it works:

这是我的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;
}

基本上是:

  • 具有downloadPdf动作
    • Has a downloadPdf action that
      1. 通过其名称获取PDF文档,并将其作为参数传递.在此示例中,我们将使用'helloWorld'.

      1. 使用分发包中的PdfResponse类返回使用PDF内容创建的新Response.
      1. Returns a new Response created with the content of the PDF, using the PdfResponse class in the bundle.

    1. 它使用twig引擎渲染视图.
    1. it renders a view with the twigengine.

    1. 获取服务(拆分为另一个功能getPdfGenerator()).

    1. 在未传入任何选项的情况下将服务用于getOutputFromHtml().

  • 这是我的helloWorld.pdf.twig:

<html>
    <body>
        <div class="pdfPageBody">
            <h1>
                Hello, World!
            </h1>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        </div>
    </body>
</html>

这是生成的PDF,完全符合预期:

And here it is the resulting PDF, exactly as expected:

因此,我现在添加页眉和页脚.为此,我只添加了两个小树枝,将HTML渲染为几个变量,然后将它们传递到Pdf渲染器的选项中:

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:

这是我的header.pdf.twig:

<html>
    <body>
        <div style="border: 5px dashed crimson; color: maroon; background-color: darksalmon">
            This is a header
        </div>
    </body>
</html>

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!!

这就是我得到的:

要在图片中注明:

  1. 标题中包含内容".我可以看到页面内容的文本,例如已裁剪".
  2. 页脚未完全呈现,因为它隐藏了所有底部边框线,并且文本基准线与页面的底部边缘对齐.

Soooo,因此是我的问题!

  • 我该怎么做才能同时显示标题?
  • 是否可以通过这种简单的设置看到PDF中呈现的标题?为什么它不出现?
  • 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?

已解决!

好吧,wkhtmltopdf似乎非常严格地考虑了doctype,如果没有,它会做一些奇怪的事情.

Well, it seems that wkhtmltopdf is really strict to consider the doctype and it does weird things if not.

灵感来自于: https://stackoverflow.com/a/28343079/1315009

因此,我更改了所有树枝以包括<!DOCTYPE html>:

So, I changed all the twigs to include <!DOCTYPE html>:

<!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:

它恰好具有:

  1. 标题,没有怪异的剪裁
  2. 页脚.

希望能提供帮助!