a5sys/pdf-bundle

dev-master 2016-08-31 12:37 UTC

This package is auto-updated.

Last update: 2024-08-28 20:19:41 UTC


README

目标

此组件允许通过使用封装器 phpwkhtmltopdf 来生成PDF文档,它本身使用工具 wkhtmltopdf

wkhtmltopdf 的优势在于它使用Webkit处理HTML代码,具有JS和CSS功能,就像代码在浏览器中运行一样。

#### 为什么这个组件,KnpSnappyBundle 已经存在?

KnpSnappyBundle 并不在所有情况下都工作,尤其是在Windows上,当生成的HTML有外部文件(CSS、JS、图片)时。由于PHP proc_open函数似乎存在bug,我们遇到了一些网络访问问题。

在成功尝试了phpwkhtmltopdf之后,这个组件被创建出来,以便与Symfony 2集成。

依赖

需要 phpwkhtmltopdfwkhtmltopdf

安装

首先安装 wkhtmltopdf (http://wkhtmltopdf.org/downloads.html)

composer.json 中添加依赖

"a5sys/pdf-bundle": "dev-master",
"mikehaertl/phpwkhtmltopdf": "~2.0"

AppKernel.php 中声明组件

new A5sys\PdfBundle\A5sysPdfBundle(),

注意:封装器 phpwkhtmltopdf 是一个库,不是一个组件。

配置

  • 安装wkhtmltopdf。确保路径中不要有空格。
  • 配置A5sys ProjectBundle

config.yml 中添加

a5sys_pdf:
    binary: "C:/wkhtmltopdf/bin/wkhtmltopdf.exe"
    # temp_dir: "D:/tmp"
    # encoding: "UTF-8"
    # command_options:
    #    use_exec: true
    #    escape_args: false
    #    proc_options:
    #        bypass_shell: true
    #        suppress_errors: false
  • binary: 必须的
  • temp_dir: 可选,默认系统临时目录 (C:/windows/temp)。
  • encoding: 可选,默认 UTF-8
  • command_options: 可选,默认创建具有默认子值的数组 -- use_exec: 可选,默认 true,系统是否使用exec函数而不是proc_open? -- escape_args: 可选,默认 false,在将参数集成到命令之前,系统是否转义参数? -- proc_options: 可选,默认 NULL,当 use_exec = false 时使用 ---- bypass_shell: 可选,默认 true,在Windows上推荐 ---- suppress_errors: 默认 false。在Windows上建议设置为 TRUE。即使在错误发生时,也可以进行生成。不保证PDF正确生成。

使用

以下给出一个专业服务示例。

$this->templating 是注入的twig服务。$this->pdfService 是要注入的PDF服务。

utf8_decode 用于头部和尾部。为了获得重音符号,这是必要的。

use A5sys\PdfBundle\Service\PdfService;

class MyService
{
    /**
     * @var $data array
     */
    public function savePdf($data)
    {
        // HTML of pdf
        $html = $this->templating->render('MyAppBundle:Folder:my_pdf.pdf.twig', $data);

        // Header in HTML
        $htmlHeader = $this->templating->render('MyAppBundle:Folder:my_header.pdf.twig');

        // Footer in HTML
        $htmlFooter = $this->templating->render('MyAppBundle:Folder:my_footer.pdf.twig');

        // name and path to PDF file
        $fileName = uniqid() . ".pdf";
        $filePath = $this->constants['my_pdf_path'] . "/" . $fileName;

        // note : throws ServiceException
        // Generation and saving of the PDF

        $options = array(
           //'no-outline',
            'orientation' => 'Landscape',
            'header-html' => utf8_decode($htmlHeader),
            'header-spacing' => '2', // space between header and content in mm
            'footer-html' => utf8_decode($htmlFooter),
        );

        $this->pdfService->saveAs(
            $filePath,
            $html,
            $options
        );
    }
}

到2015-02-10,仅实现了wrapper phpwkhtmltopdf的saveAs。

选项

变量 **$options ** 允许指定用于生成的选项。最初,配置信息将集成到这个数组中。如果您想覆盖配置的值,只需将封装器的键 phpwkhtmltopdf 添加到数组中。

具体的 phpwkhtmltopdf 封装器在这里: https://github.com/mikehaertl/phpwkhtmltopdf#special-global-options

仍在 $options 中,与特定封装器选项在同一级别,您可以添加所有希望提供给 wkhtmltopdf 的选项,例如示例中的orientation、header-spacing、header-html或footer-html。

所有wkhtmltopdf选项在这里: http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

页面分断

在示例中,$html 变量包含要在PDF中渲染的所有HTML。可以通过CSS显式指定页面分断的位置。

<div style="page-break-after: always;"></div>

页码

在示例的 footer-html 中没有给出参数,但是 wkhtmltopdf 会为我们处理!我们可以获取当前页码,甚至更多,例如使用以下代码

<!DOCTYPE html>
<html>
    <head>
        <script>
        function subst() {
          var vars={};
          var x=document.location.search.substring(1).split('&');
          for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
          var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
          for (var i in x) {
            var y = document.getElementsByClassName(x[i]);
            for (var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
          }
        }
        </script>
    </head>
    <body style="border:0; margin: 0;" onload="subst()">
        <table style="width: 100%">
          <tr>
            <td style="text-align: left">{{ 'now'|date('d/m/Y') }}</td>
            <td style="text-align: center">{{ 'pdf.archival.title'|trans|raw('html') }}</td>
            <td style="text-align: right">
              {{ 'page'|trans }} <span class="page"></span> {{ 'pageOn'|trans }} <span class="topage"></span>
            </td>
          </tr>
        </table>
    </body>
</html>

JS 是否正常工作?是的,是 Webkit 处理页面,即使是 header-html 和 footer-html

注意:不要忘记在页脚和页眉中添加 doctype,否则将无法工作!

此 HTML 代码将日期显示在左侧,中间显示翻译文本,右侧显示文本“第 x 页共 y 页”