Skip to content

表单 (AcroForm)

PDF 目前支持两种用于交互式收集用户信息的表单类型:AcroForms 和 XFA forms。

AcroForms 是基于 PDF 规范的原始可填写表单。福昕 PDF SDK 提供了丰富的 API,允许开发者以编程方式查看和编辑表单域。在 PDF 文档中,表单域是收集用户数据的常用方式。Form 类提供了多种 API,用于获取表单域或表单控件、导入/导出表单数据以及执行其他相关操作。

常用 API (Java 示例):

  • 获取表单域:

    java
    int fieldCount = form.getFieldCount();
    Field field = form.getField(index);

    使用 Form.getFieldCount() 获取表单域的数量,使用 Form.getField(index) 获取指定索引的表单域对象。

  • 获取 PDF 页面中的表单控件:

    java
    int controlCount = form.getControlCount(pdfpage);
    Control control = form.getControl(pdfpage, index);

    使用 Form.getControlCount(pdfpage) 获取指定页面中表单控件的数量,使用 Form.getControl(pdfpage, index) 获取指定页面中指定索引的表单控件对象。

  • 导入/导出表单数据 (XML):

    java
    form.importFromXML();
    form.exportToXML();

    使用 Form.importFromXML(path) 从指定的 XML 文件导入表单数据,使用 Form.exportToXML(path) 将表单数据导出到指定的 XML 文件。

  • 获取 Form Filler 对象:

    java
    FormFiller formFiller = form.getFormFiller();

    使用 Form.getFormFiller() 获取用于交互式填充表单的 FormFiller 对象。

  • 导入/导出表单数据 (FDF/XFDF):

要从 FDF 或 XFDF 文件导入表单数据,或将表单数据导出到 FDF 或 XFDF 文件,请参考 pdf.PDFDoc 类的以下接口:

java
pdfDoc.importFromFDF(fdfDoc, types, page_range);
pdfDoc.exportToFDF(	fdfDoc, types, page_range);

加载 PDF 中的表单

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/fs_pdfform.h"

using namespace foxit;
using namespace pdf;
using namespace interform;
...

// Assuming PDFDoc doc has been loaded.

bool hasForm = doc.HasForm();
if(hasForm)
   Form form(doc);
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfform_c.h"
...

// Assuming FS_PDFDOC_HANDLE doc has been loaded.

FS_BOOL hasForm;
FSDK_PDFDoc_HasForm(doc, &hasForm);
if(hasForm)
    FS_FORM_HANDLE form;
FSDK_Form_Create(doc, &form);
...
java
import com.foxit.sdk.pdf.interform.Form;
...

// Assuming PDFDoc doc has been loaded.
...

Boolean hasForm = doc.hasForm();
if(hasForm)
   Form form = new Form(doc);
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *

...
# Assuming PDFDoc doc has been loaded.

hasForm = doc.HasForm()
if hasForm:
    form = Form(doc)
...
objc
#include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.

BOOL hasform = [doc hasForm];
if(hasform)
  FSForm *form = [[FSForm alloc] initWithDocument:doc];
...
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");

...
// Assuming PDFDoc doc has been loaded.

let hasForm = doc.HasForm()
if(asForm){
    let form = new FSDK.Form(doc)
}
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.interform;
using foxit.pdf.annots;
...

// Assuming PDFDoc doc has been loaded.

Boolean hasForm = doc.HasForm();
If(hasForm)
Form form = new Form(doc);
...

获取表单域个数以及设置其属性

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/interform/fs_pdfform.h"

using namespace foxit;
using namespace pdf;
using namespace interform;

...
// Assuming PDFDoc doc has been loaded.

Form form(doc);
int countFields = form. GetFieldCount(NULL);
for (int i = 0; i < nFieldCount; i++)
{
     Field field = form.GetField(i, filter);
     Field::Type type = field.GetType();
     WString org_alternateName = field.GetAlternateName();
     field.SetAlternateName(L"signature");
}
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfform_c.h"

...
// Assuming FS_PDFDOC_HANDLE doc has been loaded.

