php tcpdf分页问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2092089/
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
Problem with tcpdf Pagebreak
提问by fillibuster
I have a little problem with a pagebreak. The Multicell is displayed over the footer of the first page and then it breaks: How can I set the bottom margin of the page so that the break happened earlier above? Here is the example PDF: Exampleand here the sourcecode:
我有一个分页符的小问题。多单元格显示在第一页的页脚上,然后中断:如何设置页面的底部边距,以便中断发生在上面?这是示例 PDF:示例和源代码:
<?php require_once('../tcpdf/config/lang/eng.php');
require_once('../tcpdf//tcpdf.php');
class MYPDF extends TCPDF {
public function Header() {
$auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false,0);
$this->setJPEGQuality(100); $img_file = 'images/mandanten/ce_background.jpg';
$this->Image($img_file, $x=160, $y=72, $w=36, $h=200, $type='', $link='', $align='', $resize=true, $dpi=150, $palign='', $ismask=false, $imgmask=false, $border=0);
$this->SetAutoPageBreak($auto_page_break); }
}
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor('tmpAutor');
$pdf->SetTitle('tmpTitle'); $pdf->SetSubject('tmpSubject');
$pdf->SetKeywords('tmp'); $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(True, PDF_MARGIN_BOTTOM);
//set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
//set some language-dependent strings
$pdf->setLanguageArray($l); $pdf->AddPage();
$pdf->SetFont('freesans', '', 16);
$pdf->Cell(0, 10, 'Headline', 0, 1, 'L');
$pdf->SetFont('freesans', '', 11);
// Some Dummy Unicode content
$tmp = 'Lorèm ìpsum dolor sìt ?mèt, ?onsètètur s?dìps?ìng èlìtr, sèd dì?m nonumy èìrmod tèmpor ìnvìdunt ut l?borè èt dolorè m?gn? ?lìquy?m èr?t, sèd dì?m voluptu?. ?t vèro èos èt ???us?m èt justo duo dolorès èt è? rèbum. Stèt ?lìt? k?sd gubèrgrèn, no sè? t?kìm?t? s?n?tus èst Lorèm ìpsum dolor sìt ?mèt. Lorèm ìpsum dolor sìt ?mèt, ?onsètètur s?dìps?ìng èlìtr, sèd dì?m nonumy èìrmod tèmpor ìnvìdunt ut l?borè èt dolorè m?gn? ?lìquy?m èr?t, sèd dì?m voluptu?. ?t vèro èos èt ???us?m èt justo duo dolorès èt è? rèbum. Stèt ?lìt? k?sd gubèrgrèn, no sè? t?kìm?t? s?n?tus èst Lorèm ìpsum dolor sìt ?mèt.w?èdr';
$pdf->MultiCell(140, 0, $tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp, 0, 'J', 0, 0, '', '', true, 0,true);
$pdf->Output('example_051.pdf', 'I');
回答by ChuckO
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER); $pdf->SetAutoPageBreak(True, PDF_MARGIN_BOTTOM);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER); $pdf->SetAutoPageBreak(True, PDF_MARGIN_BOTTOM);
Have you tried:
你有没有尝试过:
$pdf->SetAutoPageBreak(True, PDF_MARGIN_FOOTER);
or
或者
$pdf->SetAutoPageBreak(True, where_I_want_break);
回答by Chance
Like Jason,
像杰森一样,
I also use the checkPageBreak() function. I am using version 5.9.113 of tcpdf. I had to modify the changePageBreak() function from protected to public. Then in a loop that output each row of data from a database table using MultiCell() with custom width cells, I check for new page, handle accordingly, and it works like a charm. I do not have to use transaction methods to handle new pages.
我也使用 checkPageBreak() 函数。我正在使用 tcpdf 的 5.9.113 版。我不得不将 changePageBreak() 函数从 protected 修改为 public。然后在使用 MultiCell() 和自定义宽度单元格输出数据库表中的每一行数据的循环中,我检查新页面,进行相应处理,它就像一个魅力。我不必使用事务方法来处理新页面。
Here is an excerpt of the looping code that handles it all:
这是处理这一切的循环代码的摘录:
while($data = mysql_fetch_assoc($result))
{
$pdf->MultiCell(20,6,$data['date'],0,'C',0,0);
$pdf->MultiCell(40,6,$data['refnumber'],0,'C',0,0);
$pdf->MultiCell(66,6,$data['memo'],0,'L',0,0);
$pdf->MultiCell(20,6,$data['linetotal']),0,'R',0,0);
$pdf->Ln();
if($pdf->checkPageBreak()) $pdf->Ln();
}
The checkPageBreak() function returns true when a new page is added. When this is the case, you can perform any additional tasks needed as I did with a new line.
添加新页面时,checkPageBreak() 函数返回true。在这种情况下,您可以执行所需的任何其他任务,就像我对新行所做的那样。
Hope this helps someone else with this MutliCell and custom width issue.
希望这可以帮助其他人解决此 MutliCell 和自定义宽度问题。
Chance
机会
回答by ssdscott
Same issue here, using version 6.2.0 of the library (so sad to report that rumors that this has been fixed are premature). I liked dwayne towell's approach with Ln, but am nervous about such a systemic change - there may be a subtle MultiCell behavior that gets broken... I also liked Chance's idea of just calling checkPageBreak inside the loop. I found this question while searching to see if TCPDF had a "keep together" option.
同样的问题,使用库的 6.2.0 版(很遗憾,有传言说这已经被修复还为时过早)。我喜欢 dwayne towell 对 Ln 的方法,但对这种系统性变化感到紧张 - 可能有一个微妙的 MultiCell 行为被破坏了......我也喜欢 Chance 的想法,即在循环内调用 checkPageBreak 。我在搜索 TCPDF 是否有“保持在一起”选项时发现了这个问题。
I have my own class derived from TCPDF (a burned-too-many-times bias against modifying libraries, I prefer to override), and added this method:
我有我自己的从 TCPDF 派生的类(对修改库的多次偏见,我更喜欢覆盖),并添加了这个方法:
/**
* Keep the next segment together on one page
* @param $height (float) the height of the lines to print together
*/
public function keepTogether($height) {
$this->checkPageBreak($height);
}
I've updated my printing code to include above the print-each-record loop:
我已经更新了我的打印代码以包含在 print-each-record 循环之上:
// getStringHeight ($w, $txt, $reseth=false, $autopadding=true, $cellpadding='', $border=0)
$lineHeight = $this->pdf_printer->getStringHeight(0, 'Test', false, true, '', 1);
and then at the top of the loop
然后在循环的顶部
$this->pdf_printer->keepTogether($lineHeight);
This works for me. The print loop uses MultiCell because I need to tweak font sizes in different columns. So I don't have to switch to HTML just to get a better printout.
这对我有用。打印循环使用 MultiCell,因为我需要调整不同列中的字体大小。所以我不必为了获得更好的打印输出而切换到 HTML。
回答by Dwayne Towell
The problem is in Ln(). It does not perform a checkPageBreak(). Change the following lines at the end of Ln():
问题出在Ln(). 它不执行checkPageBreak(). 更改末尾的以下几行Ln():
if (is_string($h)) {
$this->y += $this->lasth;
} else {
$this->y += $h;
}
to these:
到这些:
if (is_string($h))
$h = $this->lasth;
if (!$this->checkPageBreak($h))
$this->y += $h;
I opened a patch ticketon it.
我在上面开了一张补丁票。
回答by Dan
Had the same issue, but used a method from one of the tcpdf examples that sets the autopagebreak off, writes out the cell, and then turns autopagebreak back on:
有同样的问题,但使用了 tcpdf 示例之一中的方法,该方法将 autopagebreak 设置为关闭,写出单元格,然后重新打开 autopagebreak:
public function WriteCellText( $CellValue, $x, $y,$w, $h){
$bMargin = $this->getBreakMargin();
$auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0);
$this->SetXY($x, $y, true);
$this->Cell($w,$h, $CellValue, 0, 0, 'L', 0, '', 0, true);
$this->SetAutoPageBreak($auto_page_break, $bMargin);
}
回答by Sumod Nair
Pleas try the writeHTMLCell function instead of MultiCell
请尝试使用 writeHTMLCell 函数而不是 MultiCell
change
改变
$pdf->MultiCell(140, 0, $tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp."<br><br>".$tmp, 0, 'J', 0, 0, '', '', true, 0,true);
to
到
$this->writeHTMLCell(0, 25, 25, 250,'Footer value', 0, 0, 0, true, 'C', true);
回答by Sumod Nair
Or else you can override the TCPDF footer method like,
否则,您可以覆盖 TCPPDF 页脚方法,例如,
// Position at 15 mm from bottom
$this->SetY(-15);
// Set font
$this->SetFont('helvetica', 'B', 8);
//Userdefind Function -Testing
$pg_num = $this->getPage();
$page_height = $this->getPageHeight();
$ph = $page_height;
$this->writeHTMLCell(0, 25, 25, $ph-19.4,'footer data', 0, 0, 0, true, 'C', true);
$this->writeHTMLCell(0, 25, 25, $ph-9.4,'footer data', 0, 0, 0, true, 'L', true);
回答by JasonMichael
I got around this problem by using the checkPageBreak method, using a while loop. I'm using PHP 4, though. In PHP5, checkPageBreak is a private method. I think its worthwhile that we request it be made public, so that we can get more conttrol over the pages.
我通过使用 checkPageBreak 方法和 while 循环解决了这个问题。不过,我使用的是 PHP 4。在 PHP5 中,checkPageBreak 是一个私有方法。我认为我们要求将其公开是值得的,以便我们可以更好地控制页面。
I also used the transaction methods so that after checking if I reached a point close to the max page height, I rolled back the transaction and did addPage().
我还使用了事务方法,以便在检查是否达到接近最大页面高度的点后,回滚事务并执行 addPage()。
I'll get a copy of my loop here sometime soon. This is a great library, but the auto page break is a pain with the multi-cell features.
我很快就会在这里得到我的循环的副本。这是一个很棒的库,但是自动分页对于多单元格功能来说很痛苦。
-Jason
-杰森
回答by Yelnar
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
...
$pdf->SetMargins(10, 10, 10);
$pdf->SetAutoPageBreak(true, 10);
foreach($array as $item)
{
$pdf->AddPage(); //add new page for new item
$txt = some_long_long_text;
$pdf->Write(0, $txt, '', 0, 'C', true);
$pdf->endPage(); //do end of page
$pdf->lastPage(); //set cursor at last page, because autopagebreak not do it
}
In example, you have 10 pupils in array, and you need create resume for each. In exam, one resume have 3 pages. So in out u get pdf with 30 pages, with correct text.
例如,您有 10 个学生,您需要为每个学生创建简历。在考试中,一份简历有3页。因此,您将获得 30 页的 pdf,并带有正确的文本。
p.s Sry for my English.
ps Sry 我的英语。
回答by Julien Gustin
The blank page is not really a real new page because when you add a page, you're still on the white page. So following fixes the problem :
空白页并不是真正的新页面,因为当您添加页面时,您仍然在白页上。因此,以下解决了问题:
$this->pdf->AddPage('P', 'A4');
$this->pdf->deletePage($this->pdf->getNumPages());

