tcpdf 分页问题

发布于 2024-08-17 23:48:52 字数 2841 浏览 10 评论 0原文

我在分页时遇到了一个小问题。多单元显示在第一页的页脚上,然后中断:如何设置页面的下边距,以便中断发生在上面?以下是示例 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');

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: Example and here the sourcecode:

<?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');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

深者入戏 2024-08-24 23:48:52

$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(True, PDF_MARGIN_BOTTOM);

您是否尝试过:

      $pdf->SetAutoPageBreak(True, PDF_MARGIN_FOOTER);

      $pdf->SetAutoPageBreak(True, where_I_want_break);

$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);
夜吻♂芭芘 2024-08-24 23:48:52

和 Jason 一样,

我也使用 checkPageBreak() 函数。
我正在使用 tcpdf 版本 5.9.113。
我必须将changePageBreak() 函数从受保护修改为公共。
然后,在使用具有自定义宽度单元格的 MultiCell() 输出数据库表中的每一行数据的循环中,我检查新页面,进行相应的处理,它的工作方式就像一个魅力。
我不必使用事务方法来处理新页面。

下面是处理这一切的循环代码的摘录:

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();
    }

添加新页面时 checkPageBreak() 函数返回 true。在这种情况下,您可以执行所需的任何其他任务,就像我对新行所做的那样。

希望这可以帮助其他人解决这个 MutliCell 和自定义宽度问题。

机会

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.

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.

Hope this helps someone else with this MutliCell and custom width issue.

Chance

云淡月浅 2024-08-24 23:48:52

同样的问题,使用该库的 6.2.0 版本(很遗憾地报告,有关此问题已得到修复的传言还为时过早)。我喜欢 dwayne towell 的 Ln 方法,但对这样的系统性变化感到紧张 - 可能会出现微妙的 MultiCell 行为被破坏...我也喜欢 Chance 的想法,即在循环内调用 checkPageBreak。我在搜索 TCPDF 是否有“保持在一起”选项时发现了这个问题。

我有自己的从 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);
}

我已更新我的打印代码以包含在打印每个记录循环之上:

// getStringHeight ($w, $txt, $reseth=false, $autopadding=true, $cellpadding='', $border=0)
$lineHeight = $this->pdf_printer->getStringHeight(0, 'Test', false, true, '', 1);

然后在循环的顶部

$this->pdf_printer->keepTogether($lineHeight);

这对我有用。打印循环使用 MultiCell 因为我需要调整不同列中的字​​体大小。因此我不必为了获得更好的打印输出而切换到 HTML。

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.

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:

/**
 * 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:

// 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.

待天淡蓝洁白时 2024-08-24 23:48:52

遇到了同样的问题,但使用了 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);
    }

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:

    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);
    }
醉梦枕江山 2024-08-24 23:48:52

问题出在 Ln() 中。它不执行 checkPageBreak()。将 Ln() 末尾的以下行更改

    if (is_string($h)) {
        $this->y += $this->lasth;
    } else {
        $this->y += $h;
    }

为:

    if (is_string($h))
        $h = $this->lasth;
    if (!$this->checkPageBreak($h))
       $this->y += $h;

我打开了 补丁票就可以了。

The problem is in Ln(). It does not perform a checkPageBreak(). Change the following lines at the end of 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 ticket on it.

a√萤火虫的光℡ 2024-08-24 23:48:52

对于分页 TCPDF 库仍然遇到相同问题的人,

  • 您可以使用



在 HTML 内容中手动中断页面。请记住,TCPDF 只接受标签属性的双引号 (")。不要对标签使用单引号 (')。

使用 $tcpdf- >AddPage() 在代码中手动分页

  • 当您设置 SetAutoPageBreak(TRUE, 10); 时,这意味着:当文档的高度达到 (bottom - 10) 时。因此,如果您想要更多空间,只需将数字减少到0即可将光标移动到新页面。它将绘制到文档末尾,底部没有任何边距。

For someone who still has the same problem with page-break TCPDF library

  • You can use <div style="page-break-before:always"></div>
    OR <br pagebreak="true"/>

to break page manually in your HTML content. Remember that TCPDF only accept the double quote (") for attributes of tags. Don't use single quote (') for your tag.

Use $tcpdf->AddPage() to break page manually in your code.

  • When you set SetAutoPageBreak(TRUE, 10); that means: when the height of document reach to (bottom - 10) then move the cursor to new page. So if you want to have more space, just reduce the number into 0. It will draw until the end of the document without any margin from bottom.
小巷里的女流氓 2024-08-24 23:48:52

我通过使用 checkPageBreak 方法和 while 循环解决了这个问题。不过我使用的是 PHP 4。在 PHP5 中,checkPageBreak 是一个私有方法。我认为我们要求将其公开是值得的,这样我们就可以更好地控制页面。

我还使用了事务方法,以便在检查是否达到接近最大页面高度的点后,我回滚事务并执行 addPage()。

我很快就会在这里得到我的循环的副本。这是一个很棒的库,但自动分页对于多单元功能来说是一个痛苦。

-杰森

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.

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().

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

柒夜笙歌凉 2024-08-24 23:48:52

请尝试 writeHTMLCell 函数而不是 MultiCell

更改

$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); 

$this->writeHTMLCell(0, 25, 25, 250,'Footer value', 0, 0, 0, true, 'C', true);

Pleas try the writeHTMLCell function instead of 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);
治碍 2024-08-24 23:48:52

或者您可以重写 TCPDF 页脚方法,例如,

// 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);

Or else you can override the TCPDF footer method like,

// 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);
狂之美人 2024-08-24 23:48:52
    $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
    }

例如,您有 10 名学生,您需要为每个学生创建简历。考试时,一份简历有3页。所以你会得到 30 页的 pdf 文件,其中包含正确的文本。

PS 对不起我的英语。

    $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.

p.s Sry for my English.

森林很绿却致人迷途 2024-08-24 23:48:52

空白页面并不是真正的新页面,因为当您添加页面时,您仍然在白色页面上。因此,以下解决了问题:

$this->pdf->AddPage('P', 'A4');
$this->pdf->deletePage($this->pdf->getNumPages());

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());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文