FS_FORM_HANDLE form;
FSDK_Form_Create(doc, &form);
int countFields = 0;
FSDK_Form_GetFieldCount(form, NULL, &countFields);
for (int i = 0; i < nFieldCount; i++)
{
     FS_FIELD_HANDLE field;
     FSDK_Form_GetField(form, i, NULL, &field);
     FSFieldType type;
     FSDK_Field_GetType(field, &type);
     FS_WSTR org_alternateName;
     FSDK_Field_GetAlternateName(field, &org_alternateName);
     FSDK_Field_SetAlternateName(field, L"signature");
}
java
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.interform.Form;
import com.foxit.sdk.pdf.interform.Control;
import com.foxit.sdk.pdf.interform.Field;
...

// Assuming PDFDoc doc has been loaded.
...

Form form = new Form(doc);
String filter = "";
            
int nControlCount = form.getFieldCount(filter);
for (int i=0; i<nControlCount; i++)
{
Field field = form.getField(i, filter);
Field.Type type = field.getType();
String fdName = field. getAlternateName ();
field.setAlternateName("signature");
}
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *

...
# Assuming PDFDoc doc has been loaded.

form = Form(doc)
countFields = form.GetFieldCount("")
for i in range(0, countFields):
    field = form.GetField(i, filter)
    type = field.GetType()
    org_alternateName = field.GetAlternateName()
    field.SetAlternateName("signature")
objc
#include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
FSForm *form = [[FSForm alloc] initWithDocument:doc];
int count = [form getFieldCount:@""];
for (int i = 0; i < count; i++) {
    FSField* field = [form getField:i filter:@""];
    FSFieldType field_type = [field getType];
    NSString* name = [field getAlternateName];
    [field setAlternateName:@"signature"];
}
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");

...
// Assuming PDFDoc doc has been loaded.

let form = new FSDK.Form();
let count = form.GetFieldCount("");
for (let i = 0; i < count; i++) {
  let field = form.GetField(i, filter);
  let type = field.GetType();
  let org_alternateName = field.GetAlternateName();
  field.SetAlternateName("signature");
}
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.interform;
using foxit.pdf.annots;
...

// Assuming PDFDoc doc has been loaded.

Form form = new Form(doc);
int count = form.GetFieldCount("");
for (int i = 0; i < count; i++)
{
Field field = form.GetField(i, "");
Field.Type type = field.GetType();
WString org_alternateName = field.GetAlternateName();
field.SetAlternateName("signature");
}

将 PDF 中的表单数据导出到 XML 文件

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/interform/fs_pdfform.h"

using namespace foxit;
using namespace pdf;
using namespace interform;
... 
// Assuming PDFDoc doc has been loaded.

Form form(doc);
...
form.ExportToXML(XMLFilePath);
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfform_c.h"
... 
// Assuming FS_PDFDOC_HANDLE doc has been loaded.
char* wstring2string(const wchar_t *source, size_t source_size, char *dest, size_t dest_size) {
  char* curLocale = setlocale(LC_ALL, NULL);
  setlocale(LC_ALL, "chs");
  memset(dest, 0, dest_size);
  wcstombs(dest, source, dest_size);
  setlocale(LC_ALL, "C");
  return dest;
} 
...
FS_FORM_HANDLE form;
FSDK_Form_Create(doc, &form);
...
FS_BOOL return_value;
xmlFileSize = wcslen(XMLFilePath);
destXMLsize = xmlFileSize _size + 1;
char* destXML =  (char*)malloc(dest_size);
wstring2string(XMLFilePath, xmlFileSize, destXML, destXMLsize);
FSDK_Form_ExportToXML(form, , &return_value);
free(destXML);
...
java
import com.foxit.sdk.pdf.interform.Form;
...

// Assuming PDFDoc doc has been loaded.
...

Form form = new Form(doc);
form.exportToXML("form.xml");
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *

...
# Assuming PDFDoc doc has been loaded.
form = Form(doc)
...
form.ExportToXML(XMLFilePath)
objc
#include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
...

FSForm *form = [[FSForm alloc] initWithDocument:doc];
BOOL is_success = [field exportToXML:@"test.xml"];
...
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");

...
// Assuming PDFDoc doc has been loaded.
let form = new FSDK.Form(doc);
...
form.ExportToXML(XMLFilePath)
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.interform;
using foxit.pdf.annots;
...

// Assuming PDFDoc doc has been loaded.

Boolean hasForm = doc.HasForm();
If(hasForm)
Form form = new Form(doc);
...
form.ExportToXML(XMLFilePath);
...

通过 XML 文件导入表单数据到 PDF

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/interform/fs_pdfform.h"

using namespace foxit;
using namespace pdf;
using namespace interform;
... 
// Assuming PDFDoc doc has been loaded.

