代码之家  ›  专栏  ›  技术社区  ›  Natkeeran

fpdf-返回上一页

  •  3
  • Natkeeran  · 技术社区  · 15 年前

    我正在使用fpdf生成PDF发票。

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

    现在,如果我可以添加这样的新页面: $pdf->addpage();

    但是,这把所有的东西都放到了第二页,不管是在这句话之后。

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

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

    谢谢您。

    8 回复  |  直到 7 年前
        1
  •  3
  •   Brad Mace Mike King    14 年前
    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");
    

    它可以是字符串或数组。

        2
  •  5
  •   Jared Alessandroni    12 年前

    我有一个非常类似的问题,我继续讲,只是在课堂上添加了函数:

    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,这可能不适合你,但我在解决这个问题后意识到,脚本非常容易导航,并且为简单的改进留下了很大的空间。请注意,您不必在上面检查另一个页面,而是可以添加一个变量,您可以调用该变量临时告诉脚本,您只需跳到下一个页面,而不必添加页面。

        3
  •  3
  •   Chris Newman    15 年前

    fpdf不允许您返回上一页。一旦你完成了一个页面——或者通过调用addpage()或者在setautopagebreak()打开时耗尽空间——你就完成了。

    解决方法是生成不包含总计的文档,将其写入临时文件,然后重新加载(使用fpdi: http://www.setasign.de/products/pdf-php-solutions/fpdi/ )把总数加在正确的地方。

        4
  •  0
  •   Marc Rochkind    12 年前

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

    编程已经足够复杂了!

    所以,把发票的模型或者它是什么从展示中分离出来。构建整个模型。然后输出演示文稿(本例中为PDF)。

        5
  •  0
  •   Sergio del Río    12 年前

    我发现*str_replace*方法非常合适,因为需要写“n of m pages”。在我构建每一页时,首先正常地写下n个数字,最后逐页替换$pdf->pages[$i]中的m密码。

        6
  •  0
  •   Radley Sustaire    11 年前

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

    我的解决方案是记录文档的“垂直位置”,其中包括页码( $pdf->PageNo() )以及Y位置( $pdf->GetY() )

    您需要存储两个不同的垂直位置。首先,存储“起始点”,在这里您将开始第二列。第二,存储文档最下面的“最大点”。最大点很棘手,因为您不能单独查看页码或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
  •   Viraj    8 年前

    我有同样的问题,我克服了fpdf类的一些方法,并且能够以一种相当简单的方式解决它。为了来回浏览页面,只需更改fpdf对象的页面属性。但是,一旦您返回一个页面,当您进入下一个页面时,您将添加一个新页面,而不是进入已经存在的页面。为了解决这个问题,我创建了一个名为“添加新页面”的布尔值,并在重写的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
  •   Léonard.    7 年前

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

    放入“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