【问题标题】:FPDF height of a MultiCell ElementMultiCell 元素的 FPDF 高度
【发布时间】:2013-08-21 11:24:39
【问题描述】:

我使用 FPDF 库将一些文档文件导出为 PDF。一个文档包括具有不同长度的字符串列表。我将所有字符串打印为$pdf->MultiCell()。现在我想让 MultiCell 的当前高度具有相同的行距,以防它们只有一行或多行。

代码示例:

//MySQL Query
while($row = mysql_fetch_array($res) {
   $pdf->SetXY(18, $x);
   $pdf->MultiCell(80, 5, $rowr['text']); //text has one or more lines
   $x = $x + 10; // Here I would prefer a solution to say: $x = $x + 2 + height of the MultiCell()
}

【问题讨论】:

  • 你到底想做什么?你说你需要高度,但是你动态设置x坐标,你想得到宽度吗?如果要获取单元格的高度,请在MultiCell()前后调用getY()

标签: php fpdf


【解决方案1】:

我遇到了完全相同的问题;我使用 FPDF 生成发票,每行有四个单元格,第一个单元格是具有不同高度的 MultiCell(默认高度为 5,但如果订单名称太长,它会在总高度 10 中添加另一行,依此类推) .问题是剩下的 3 个单元格的高度是固定的。

在寻找解决方案之后,似乎唯一的方法是编写一个复杂的函数或使用一些第三方工具。由于我希望我的应用程序尽可能轻巧,因此我使用了以下方法来解决它,我认为这比外部插件要简单得多。

  1. 发票详细信息的行从 Y=95 开始,所以我使用 $Y=95; 在我的 while 循环之前
  2. 我的第一个单元格(MultiCell)如下:

    $pdf->SetXY(10,$Y);
    $pdf->MultiCell(60,5,$row['Name'],1,1,'L');
    
  3. 我使用 FPDF 的 GetY() 函数获取当前高度并将其保存为 H:

    $H = $pdf->GetY();
    

    如果 MultiCell 的高度为 5,GetY() 将返回 100,如果高度为 10,GetY() 将返回 105,依此类推。

  4. 我添加了新变量 $height:

    $height= $H-$Y;
    

    结果正好给了我 MultiCell 的高度。

  5. 我使用 $Y 和 $height 来设置当前位置和列高:

    $pdf->SetXY(130,$Y);
    $pdf->Cell(40,$height,$row['RowName'],1,1,'L');
    
  6. 在完成while循环集之前给$Y $H的值:

    $Y=$H;
    

整个循环如下所示并且完美运行:

$Y= 95;

$query = mysqli_query($con,"SELECT * FROM table");

while($row = mysqli_fetch_array($query)) {
    $pdf->SetXY(10,$Y);
    $pdf->MultiCell(60,5,$row['ROW1'],1,1,'L');

    $H = $pdf->GetY();
    $height= $H-$Y;

    $pdf->SetXY(70,$Y);
    $pdf->Cell(60,$height,$row['ROW2'],1,1,'L');
    $pdf->SetXY(130,$Y);
    $pdf->Cell(40,$height,$row['ROW3'],1,1,'L');
    $pdf->SetXY(170,$Y);
    $pdf->Cell(30,$height,$row['ROW4'],1,1,'L');

    $Y=$H;
}

如果每行有 2 个或更多 MultiCell 列,这会变得很棘手,但仍然可以用类似的方式解决。

【讨论】:

    【解决方案2】:

    我在这里找到了有趣的解决方案 - https://github.com/artkonekt/pdf-invoice/blob/master/src/InvoicePrinter.php#L469

    $calculateHeight = new self;
    $calculateHeight->addPage();
    $calculateHeight->setXY(0, 0);
    $calculateHeight->SetFont($this->font, '', 7);
    $calculateHeight->MultiCell($this->firstColumnWidth, 3, $item['description'], 0, 'L', 1);
    $descriptionHeight = $calculateHeight->getY() + $cellHeight + 2;
    

    因此,他确实创建了一个“临时”PDF,添加了多单元格,然后简单地测量高度 (newY - oldY)

    另外,请记住,如果文本换行 - 单元格的高度将为 = number_of_lines * $height(高度作为第二个参数传递给 MultiCell)

    因此,如果您将 5 作为 $height 传递,并且临时 PDF 测量该单元格将为 15,您可以确定文本将扩展到 3 行。

    【讨论】:

      【解决方案3】:

      我正在使用 golang 进行编码,所以我将展示一些伪代码。我希望phpgolang 中的可访问方法相同。

      有一个方法叫做pdf.SplitLines(text, width)。您将传递您的字符串内容和所需的宽度,它将返回一个字符串数组,该数组表示将被计算以显示该内容的行。

      这样就很容易了。在伪代码中它可能看起来像:

      fontSize = 10;
      lineHeight = 12;
      targetWidth = 50;
      pdf.SetFontSize(fontSize)
      nLines = length(pdf.SplitLines(content, targetWidth));
      
      multiCellHeight = nLines * lineHeight;
      pdf.Multicell(targetWidth, lineHeight, content, ...) 
      

      呈现的MultiCell 将具有与multiCellHeight 中存储的完全相同的大小。这样您就可以在渲染之前获得高度。

      这是有效的,因为传递给MultiCellheight 是每一行的lineHeight。如果您在渲染前知道行,您将获得总高度。


      如果php 因任何原因失败,我很抱歉。如果是这样,请告诉我。

      【讨论】:

      • 我正在尝试用 GoFPDF 做这样的事情,但是....
      【解决方案4】:

      打印文本时不使用寄宿生不是更容易吗?

      你可以使用 $pdf->GetY();获取当前的 y 值。

      然后当你打印完所有文本后,你可以使用 $pdf->GetY();获取每段文本之后的高度。比较 y 值,看看哪个最大。

      那么你需要做的就是 $pdf-> SetY($y);到原始 y 值并使用 $pdf->Cell() 绘制边界,因为您知道高度和宽度;

      我就是这样做的。

      编辑:测试它,似乎工作。现在和我一起唱歌——“你得到了两全其美……”不是吗?

      $cellData = array();
      $cellData[0] = array();
      $cellData[0][0] = array();
      $cellData[0][0]['text'] = 'Audiometry';
      $cellData[0][0]['width'] = '47';
      
      $cellData[0][1] = array();
      $cellData[0][1]['text'] = 'Control of Noise at Work Regulations 2005.';
      $cellData[0][1]['width'] = '47';
      
      $cellData[0][2] = array();
      $cellData[0][2]['text'] = 'Fit with restrictions (as detailed below) to work in a noise controlled zone.';
      $cellData[0][2]['width'] = '47';
      
      $cellData[0][3] = array();
      $cellData[0][3]['text'] = 'Recommended review date: 2021-11-27
      
      Referral: Referred to OHP';
      $cellData[0][3]['width'] = '47';
      
      setAllCellSizes($cellData, $pdf);
      
      function setAllCellSizes($cellData, $pdf){
      $y = $pdf->GetY();
      $x = $pdf->GetX();
      
      $largestCell = 0;
      for($cordI = 0; $cordI < count($cellData); $cordI++){
          $curX = 10;
          for($cordJ = 0; $cordJ < count($cellData[$cordI]); $cordJ++){
              $pdf->SetXY($curX,$y);
              $pdf-> MultiCell($cellData[$cordI][$cordJ]['width'], 5, $cellData[$cordI][$cordJ]['text'], '0', 'L');
              $curX = $curX + $cellData[$cordI][$cordJ]['width'];
      
              $cellHeight = $pdf->GetY() - $y;
      
              if($largestCell < $cellHeight){
                  $largestCell = $cellHeight;
              }
          }
      
          $curX = 10;
          for($cordJ = 0; $cordJ < count($cellData[$cordI]); $cordJ++){
              $pdf->SetXY($curX,$y);
              $pdf->Cell($cellData[$cordI][$cordJ]['width'],$largestCell,'',1,1,'L');
              $curX = $curX + $cellData[$cordI][$cordJ]['width'];
          }
      }
      
      return $cellData;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-20
        • 1970-01-01
        • 2012-11-13
        • 1970-01-01
        • 2013-12-29
        • 2013-03-01
        • 1970-01-01
        • 2010-11-28
        相关资源
        最近更新 更多