Form form(doc);
...
form.ImportFromXML(XMLFilePath);
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfform_c.h"
... 
// Assuming FS_PDFDOC_HANDLE doc has been loaded.

FS_FORM_HANDLE form;
FSDK_Form_Create(doc, &form);
...
FS_BOOL return_value;
wstring2string(XMLFilePath, xmlFileSize, destXML, destXMLsize);
FSDK_Form_ImportFromXML(form, destXML, &return_value);
...
java
import com.foxit.sdk.pdf.interform.Form;
...
Form form = new Form(doc);
form.importFromXML("form.xml");
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *

# Assuming PDFDoc doc has been loaded.
form = Form(doc)
...
form.ImportFromXML(XMLFilePath)
...
objc
#include "FSPDFObjC.h"
...
FSForm *form = [[FSForm alloc] initWithDocument:doc];
BOOL is_success = [field importFromXML:@"test.xml"];
...
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");

// Assuming PDFDoc doc has been loaded.
let form = new FSDK.Form(doc);
...
form.ImportFromXML(XMLFilePath)
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.interform;
using foxit.pdf.annots;
...

// Assuming PDFDoc doc has been loaded.

Boolean hasForm = doc.HasForm();
If(hasForm)
Form form = new Form(doc);
...
form.ImportFromXML(XMLFilePath);
...

获取表单域的坐标

  1. 通过 PDFDoc 加载 PDF 文件。
  2. 遍历 PDFDoc 的表单域,以获取表单的 field 对象。
  3. 遍历 field 对象的 form controls,以获取 form control 对象。
  4. 通过 form control 获取相关的 widget annotation 对象。
  5. 调用 widget annotation 对象的 GetRect 方法获取表单的坐标。
c++
#include <iostream>

#include "../../../include/common/fs_common.h"
#include "../../../include/pdf/fs_pdfdoc.h"
#include "../../../include/pdf/annots/fs_annot.h"
#include "../../../include/pdf/interform/fs_pdfform.h"

using namespace foxit;
using namespace foxit::common;
using namespace pdf;
using namespace annots;
using namespace interform;

...

PDFDoc doc(input_file);
ErrorCode error_code = doc.Load();
if (error_code != foxit::e_ErrSuccess) {
  printf("The Doc [%s] Error: %d\n", (const char*)String::FromUnicode(input_path), error_code);
  return 1;
}

if (!doc.HasForm()) return 1;
interform::Form form(doc);  
for (int i = 0; i < form.GetFieldCount(NULL); i++) {
  interform::Field field = form.GetField(i, NULL);
  if (field.IsEmpty()) continue;
  for (int j = 0; j < field.GetControlCount(); j++) {
    interform::Control control = field.GetControl(j);
    annots::Widget widget = control.GetWidget();
    // Get rectangle of the  annot widget.
    RectF rect = widget.GetRect();
  }
}
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfform_c.h"

...
FS_PDFDOC_HANDLE doc;
FSErrorCode error_code = FSDK_PDFDoc_Create0(input_file, &doc);
if (error_code != e_FSErrSuccess) return 1;

error_code = FSDK_PDFDoc_Load(doc, NULL);
if (error_code != e_FSErrSuccess) {
  FSDK_PDFDoc_Release(doc);
  return 1;
}
FS_BOOL isHaveForm;
FSDK_PDFDoc_HasForm(doc, &isHaveForm);
if (!isHaveForm) return 1;
FS_FORM_HANDLE form;
FSDK_Form_Create(doc, &form);
int fieldCount = 0;
FSDK_Form_GetFieldCount(form, NULL, &fieldCount);
for (int i = 0; i < fieldCount; i++) {
  FS_FIELD_HANDLE field;    
  FSDK_Form_GetField(form, i, NULL, &field);
  FS_BOOL isEmpty;
  FSDK_Field_IsEmpty(field, &isEmpty);
  if (isEmpty) continue;
  int controlCount = 0;
  FSDK_Field_GetControlCount(field, &controlCount);
  for (int j = 0; j < controlCount; j++) {
    FS_CONTROL_HANDLE control;
    FSDK_Field_GetControl(field, j, &control);
    FS_WIDGETANNOT_HANDLE widget;
    FSDK_Control_GetWidget(control, &widget);
    FSRectF rect;
    //Get rectangle of the annot widget.
    FSDK_Annot_GetRect(widget, &rect);
  }
}
FSDK_Form_Release(form);
FSDK_PDFDoc_Release(doc);
...
java
import com.foxit.sdk.common.Constants;
import com.foxit.sdk.common.fxcrt.RectF;
import com.foxit.sdk.PDFException;
import com.foxit.sdk.common.Library;
import com.foxit.sdk.pdf.annots.Widget;
import com.foxit.sdk.pdf.interform.Control;
import com.foxit.sdk.pdf.interform.Field;
import com.foxit.sdk.pdf.interform.Form;
import com.foxit.sdk.pdf.PDFDoc;

