mPDF имеет базовую поддержку свойства page-break-inside: avoid
CSS ( см. Документацию по всем поддерживаемым CSS ), но, как мне показалось, это не работает (если вообще) для плавающих элементов. Если это работает, это легкий выигрыш:
<div style="page-break-inside: avoid;">
<!-- Contents -->
</div>
Если это не работает, вы можете разбить ваш HTML-контент на более мелкие куски и записать каждый блок в раздел за раз:
$mpdf->WriteHTML($chunk1);
$mpdf->WriteHTML($chunk2);
$mpdf->WriteHTML($chunk3);
Между чанками вы можете проверить, где находится текущий указатель Y на странице, используя $mpdf->y
, а затем принудительно разорвать страницу, если для вашего чанка недостаточно места:
if ($mpdf->y > 150) { // if the Y pointer is lower than 150mm on the page
$mpdf->WriteHTML('<pagebreak />');
}
Этот метод требует, чтобы вы могли: 1. разбить ваш HTML на более мелкие куски и 2. узнать, насколько велик ваш чанк (или, по крайней мере, в хорошем приближении).
Для действительно динамического содержимого наиболее надежный метод, который я нашел, - это клонирование объекта Mpdf перед записью каждого чанка и проверка увеличения count($mpdf->pages)
. Я рекомендую библиотеку myclabs / DeepCopy ( пакет, который будет свернут в mPDF в будущем обновлении ). Если массив увеличивается, ваш чанк не умещается на одной странице, и вам нужно добавить разрыв страницы:
$copier = new DeepCopy\DeepCopy(true);
$MpdfClone = $copier->copy($mpdf);
$currentPageCount = count($MpdfClone->pages);
$currentPageCount = $currentPageCount !== 0 ? $currentPageCount : 1; //fix when the object is first created and no pages have been added
$MpdfClone->WriteHTML($chunk);
if ($currentPageCount !== count($MpdfClone->pages)) {
$mpdf->WriteHTML('<pagebreak />');
}
unset($MpdfClone);
$mpdf->WriteHTML($chunk);
При написании большого количества фрагментов в PDF с использованием этого метода возникают большие издержки. Я рекомендую запустить свои собственные тесты, прежде чем принять решение о внедрении этой техники.