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

mPDF creates blank page after TOC when using different orientation

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

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

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

PDF 在 HTML 中创建,然后处理为 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();

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

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

  1. 此方法未记录且似乎有问题
  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 />。这实际上并没有改变目录的方向,而是改变了下一页——我想这与 mPDF 的内部结构有关。 然后,当您想将方向更改为纵向时,只需在要应用它的页面上添加 class="portrait"(如“第 2 页”所示)。

其他需要注意的事项是:

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

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

给出 here that TOCpagebreak will always start at an odd page number. Also, there is an 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();