fpdf - 返回上一页

时间:2009-10-22 18:41:53

标签: php pdf fpdf

我使用fpdf生成pdf发票。

一些发票包含许多项目,详细信息需要进入第二页。但是,我需要在第一页上显示总数和其他详细信息。

现在,如果我可以像这样添加新页面: $ PDF-> AddPage();

但是,无论在此声明之后,这都会将所有内容放入第二页。

似乎没有办法为write或cell方法指定页面。

渲染,计算有点复杂,因此不希望在完全渲染第一页后存储到临时数组中并显示。

谢谢。

9 个答案:

答案 0 :(得分:5)

我遇到了一个非常类似的问题,我继续将该功能添加到课程中:

function SetPage($num) {
    $this->page = $num;
}

这确实是你所期望的。但是,当您尝试返回下一页时,您需要显式设置它或添加到Cell()功能。这是添加页面的地方:

    if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())

这会检查AcceptPageBreak,显然,如果我们留在页面上,页面的高度是否小于我们最终的位置。我所做的是在这里添加一个条件来检查下面是否有另一页。如果有,而不是添加新页面,我继续前进,只是将我的Y设置为我的边距,并使用上述功能访问该页面。就这样:

if ($this->page < count($this->pages)) {
        $this->SetPage(($this->page)+1);
        $this->y = .5;
    }

如果你对使用FPDF感到不舒服,这可能不适合你,但是我解决这个问题后的实现实际上是脚本很容易导航并为简单的改进留下了很大的空间。请注意,您可以添加一个可以调用的变量,而不是在上面检查另一个页面,这个变量会暂时告诉脚本,而不是添加页面,只需跳转到下一个。

答案 1 :(得分:3)

FPDF不允许您返回上一页。一旦你完成了一个页面 - 通过调用AddPage()或者在打开SetAutoPageBreak()时耗尽空间 - 你已经完成了它。

解决方法是生成没有总计的文档,将其写入临时文件然后加载回来(使用FPDI:http://www.setasign.de/products/pdf-php-solutions/fpdi/)并在正确的位置添加总计。

答案 2 :(得分:3)

if(!empty($this->replace) && !empty($this->replacement)){
    $this->pages[$n]=str_replace($this->replace,$this->replacement,$this->pages[$n]);
}

我将此代码添加到_putpages()中的fpdf类,位于/ Page content line 2851下面

将以上内容添加到代码后的示例:

$pdf->replace = array("{paid_msg}","{balance}");
$pdf->replacement = array("Paid","0.00");

它可以是字符串或数组。

答案 3 :(得分:1)

我使用了 Radley Sustaire 的回答(谢谢),效果很好。 我想为那些无法正常工作的人添加这个:

  1. 将公共函数添加到 FPDF 源 (fpdf.php)
  2. 当您想返回不同页面的不同 Y-Pos 时,您可以使用数组来跟踪着陆点:
    $startPos[] = $pdf->GetVerticalPosition();
  1. 要返回某个页面,您可以使用:
    $pdf->SetVerticalPosition( $startPos[0] );

[0] -> 数组中的第一页/Ypos
[1] -> 数组中的第二页/Ypos
[n] -> 数组中的 n+1 页/Ypos

答案 4 :(得分:0)

这里有一些聪明的解决方案,但我不推荐这种技巧,因为它违背了基本的FPDF模型,迟早可能会导致其他问题。

编程已经很复杂了!

因此,将发票的模型或其中的任何内容与演示文稿分开。构建整个模型。然后输出演示文稿(本例中为PDF)。

答案 5 :(得分:0)

我发现非常适合* str_replace *方法,因为需要写m页&#34; n#34;。在我构建每一页时,首先正常编写n编号,最后逐页替换$ pdf-&gt; pages [$ i]中的m密码。

答案 6 :(得分:0)

我通过两列布局遇到了这个问题,其中一列可能会很大,它会跨越到下一页。我想将Y位置设置回与第一列相同的Y位置,以便它们彼此对齐,但也可以在两列中最大的列下继续文档。

我的解决方案是记录&#34;垂直位置&#34;该文档包含页码($pdf->PageNo())和Y位置($pdf->GetY())。

您需要存储两个不同的垂直位置。首先,存储&#34;起点&#34;这是你开始第二列的地方。第二,存储最大点&#34;这是文件中最远的。最重要的一点是棘手的,因为你不能单独查看页码或Y值,你必须同时查看它们。

我创建了这三种方法来帮助我。

此解决方案在示例中不包含X位置。

public function GetVerticalPosition() {
  // Include page and Y position of the document
  return array(
    'page' => $this->PageNo(),
    'y' => $this->GetY(),
  );
}

public function SetVerticalPosition( $pos ) {
  // Set the page and Y position of the document
  $this->page = $pos['page'];
  $this->SetY( $pos['y'] );
}

public function FurthestVerticalPosition( $aPos, $bPos = null ) {
  if ( $bPos === null ) $bPos = $this->GetVerticalPosition();

  // Returns the "furthest" vertical position between two points, based on page and Y position
  if ( 
    ($aPos['page'] > $bPos['page']) // Furthest position is located on another page
    ||
    ($aPos['page'] == $bPos['page'] && $aPos['y'] > $bPos['y'] ) // Furthest position is within the same page, but further down
  ) {
    return $aPos;
  }else{
    return $bPos;
  }
}

用法非常简单。在绘制可变高度列之前,您需要抓住起始位置,并开始收集最大位置。

$startPos = $this->GetVerticalPosition();
$furthestPos = $this->GetVerticalPosition();

渲染每个单元格之后,在渲染同一级别的另一个单元格之前,您想要更新最远的位置(如果需要),然后设置回起始位置。

// Returns the furthest of the two possibilites
$furthestPos = $this->FurthestVerticalPosition( $this->GetVerticalPosition(), $furthestPos );
$this->SetVerticalPosition( $startPos );

完成列的渲染后,将文档设置为到目前为止记录的最大距离。

$this->SetVerticalPosition( $furthestPos );

现在您的列已正确对齐,文档指针位于最远绘制的列之后。

答案 7 :(得分:0)

我有同样的问题,我覆盖了FPDF类的一些方法,并且能够以相当简单的方式修复它。要往返页面,您只需更改FPDF对象的页面属性即可。但是,一旦您返回页面,当您进入下一页时,您将最终添加新页面而不是进入现有页面。为了解决这个问题,我创建了一个名为add_new_page的布尔值,并在我重写的accept_page_break方法中使用它来查看是否要创建新页面或进度到现有页面。

def prev_page(self):
    self.page -= 1
    self.add_new_page = False

def next_page(self):
    self.page += 1

def accept_page_break(self):
    "Accept automatic page break or not"
    if self.add_page:
        return self.auto_page_break
    else:
        self.page += 1
        self.add_new_page = True

答案 8 :(得分:0)

只是一个简单的“黑客”,但数据需要按页码排序(不是很难^ ^)

放入“for循环”放置数据:

// ensure we are on the good page, but fields HAVE TO be ordered by page number
while($this->fpdf->PageNo() != $myData->getPage()){
    $this->fpdf->AddPage();
}

你完成了!无需改变FPDF:D