表单 (AcroForm)
PDF 目前支持两种用于交互式收集用户信息的表单类型:AcroForms 和 XFA forms。
AcroForms 是基于 PDF 规范的原始可填写表单。福昕 PDF SDK 提供了丰富的 API,允许开发者以编程方式查看和编辑表单域。在 PDF 文档中,表单域是收集用户数据的常用方式。Form
类提供了多种 API,用于获取表单域或表单控件、导入/导出表单数据以及执行其他相关操作。
常用 API (Java 示例):
获取表单域:
javaint fieldCount = form.getFieldCount(); Field field = form.getField(index);
使用
Form.getFieldCount()
获取表单域的数量,使用Form.getField(index)
获取指定索引的表单域对象。获取 PDF 页面中的表单控件:
javaint controlCount = form.getControlCount(pdfpage); Control control = form.getControl(pdfpage, index);
使用
Form.getControlCount(pdfpage)
获取指定页面中表单控件的数量,使用Form.getControl(pdfpage, index)
获取指定页面中指定索引的表单控件对象。导入/导出表单数据 (XML):
javaform.importFromXML(); form.exportToXML();
使用
Form.importFromXML(path)
从指定的 XML 文件导入表单数据,使用Form.exportToXML(path)
将表单数据导出到指定的 XML 文件。获取 Form Filler 对象:
javaFormFiller 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);
...
获取表单域的坐标
- 通过 PDFDoc 加载 PDF 文件。
- 遍历 PDFDoc 的表单域,以获取表单的 field 对象。
- 遍历 field 对象的 form controls,以获取 form control 对象。
- 通过 form control 获取相关的 widget annotation 对象。
- 调用 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()){}
}
}
}
}
}
...