当使用不同的方向时,mPDF在TOC之后创建空白页

时间:2019-05-22 19:36:28

标签: php mpdf

我正在尝试通过mPDF创建PDF文件,其中图纸的方向如下:

___________
| Page 1   |
|          |
| Portrait |
|          |
___________
___________
| Page 2   |
|  TOC     |
| Portrait |
|          |
___________
__________________
| Page 3          |
| Landscape       |
|                 |
__________________
___________
| Page 4   |
|          |
| Portrait |
|          |
___________

但是,更改第3页的方向会使mPDF在第2页(TOC)和第3页之间创建空白页。

以HTML创建PDF,然后将其处理为mPDF。代码如下:

HTML:

<html>
<head>
    <style>
        @page page-landscape { size: landscape; }
        @page page-portrait { size: portrait; }

        div.landscape {
            page: page-landscape;
        }
        div.portrait {
            page: page-portrait;
        }

    </style>
</head>
<body>
    <div>
        <div>First page - displayed Portrait. The second page should be the TOC (portrait) and the 3rd should be on landscape</div>
    </div>

    <tocpagebreak />

    <div class="landscape">
       <bookmark content="TOC entry" level="0"/>
        <tocentry content="TOC entry" level="0"/>
        <p>TOC entry - Shouldn\'t have a empty page before</p>
    </div>

    <div class="portrait">
        another page
    </div>
</body>
</html>

PHP

$mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML($html);
$mpdf->Output();

我已经尝试了很多方法来使这项工作成功,但是没有成功。我将列出其中一些:

  • toc-selector="page-portrait"标签上使用<tocpagebreak>
  • toc-orientation="P"标签上使用<tocpagebreak>
  • <pagebreak orientation="L" />之后添加<tocpagebreak>
  • 使用class="landscape"选择器在TOC之后的div中使用@page,如本例所示
  • 在mPDF的构造函数上将变量autoPageBreak设置为false
  • 包装div中的页面并弄乱<pagebreak>的位置

我正在使用mPDF v6.0,现在正在更新为mPDF v8.0.1。在所有版本(6、7和8)上都会发生此问题。在版本6上,我通过在$mpdf->DeletePages(2);之后添加$mpdf->WriteHTML($html);来使用骇客,但这有两个主要问题:

  1. 此方法未记录,似乎有错误
  2. 因此,页码与正确的页面不匹配,因此我无法在页脚上添加页码

有没有空白页可以完成此操作的方法?还是可行的解决方法?

2 个答案:

答案 0 :(得分:2)

我想出了如何使它工作的方法。关键是将class="landscape"(或您在CSS上设置的名称)添加到<tocpagebreak />的容器中,而不是要在横向上显示的实际页面。

因此,HTML应该是:

<html>
<head>
    <style>
         @page page-landscape { size: landscape; }
         @page page-portrait { size: portrait; }

        div.landscape { page: page-landscape; }
        div.portrait { page: page-portrait; }
    </style>
</head>

<body>
    <div class="portrait">
        <div>First page - displayed Portrait. The second page should be the TOC (portrait) and the 3rd should be on landscape</div>
    </div>

    <div class="landscape">
        <tocpagebreak />
   </div>

    <div>
     <bookmark content="TOC entry consolidacao" level="0"/>
        <tocentry content="TOC entry consolidacao" level="0"/>
        <p>TOC entry - Shouldn't have a empty page before</p>
    </div>

    <div class="portrait">
        <bookmark content="2nd page" level="0"/>
        <tocentry content="2nd page" level="0"/>
        <p>2nd page</p>
    </div>
</body>
</html>

请注意,<div class="landscape">包装了<tocpagebreak />。实际上,这实际上并不会改变TOC的方向,而只会改变下一页-我想它与mPDF的内部结构有关。 然后,当您要将方向更改为纵向时,只需在要应用的页面上添加class="portrait"(如“第二页”所示)。

其他需要注意的是:

  1. 如果您对所有内容都有一个包装(带有填充),那么似乎在目录顶部或目录顶部都会创建一个空白页面(无论出于何种原因)。我有一个<div class="page-content">作为<body>的子元素,而这个班级有一个padding: 15px;,这使mPDF创建了一个新页面。
  2. 如果您使用的是样式表,建议您在测试时将其删除。该示例按原样工作,但是如果您在使用外部样式表时尝试使用它,则可能无法按预期工作。发生这种情况时,这意味着某种样式迫使mPDF创建空白页(这是我发现1.的方式)。此外,我正在使用Bootstrap的rowcol-xx类并将其全部删除。
  3. 仅使用<pagebreak />创建新页面,但保持方向。或者使用style="page-break-before: always;"。这很重要,因为在闲逛时,您可能会发现自己使用<pagebreak />创建了一个新页面,而只是试图改变方向,从而为您提供了一个新的空白页面。
  4. 最后,如果您使用的是$mpdf->SetFooter()$mpdf->SetHTMLFooter()(或相应的Header方法),则一旦使用@page选择器,则页眉/页脚将不会显示在这页纸。您需要设置一个命名的页眉/页脚,并在@page选择器上通过CSS进行指定。有关更多信息,请参见example 5 on the docs

答案 1 :(得分:0)

我正在使用问题中的代码,并将其更新为生成pdf,而在pdf中的TOC之后没有空白页。

根据here,TOCpagebreak将始终以奇数页码开头。另外,还有一个issue with mpdf,它在TOC页面之后添加了一个空白页面。

我将html代码分为两部分,并在TOC之后删除了空白页以获得最终的pdf。

php中的代码是:


require_once __dir__.'/vendor/autoload.php';


$html = '<html>
<head>
    <style>
        @page page-landscape { size: landscape; }
        @page page-portrait { size: portrait; page-break-inside:avoid; }

        div.landscape {
            page: page-landscape;
        }
        div.portrait {
            page: page-portrait;
        }

    </style>
</head>
<body>
    <div>
        <div>First page - displayed Portrait. The second page should be the TOC (portrait) and the 3rd should be on landscape</div>
    </div>

<tocpagebreak />';

$mpdf = new \Mpdf\Mpdf();

$mpdf->WriteHTML($html);
$page = $mpdf->page;


$html2= '<div class="portrait" style="page-break:avoid !important;">
       <bookmark content="TOC entry" level="0"/>
        <tocentry content="TOC entry" level="0"/>
        <p>TOC entry - Shouldn\'t have a empty page before</p>
    </div>

    <div class="landscape">
        another page
    </div>
</body>
</html>';


$mpdf->WriteHTML($html2);
$mpdf->DeletePages($page);
$mpdf->Output();