【问题标题】:Is it possible to make a TCPDF element with maximum height?是否可以制作具有最大高度的 TCPDF 元素?
【发布时间】:2018-08-14 22:02:09
【问题描述】:

我正在使用 PHP 处理 TCPDF。我正在尝试制作一个必须只有一页长的PDF文档。该文档包含一个表格,其中的数据具有动态确定的行数。

我想做的是给这个表格一个最大高度(例如 10 厘米),如果超过这个限制,就缩小表格的字体大小。这样数据仍然存在,但文档将适合一页。这可能吗?我试过使用WriteHTML() 方法,但它似乎忽略了我给它的高度。 (也就是说,如果数据溢出,它只是继续写入而不是切断它。)

这可能吗?

【问题讨论】:

    标签: php pdf-generation tcpdf


    【解决方案1】:

    一种方法是设置单个MultiCellCell 输出的大小。涉及很多视觉调整,但您可以非常精确。为简单起见,我创建了一个带有固定线高的粗略示例。基本上这个想法是设置你的最大高度并将(Multi)Cells放在前一个的右侧,$ln参数设置为0。(或者在每次调用之前设置坐标。)你可以看到一个示例输出文件here :https://s3.amazonaws.com/rrbits/maxheight.pdf

    MultiCell 有一个autofit 设置,可以为您处理缩小字体,我在MultiCell 示例中使用了该设置。一个潜在的警告是它将允许包装。

    Cell 没有自动调整参数,但您可以通过将字体大小设置为合理的最大值来模拟它,使用GetStringWidth 检查单元格字符串的宽度并减小字体大小直到适合。 [编辑:我不在这里这样做,但在输出单元格后恢复字体大小是个好主意,否则你可能会得到一些意想不到的结果。](参见第 105 行的循环)。 (Cell 确实有一些可用的字体拉伸选项,请参阅 TCPDF example 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;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-28
      • 1970-01-01
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 2019-03-19
      • 2022-01-01
      相关资源
      最近更新 更多