php MultiCell 元素的 FPDF 高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18356118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
FPDF height of a MultiCell Element
提问by Thomas1703
I use the FPDF library to export some document files as PDF. One document includes a list of strings which have a different length. I print all strings as $pdf->MultiCell()
. Now I would like to have the current height of that MultiCell to have the same line spacing in case that they have just one line or more.
我使用 FPDF 库将一些文档文件导出为 PDF。一个文档包含具有不同长度的字符串列表。我将所有字符串打印为$pdf->MultiCell()
. 现在我想让 MultiCell 的当前高度具有相同的行距,以防它们只有一行或更多行。
Code Example:
代码示例:
//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()
}
回答by
I had the exact same problem; I use FPDF to generate invoices and there are four cells per row with first cell being a MultiCell with varying height (default height is 5, but if order name is too long it adds another line to a total height of 10, and so on). The problem is that the remaining 3 cells have fixed height.
我有同样的问题; 我使用 FPDF 生成发票,每行有四个单元格,第一个单元格是具有不同高度的 MultiCell(默认高度为 5,但如果订单名称太长,则会在总高度为 10 的情况下添加另一行,依此类推) . 问题是剩下的 3 个单元格具有固定的高度。
After looking for solutions it seems the only way is to write a complex function or use some third party tool. Since I want my app to be as light as possible I used the following approach to solve it which in my opinion is way simpler than external plugin.
在寻找解决方案后,似乎唯一的方法是编写复杂的函数或使用某些第三方工具。由于我希望我的应用程序尽可能轻巧,因此我使用以下方法来解决它,在我看来这比外部插件简单得多。
- Rows with details on the Invoice start at Y=95 so I use
$Y=95;
before my while loop My first cell (the MultiCell) is as follows:
$pdf->SetXY(10,$Y); $pdf->MultiCell(60,5,$row['Name'],1,1,'L');
I use the FPDF's GetY() function to get current height and save it as H:
$H = $pdf->GetY();
If the MultiCell's height is 5 GetY() will give back 100, if the height is 10 GetY() gives back 105 and so on.
I add new variable $height:
$height= $H-$Y;
Which as result gives me precisely the height of the MultiCell.
I use $Y and $height to set current position and column height:
$pdf->SetXY(130,$Y); $pdf->Cell(40,$height,$row['RowName'],1,1,'L');
Before finishing the while loop set give $Y the $H's value:
$Y=$H;
- 包含发票详细信息的行从 Y=95 开始,因此我
$Y=95;
在 while 循环之前使用 我的第一个单元格(MultiCell)如下:
$pdf->SetXY(10,$Y); $pdf->MultiCell(60,5,$row['Name'],1,1,'L');
我使用 FPDF 的 GetY() 函数获取当前高度并将其保存为 H:
$H = $pdf->GetY();
如果 MultiCell 的高度为 5 GetY() 将返回 100,如果高度为 10 GetY() 返回 105,依此类推。
我添加新变量 $height:
$height= $H-$Y;
结果就是给了我 MultiCell 的高度。
我使用 $Y 和 $height 来设置当前位置和列高:
$pdf->SetXY(130,$Y); $pdf->Cell(40,$height,$row['RowName'],1,1,'L');
在完成 while 循环集之前,给 $Y 设置 $H 的值:
$Y=$H;
Entire loop looks as follows and works perfectly:
整个循环如下所示并且完美运行:
$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;
}
If you have 2 MultiCell columns or more in each row it gets tricky but still can be solved in a similar manner.
如果每行有 2 个或更多 MultiCell 列,它会变得棘手,但仍然可以以类似的方式解决。
回答by Predrag Damnjanovi?
I found interesting solution here - https://github.com/artkonekt/pdf-invoice/blob/master/src/InvoicePrinter.php#L469
我在这里找到了有趣的解决方案 - 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;
So, he literally create a 'temporary' PDF, add multicell, and then simply measure height (newY - oldY)
因此,他从字面上创建了一个“临时”PDF,添加了多单元格,然后简单地测量高度(newY - oldY)
Also, keep in mind that if text goes to new line - height of cell will be = number_of_lines * $height
(height passed to MultiCell as second parameter)
另外,请记住,如果文本转到新行 - 单元格的高度将为 = number_of_lines * $height
(高度作为第二个参数传递给 MultiCell)
So, if you passed 5 as $height, and temporary PDF measure that cell will be 15, you can be sure that text will spread to 3 lines.
因此,如果您将 5 作为 $height 传递,并且临时 PDF 测量该单元格将为 15,则您可以确定文本将扩展为 3 行。
回答by C4d
I'm coding in golang so I'll show some pseudo-code. I hope the accessible methods are the same in php
as in golang
.
我正在用 golang 编码,所以我将展示一些伪代码。我希望访问的方法是相同的php
作为golang
。
There is a method called pdf.SplitLines(text, width)
. You will pass your string content and the desired width and it will return an array of strings that represents the lines that'll be computed to display that content.
有一种方法叫做pdf.SplitLines(text, width)
。您将传递您的字符串内容和所需的宽度,它将返回一个字符串数组,该数组表示将被计算以显示该内容的行。
With that its easy. In pseudo-code it could look like:
有了它就很容易了。在伪代码中,它可能如下所示:
fontSize = 10;
lineHeight = 12;
targetWidth = 50;
pdf.SetFontSize(fontSize)
nLines = length(pdf.SplitLines(content, targetWidth));
multiCellHeight = nLines * lineHeight;
pdf.Multicell(targetWidth, lineHeight, content, ...)
The rendered MultiCell
will have the exact same size as stored in multiCellHeight
. This way you'll get the hight before rendering.
呈现的MultiCell
大小将与存储在multiCellHeight
. 这样你就可以在渲染之前获得高度。
This is working because the passed height
for the MultiCell
is the lineHeight
of each row. If you know the rows before rendering, you'll get the total height.
这是有效的,因为传递height
的MultiCell
是lineHeight
每一行的。如果您在渲染之前知道行,您将获得总高度。
I'm sorry if this fails for any reason for php
. Just let me know if that's the case.
如果这因任何原因失败,我很抱歉php
。如果是这种情况,请告诉我。