php - 是否可以制作具有最大高度的 TCPDF 元素?
问题描述
我正在使用 PHP 处理 TCPDF。我正在尝试制作一个必须只有一页长的 PDF 文档。该文档包括一个表格,其数据具有动态确定的行数。
我想做的是给这张桌子一个最大高度(例如10厘米),如果超过这个限制,就缩小表格的字体大小。这样数据仍然存在,但文档将适合一页。这可能吗?我试过使用这个WriteHTML()
方法,但它似乎忽略了我给它的高度。(也就是说,如果数据溢出,它只是继续写入而不是切断它。)
这可能吗?
解决方案
一种方法是设置个体MultiCell
或Cell
输出的大小。涉及很多视觉调整,但您可以非常精确。为简单起见,我创建了一个带有固定线高的粗略示例。基本上,这个想法是将您的最大高度和位置设置(Multi)Cells
为前一个的右侧,$ln
参数设置为 0。(或在每次调用之前设置坐标。)您可以在此处查看示例输出文件:https://s3 .amazonaws.com/rrbits/maxheight.pdf
MultiCell
有一个autofit
设置可以为您处理缩小字体,我在MultiCell
示例中使用了该设置。一个潜在的警告是它将允许包装。
Cell
没有自动调整参数,但您可以通过将字体大小设置为合理的最大值来模拟它,检查单元格字符串的宽度GetStringWidth
并减小字体大小直到适合。[编辑:我不在这里这样做,但在输出单元格后恢复字体大小是个好主意,否则你可能会得到一些意想不到的结果。](参见第 105 行的循环)。(Cell
确实有一些可用的字体拉伸选项,请参阅TCPDF 示例 004,但它们并没有完全按照您的要求进行。)
<?php
require_once('TCPDF-6.2.17/tcpdf.php');
// create new PDF document
$pdf = new TCPDF('L', 'mm', array(130,130), true, 'UTF-8', false);
$pdf->SetFont('times', '', 8);
$pdf->SetAutoPageBreak(TRUE, 5);
//Generating a random table for testing.
$table = [
['Name','Description','md5'],
];
$rows = rand(10,30);
//$rows = rand(3,5);
for($i = 0; $i < $rows; $i++) {
$table[] = array(
'Sector '.rand(1,10000),
str_repeat('An Apple', rand(2,6)),
md5(rand(1,100000)),
);
}
$pdf->addPage();
$pdf->Write(2, 'MultiCell Example');
$pdf->Ln();
$pdf->SetFont('times', '', 8);
$column_widths = array(
20,
60,
30,
);
//Total table should only be 10cm tall.
$maxheight = 100/count($table);
if($maxheight > 10) {
$maxheight = 10;
}
foreach($table as $index => $row) {
if($index == 0) {
$pdf->SetFillColor(230,230,255);
} else {
if( ($index&1) == 0 ) {
$pdf->SetFillColor(210,210,210);
} else {
$pdf->SetFillColor(255,255,255);
}
}
$pdf->SetX(10);
$currenty = $pdf->GetY();
foreach($row as $index => $column) {
$pdf->MultiCell(
$width = $column_widths[$index],
$minheight = $maxheight,
$text = $column,
$border = 'B', //Border bottom
$align = 'L',
$fill = true,
$ln = 0, //Move to right after cell.
$x = null,
$y = null,
$reseth = true,
$stretch = 0,
$ishtml = false,
$autopadding = true,
$maxheight,
$valign = 'T',
$fitcell = true);
}
$pdf->SetY($currenty + $maxheight);
}
$pdf->addPage();
$pdf->SetFont('times', '', 8);
$pdf->Write(2, 'Cell Example');
$pdf->Ln();
$pdf->SetFont('times', '', 8);
$maxheight = 100/count($table);
if($maxheight > 8) {
$maxheight = 8;
}
$maxfontsize = 10;
$pdf->SetFontSize($maxfontsize);
foreach($table as $index => $row) {
if($index == 0) {
$pdf->SetFillColor(230,230,255);
} else {
if( ($index&1) == 0 ) {
$pdf->SetFillColor(210,210,210);
} else {
$pdf->SetFillColor(255,255,255);
}
}
$pdf->SetX(10);
$currenty = $pdf->GetY();
foreach($row as $index => $column) {
//Reduce the font size to fit properly.
$pdf->SetFontSize($csize = $maxfontsize);
//0.2 step down font until it fits the cell.
while($pdf->GetStringWidth($column) > $column_widths[$index]-1 ) {
$pdf->SetFontSize($csize -= 0.2);
}
$pdf->Cell(
$width = $column_widths[$index],
$cellheight = $maxheight,
$text = $column,
$border = 'B', //Border bottom
$ln = 0,
$align = 'L',
$fill = true,
$stretch = 1,
$ignore_min_height = true,
$calign = 'T',
$valign = 'T');
}
$pdf->SetY($currenty + $maxheight);
}
$pdf->Output(dirname(__FILE__).'/maxheight.pdf', 'F');
附录:替代方法WriteHTML
您可以使用的一种方法WriteHTML
是使用 开始事务startTransaction
,为整个表格设置基本字体并编写 HTML,然后检查页数。如果遇到自动分页符,请回滚事务并尝试使用较小的字体。否则提交事务。
我已经更新了上面的链接,并以此输出为例:
//Example with WriteHTML.
$pdf->AddPage();
$pdf->SetFont('times', '', 8);
$pdf->Write(2, 'WriteHTML Example');
$pdf->Ln();
$pdf->SetFont('times', '', 8);
//Max height of 100 mm.
$maxy = $pdf->GetY()+100;
$fontsize = 14;
//Make table markup.
$tablehtml = '<table cellspacing="2" style="font-family: times; font-size:_FONTSIZE_px;">';
foreach($table as $index => $row) {
if($index == 0) {
$rowstyle = ' background-color: rgb(230,230,255); '.
'font-size: 110%; font-familt: times; font-weight: bold;'.
'border-bottom: 1px solid black;';
} else {
if( ($index&1) == 0 ) {
$rowstyle = 'background-color: rgb(210,210,210);';
} else {
$rowstyle = 'background-color: white;';
}
}
$tablehtml .= "<tr style=\"$rowstyle\">";
foreach($row as $column) {
$tablehtml .= "<td>$column</td>";
}
$tablehtml .= '</tr>';
}
$tablehtml .= '</table>';
//Transaction loop.
$numpages = $pdf->getNumPages();
$done = false;
while(!$done) {
$pdf->startTransaction(true);
$pdf->SetFont('times', '', 14);
$outtable = str_replace('_FONTSIZE_', $fontsize, $tablehtml);
$pdf->writeHTML($outtable);
if($pdf->getNumPages() > $numpages || $pdf->GetY() > $maxy) {
//If we encountered a page break or exceeded the desired maximum height
//rollback the transaction.
$pdf->rollbackTransaction(true);
$fontsize -= 0.4;
//Larger font steppings will be less precise, but faster.
} else {
$pdf->commitTransaction(true);
$done = true;
}
}
推荐阅读
- prometheus - 对于 slack,[FIRING] 包含 [RESOLVED] 警报
- java - 如何在没有按钮的情况下进行复选框
- smpp - SMPP TLV 可选参数
- twig - 致命错误:未捕获的 TypeError:参数 1 传递给 Slim\Views\Twig
- angular - 在进行 ng build --prod 时,jw-angular-pagination 抛出错误
- javascript - 如何在javascript中使用while循环打印数字
- python - 使用 eval 时如何使用 df.appen
- c++ - 如何在普通图像上使用 seshat 作为 seshat(C++ 中的数学表达式识别库)的输入?
- php - 贷款 计算逾期还款,每日 0.2% 拖欠
- php - PHP语法建议