Я пытаюсь создать PDF с несколькими страницами и вам нужно заранее рассчитать высоту каждого отдельного элемента (MultiCell), чтобы подготовиться к разрыву страницы. Согласно документации, есть несколько функций, таких как GetCharWidth / GetStringWidth, чтобы поддержать меня, делая это самостоятельно, но, кроме потенциальной потери производительности, я, вероятно, не буду делать это правильно. Предложения для достижения моей цели более элегантным способом?
Ссылка: TCPDF
Я ПОЛУЧИЛ: D !!!!!
Создать другой объект pdf2
// pdf2 set x margin to pdf1's xmargin, but y margin to zero // to make sure that pdf2 has identical settings, you can clone the object (after initializing the main pdf object) $pdf2 = clone $pdf; pdf2->addpage pdf2->writeCell $height = pdf2->getY() pdf2->deletePage(pdf2->getPage()) pdf1->checkPageBreak($height); pdf1->writeCell()
W00tness: D
Это старый вопрос, но в текущей версии (по состоянию на 7 декабря 2011 г.) TCPDF есть функция, называемая getStringHeight
которая позволяет вычислить результирующую высоту строки, переданной MultiCell, до того, как на самом деле вызывается MultiCell. Затем эту высоту можно использовать для разных вещей, вычисления в исходном вопросе, а также для установки высоты строки при создании таблиц и т. Д. Отлично работает.
Просто некоторая информация в случае, если кто-то другой наткнулся на этот вопрос, ища решение этой проблемы, как и я.
В то время как ответ Карвелла велик, TCPDF упоминает, что getStringHeight
возвращает оцененную высоту. Полезно документация там обеспечивает довольно всеобъемлющий метод для получения точной высоты, которая выходит как $height
. Что касается того, почему они не используют это сами, это тайна …
// store current object $pdf->startTransaction(); // store starting values $start_y = $pdf->GetY(); $start_page = $pdf->getPage(); // call your printing functions with your parameters // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $pdf->MultiCell($w=0, $h=0, $txt, $border=1, $align='L', $fill=false, $ln=1, $x='', $y='', $reseth=true, $stretch=0, $ishtml=false, $autopadding=true, $maxh=0); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // get the new Y $end_y = $pdf->GetY(); $end_page = $pdf->getPage(); // calculate height $height = 0; if ($end_page == $start_page) { $height = $end_y - $start_y; } else { for ($page=$start_page; $page <= $end_page; ++$page) { $pdf->setPage($page); if ($page == $start_page) { // first page $height = $pdf->h - $start_y - $pdf->bMargin; } elseif ($page == $end_page) { // last page $height = $end_y - $pdf->tMargin; } else { $height = $pdf->h - $pdf->tMargin - $pdf->bMargin; } } } // restore previous object $pdf = $pdf->rollbackTransaction();
По моему опыту, почти невозможно определить высоту клетки заранее. Гораздо проще использовать функции обработки разрыва страницы TCPDF, которые расскажут вам заранее, если вы направляетесь в разворот страницы. Вот пример кода:
$yy = $this->pdf->GetY(); $check_pagebreak = $this->pdf->checkPageBreak($height+$padding,$yy,false);
Измените false на true, чтобы разрешить автоматический разрыв страницы, в противном случае вы можете справиться с логикой самого разрыва страницы, и это то, что я и сделал.
Кроме того, если вам это может понадобиться, вот еще один маленький совет: рассмотрите возможность использования функций транзакции для создания своего документа за два прохода. Первый проход используется для определения всех высот и ячеек, разрывов страниц и т. Д. Вы также можете хранить все ваши строки и строки на странице в массивах. На втором проходе создайте свой документ со всей необходимой информацией и не нуждайтесь в логике перебора страниц (второй проход может быть запущен по отдельному методу, чтобы упростить чтение кода и для вашего здравомыслия).
Сообщение Revisited: Tcpdf – Строки таблицы с переменной высотой. MultiCell содержит много полезной информации. Это краткий отрывок:
getNumLines()
… фактически позволяет нам определить, сколько строк займет строка текста, учитывая определенную ширину. Фактически, это позволяет нам делать то, что я использовал MultiCell, чтобы вернуться, ничего не рисуя. Это позволяет определить максимальную высоту ячейки с одной строкой кода:$linecount = max($pdf->getNumLines($row['cell1data'], 80),$pdf->getNumLines($row['cell2data'], 80
Использовать TCPDF Пример 20
Вычисление высот MultiCell может быть кошмаром, если ячейки / столбцы заканчиваются на разных страницах.
Использование транзакций или дополнительных PDF-объектов может сделать вещи очень медленными.
Использование функций, таких как getNumLines () и getStringHeight () для вычисления высоты «оцененных» (см. Docs) до того, как будут напечатаны ячейки, не всегда работает правильно. Особенно, если текст заканчивается как раз перед или сразу после правой границы ячейки, в результате чего строки печатаются друг над другом.
Я предпочитаю метод, использованный в примере 20, где максимальное значение Y разных страниц используется для вычисления позиции новой строки.
В примере печатаются только два столбца, но я изменил его основную функцию, чтобы иметь возможность печатать массив столбцов. Очевидно, вы могли бы добавить больше данных в массив, например шрифт каждого столбца, границы и т. Д.
public function MultiRow($columnsArray) { $page_start = $this->getPage(); $y_start = $this->GetY(); $pageArray = array(); $yArray = array(); // traverse through array and print one column at a time. $columnCount = count($columnsArray); for($i=0; $i<$columnCount; $i++) { if($i+1 < $columnCount) { // Current column is not the last column in the row. // After printing, the pointer will be moved down to // the right-bottom of the column - from where the // next multiCell in the following loop will use it // via $this->GetX(). $ln = 2; } else { // Current column is the last column in the row. // After printing, the pointer will be moved to new line. $ln = 1; } $this->MultiCell(30, 0, $columnsArray[$i], 1, 'L', 1, $ln, $this->GetX() ,$y_start, true, 0); $pageArray[$i] = $this->getPage(); $yArray[$i] = $this->GetY(); // Go to page where the row started - to print the // next column (if any). $this->setPage($page_start); } // Test if all columns ended on the same page $samePage = true; foreach ($pageArray as $val) { if($val != $pageArray['0']) { $samePage = false; break; } } // Set the new page and row position by case if($samePage == true) { // All columns ended on the same page. // Get the longest column. $newY = max($yArray); } else { // Some columns ended on different pages. // Get the array-keys (not the values) of all columns that // ended on the last page. $endPageKeys = array_keys($pageArray, max($pageArray)); // Get the Y values of all columns that ended on the last page, // ie get the Y values of all columns with keys in $endPageKeys. $yValues = array(); foreach($endPageKeys as $key) { $yValues[] = $yArray[$key]; } // Get the largest Y value of all columns that ended on // the last page. $newY = max($yValues); } // Go to the last page and start at its largets Y value $this->setPage(max($pageArray)); $this->SetXY($this->GetX(),$newY); }