...
// Load a document
PDFDoc doc = new PDFDoc(input_file);
int error_code = doc.load(null);
if (error_code != Constants.e_ErrSuccess) {
    System.out.println("The Doc " + input_file + " Error: " + error_code);
    return;
}

if (!doc.hasForm()) return;
Form form = new Form(doc);      
for (int i = 0; i < form.getFieldCount(null); i++) {
    Field field = form.getField(i, null);
    if (field.isEmpty())  continue;
    for (int j = 0; j < field.getControlCount(); j++) {
        Control control = field.getControl(j);
        Widget widget = control.getWidget();
        //Get rectangle of the annot widget.
        RectF rect = widget.getRect();
    }
}
...
py
import os
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *

...

# Load a document
doc = PDFDoc(input_file)
error_code = doc.Load("")
if error_code != e_ErrSuccess:
    print("The PDFDoc {} Error: {}".format(input_file, error_code))
    return 1

if not doc.HasForm(): return 1
form = Form(doc);  
for i in range(0, form.GetFieldCount("")):
    field = form.GetField(i, "")
    if field.IsEmpty(): continue
    for j in range(0, field.GetControlCount()):
      control = field.GetControl(j)
      widget = control.GetWidget()
      # Get rectangle of the annot widget.
      rect = widget.GetRect()
...
objc
#include "FSPDFObjC.h"

...
// Load a document
FSPDFDoc* doc = [[FSPDFDoc alloc] initWithPath:input_pdf_path];
FSErrorCode errorCode = [doc load:nil];
if (errorCode != FSErrSuccess) {
  NSLog(@"The Doc [%@] Error: %ld", input_pdf_path, errorCode);
  return -1;
}
if (![doc hasForm]) return -1;
FSForm *form = [[FSForm alloc] initWithDocument:doc];
int fieldCount = [form getFieldCount:@""];
for (int i = 0; i < fieldCount; i++) {
  FSField *field = [form getField:i filter:@""];
  if ([field isEmpty])  continue;
  int controlCount = [field getControlCount];
  for (int j = 0; j < controlCount; j++) {
    FSControl *control = [field getControl:j];
    FSWidget *widget = [control getWidget];
    //Get rectangle of the annot widget.
    FSRectF *rect = [widget getRect];
  }
}
...
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");

...
let doc = new FSDK.PDFDoc("Sample.pdf");
let error_code = doc.Load("");
if (error_code != FSDK.e_ErrSuccess) {
    return 1;
}

if (!doc.HasForm()) return 1;
let form = new FSDK.Form(DOC);
let count = form.GetFieldCount("");
for (let i = 0; i < count; i++) {
  let field = form.GetField(i, "")
  if(field.IsEmpty()) continue
  for (let j = 0; i < field.GetControlCount(); i++) {
    let control = field.GetControl(j)
    let widget = control.GetWidget()
    // Get rectangle of the annot widget.
    let rect = widget.GetRect()
}
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.interform;
using foxit.pdf.annots;

...
using (PDFDoc doc = new PDFDoc(input_file))
{
    ErrorCode error_code = doc.Load(null);
    if (error_code != ErrorCode.e_ErrSuccess)
    {
        Console.WriteLine("[Failed] Cannot load PDF document: " + input_file + ".\r\nError Code: " + error_code + "\r\n");
        return;
    }
    if (!doc.HasForm()) return;
   using (Form form = new Form(doc))
    {
        for (int i = 0; i < form.GetFieldCount(null); i++)
        {
            using (Field field = form.GetField(i, null))
            {
                if (field.IsEmpty()) continue;
                for (int j = 0; j < field.GetControlCount(); j++)
                {
                    using (Control control = field.GetControl(j))
                    using (Widget widget = control.GetWidget())
                    //Get rectangle of the annot widget.
                    using (RectF rect = widget.GetRect()){}          
                }
            }
        }
    }
}
...