mPDF создает пустую страницу после оглавления при использовании другой ориентации - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь создать файл PDF через mPDF, где листы имеют следующую ориентацию:

___________
| 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();

Я пытался сделать несколько вещей, чтобы это сработало, но безуспешно. Я перечислю некоторые из них:

  • Использование toc-selector="page-portrait" в теге <tocpagebreak>
  • Использование toc-orientation="P" в теге <tocpagebreak>
  • Добавление <pagebreak orientation="L" /> после <tocpagebreak>
  • Использование class="landscape" в div после оглавления, использование селектора @page, как показано в этом примере
  • Установка переменной autoPageBreak в false в конструкторе mPDF
  • Заворачивание страниц в div и возня с позицией <pagebreak>

Я использовал mPDF v6.0 и сейчас обновляюсь до mPDF v8.0.1. Эта проблема возникает во всех версиях (6, 7 и 8). В то время как в версии 6 я использовал хак, добавив $mpdf->DeletePages(2); после $mpdf->WriteHTML($html);, но это имеет две основные проблемы:

  1. Этот метод недокументирован и выглядит некорректно
  2. При этом номер страницы не соответствует правильным страницам, поэтому я не могу добавить номер страницы в нижний колонтитул

Есть ли способ сделать это без пустой страницы? Или жизнеспособный обходной путь?

Ответы [ 2 ]

2 голосов
/ 28 мая 2019

Я понял, как заставить это работать.Ключ должен добавить 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. Если у вас есть оболочка для всего содержимого с отступом, кажется, что создается пустая страница вверху или перед оглавлением (по любой причине).У меня был <div class="page-content"> в качестве дочернего элемента <body>, а у класса - padding: 15px;, который заставил mPDF создать новую страницу.
  2. Если вы используете таблицы стилей, я советую вам отбросить их, покатестирование.Этот пример работает как есть, но если вы попробуете его, когда у вас есть внешние таблицы стилей, он может работать не так, как ожидалось.Когда это происходит, это означает, что какой-то стиль заставляет mPDF создать пустую страницу (так я узнал о 1.).Кроме того, я использовал классы Bootstrap row и col-xx и удалил их все.
  3. Используйте <pagebreak /> только для создания новых страниц, но сохраняя ориентацию.В качестве альтернативы используйте style="page-break-before: always;".Это важно, потому что, возясь с вами, вы можете создать новую страницу с <pagebreak />, просто пытаясь изменить ориентацию, что даст вам новую пустую страницу.
  4. Наконец, если вы используете $mpdf->SetFooter() или $mpdf->SetHTMLFooter() (или соответствующие методы заголовка), если вы используете селектор @page, верхний / нижний колонтитул не будет отображаться на странице.Вам нужно установить именованный верхний / нижний колонтитул и указать его с помощью CSS на селекторе @page.См. пример 5 на документах для получения дополнительной информации.
0 голосов
/ 31 мая 2019

Я использую код в вопросе и обновил его для генерации pdf без пустой страницы после оглавления в pdf.

Здесь дано , что TOCpagebreak всегда будет начинаться с нечетного номера страницы. Также существует проблема с mpdf , когда он добавляет пустую страницу после страницы оглавления.

Я разделил HTML-код на две части и удалил пустую страницу после оглавления, чтобы получить окончательный 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();
...