【问题标题】:How to fill PDF form in php如何在php中填写PDF表单
【发布时间】:2012-02-26 17:28:42
【问题描述】:

我有很多 PDF 表单,我需要用我已经拥有的数据在 php 中填写它们。

这里只是一个sample PDF form,我想用php填写这个表格。我已经在数据库中的数据。我只想填写这张表格并保存。

我正在使用 PHP Zend 框架。

我想要的只是当我从我的网站下载这些表格时,它会使用我已有的信息预先填写 pdf 表格中的所有字段。

请帮帮我。

【问题讨论】:

    标签: php forms zend-framework pdf


    【解决方案1】:

    致电pdftk 是实现此目的的好方法。我假设您知道如何execute an external program 并忽略它。

    首先,从您的 PDF 创建一个FDF 文件。

    pdftk form.pdf generate_fdf output data.fdf
    

    您现在可以将其用作模板。您提供的示例如下所示:

    %FDF-1.2
    %<E2><E3><CF><D3>
    1 0 obj 
    <<
    /FDF 
    <<
    /Fields [
    <<
    /V ()
    /T (Date)
    >> 
    <<
    /V /
    /T (CheckBox2)
    >> 
    <<
    /V /
    /T (CheckBox3)
    >> 
    <<
    /V /
    /T (CheckBox4)
    >> 
    <<
    /V /
    /T (CheckBox5)
    >> 
    <<
    /V ()
    /T (Your_Last_Name)
    >> 
    <<
    /V ()
    /T (Your_First_Name)
    >> 
    <<
    /V /
    /T (CheckBox1)
    >>]
    >>
    >>
    endobj 
    trailer
    
    <<
    /Root 1 0 R
    >>
    %%EOF
    

    这些字段是以/V () 开头的行。在这些字段中输入您想要的值。例如:

    %FDF-1.2
    %<E2><E3><CF><D3>
    1 0 obj 
    <<
    /FDF 
    <<
    /Fields [
    <<
    /V (February 4, 2012)
    /T (Date)
    ...
    

    最后,将 FDF 与 PDF 合并。执行命令:

    pdftk form.pdf fill_form data.fdf output form_with_data.pdf
    

    如果您不需要保留 FDF 和生成的 PDF 文件,您可以简单地通过 stdin 和 stdout 管道传输数据,而不是使用临时文件。

    【讨论】:

    • 非常感谢您的回答。我需要你多一点,PDFTK 应该安装在服务器上吗?我没有太多使用PDF,有没有一些例子,或者你能解释一下我如何执行外部程序吗?请帮帮我。
    • 是的,在服务器上安装 pdftk。您可以找到instructions here。要从 PHP 执行系统命令,只需调用 exec 函数。例如。 &lt;?php exec('/usr/bin/pdftk form.pdf fill_form data.fdf output form_with_data.pdf'); ?&gt;
    • 谢谢理查德,我会试试的。谢谢一百万。
    • @RichardAyotte 这是一个很好的发现:) 我必须做同样的事情,但要有所改变。我还需要在其中一个表单字段中包含图像。我该怎么做?
    • 要“勾选” FDF 格式的复选框,请使用/V /Yes
    【解决方案2】:

    我找到了这个,它对我有用。 Zend 填写 FDF 表单域的非官方补丁。Site with the discussion and patch

    无需安装,无需外部程序,无需坐标

    用途:

    $pdf = Zend_Pdf::load('input-file-containing-form.pdf');
    $pdf->setTextField('name', 'Someone');
    $pdf->setTextField('address', '1 Main Street');
    $pdf->setTextField('city', 'Cyberspace');
    $pdf->save('outputfile.pdf');
    

    如果页面不再存在这里是 PDF.php 的补丁(如果有人有问题 - 给我写私信):

    --- Pdf.php.orig    2009-11-15 17:52:57.000000000 +0100
    +++ Pdf.php 2010-01-07 04:05:23.000000000 +0100
    @@ -202,6 +202,13 @@
          * @var array
          */
         protected static $_inheritableAttributes = array('Resources', 'MediaBox', 'CropBox', 'Rotate');
    +    
    +    /**
    +     * List of form fields
    +     *
    +     * @var array - Associative array, key: name of form field, value: Zend_Pdf_Element
    +     */
    +    protected $_formFields = array();
    
         /**
          * Request used memory manager
    @@ -315,6 +322,7 @@
    
                 $this->_loadNamedDestinations($this->_trailer->Root, $this->_parser->getPDFVersion());
                 $this->_loadOutlines($this->_trailer->Root);
    +            $this->_loadFormfields($this->_trailer->Root);
    
                 if ($this->_trailer->Info !== null) {
                     $this->properties = $this->_trailer->Info->toPhp();
    @@ -557,6 +565,61 @@
                 $this->_originalOpenOutlinesCount = $root->Outlines->Count->value;
             }
         }
    +    
    +    /**
    +     * Load form fields
    +     * Populates the _formFields array, for later lookup of fields by name
    +     *
    +     * @param Zend_Pdf_Element_Reference $root Document catalog entry
    +     */
    +    protected function _loadFormFields(Zend_Pdf_Element_Reference $root)
    +    {
    +      if ($root->AcroForm === null || $root->AcroForm->Fields === null) {
    +        return;
    +      }
    +      
    +      foreach ($root->AcroForm->Fields->items as $field)
    +      {
    +          if ( $field->FT->value == 'Tx' && $field->T !== null ) /* We only support fields that are textfields and have a name */
    +          {
    +              $this->_formFields[$field->T->value] = $field;
    +          }
    +      }
    +      
    +      if ( !$root->AcroForm->NeedAppearances || !$root->AcroForm->NeedAppearances->value )
    +      {
    +        /* Ask the .pdf viewer to generate its own appearance data, so we do not have to */
    +        $root->AcroForm->add(new Zend_Pdf_Element_Name('NeedAppearances'), new Zend_Pdf_Element_Boolean(true) );
    +        $root->AcroForm->touch();
    +      }
    +    }
    +    
    +    /**
    +     * Retrieves a list with the names of the AcroForm textfields in the PDF
    +     *
    +     * @return array of strings
    +     */
    +    public function getTextFieldNames()
    +    {
    +      return array_keys($this->_formFields);
    +    }
    +    
    +    /**
    +     * Sets the value of an AcroForm text field
    +     *
    +     * @param string $name Name of textfield
    +     * @param string $value Value
    +     * @throws Zend_Pdf_Exception if the textfield does not exist in the pdf
    +     */
    +    public function setTextField($name, $value)
    +    {
    +      if ( !isset($this->_formFields[$name]))
    +        throw new Zend_Pdf_Exception("Field '$name' does not exist or is not a textfield");
    +      
    +      $field = $this->_formFields[$name];
    +      $field->add(new Zend_Pdf_Element_Name('V'), new Zend_Pdf_Element_String($value) );
    +      $field->touch();      
    +    }
    
         /**
          * Orginize pages to tha pages tree structure.
    

    【讨论】:

    • 谢谢,这正是我想要的!
    • 谢谢,这比安装额外的软件要好得多。我不敢相信这个补丁从来没有进入 Zend 框架。
    • 我刚刚下载了 Zend Framework,补丁已经在里面了……所以现在不需要打补丁了。
    • @GonzaloBrusco 是在完整包中还是只是来自 github 的 Zend PDF 库?我希望在一个项目中只使用 zend pdf,但看起来 zend 依赖项太多了,它本身几乎没用。从我所看到的情况来看,绝对没有这些代码。
    • @Jestep - 我刚刚在这里找到它:github.com/zf1/zend-pdf,它开箱即用,补丁已经在代码中。使用 Composer 很容易安装它和 4 个必需的 Zend 依赖项 - 运行 composer require zf1/zend-pdf 并将 require_once '&lt;path to Composer's vendor dir&gt;/autoload.php'; 添加到需要使用 PDF 功能的文件中。
    【解决方案3】:

    我发现 fpdf 库在互联网上寻找相同的内容。

    http://www.fpdf.org/en/script/script93.php

    代码看起来干净、易于使用和记住它,并且适用于带有表单(可填写)的 pdf。

    <?php
    
    /***************************
      Sample using a PHP array
    ****************************/
    
    require('fpdm.php');
    
    $fields = array(
        'name'    => 'My name',
        'address' => 'My address',
        'city'    => 'My city',
        'phone'   => 'My phone number'
    );
    
    $pdf = new FPDM('template.pdf');
    $pdf->Load($fields, false); // second parameter: false if field values are in ISO-8859-1, true if UTF-8
    $pdf->Merge();
    $pdf->Output();
    ?>
    

    它带有开箱即用的示例。 希望对您有所帮助。

    【讨论】:

    • 我什至用它来使用 from_template 函数加入 pdf 的页面,并且能够打印 150 页文档而不是 150 个 1 页文件。有些系统不允许您选择 150 个文件然后打印它们。上次我在 ie: Windows 中看到它时,我注意到我最多只能选择 15 个……很奇怪。我使用宏记录器将它们全部打印出来,但最终将它们与 fpdf 结合起来更加高效、干净且不易出错。问候。
    • 不支持xfa/xdp,这是Adobe目前使用的表单格式。
    • 项目似乎已经死了,但是,如果项目上没有 PDF 最小版本要求,应该没问题:使用表单创建工具在受支持的版本中创建表单,它应该没问题。我要试试看。
    • 确认这个工作。如网站所述,如果您的 PDF 是较新版本,只需执行 pdftk modele.pdf output modele2.pdf 即可。
    • 有人接手了这个项目,现在在这里更新:github.com/codeshell/fpdm
    【解决方案4】:

    Zend_Pdf-组件可以在您的 pdf 中绘制文本,但它有点笨拙,因为您必须在 pdf 页面上指定 x 和 y 坐标。类似的东西:

    // This is the pdf-file you want to fill out...
    $pdf = Zend_Pdf::load('/path/to/pdf-template.pdf')
    $page = $pdf->pages[0]; // Use first page
    $page->drawText("firstname lastname", 200, 600);
    ...
    $pdf->pages[0] = $page;
    // be sure to write to a new file, not the original empty  form.
    $pdf->save('/path/to/pdf-output.pdf');
    

    我不知道是否有简单的方法可以找到确切的坐标,我通常会玩弄直到合适为止。

    【讨论】:

    • 但这并没有填写 PDF 表单,这对于平面 PDF 来说效果不佳,但现在适用于易出错的 PDF 表单。
    • 我知道,应该提到这一点。但据我所知,这是使用 Zend_Pdf 将文本放入 pdf 的唯一方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2010-09-09
    • 2021-10-26
    • 2018-07-03
    • 1970-01-01
    • 2012-07-26
    相关资源
    最近更新 更多