Skip to content

Formularfelder bearbeiten

PDF Oxide bietet umfassende Unterstützung für Formularfelder: vorhandene Werte lesen, Felder programmatisch ausfüllen, neue Felder hinzufügen, Eigenschaften konfigurieren, Formulare in statischen Seiteninhalt reduzieren und Formulardaten im FDF/XFDF-Format exportieren. XFA-Formulare können analysiert und in AcroForm konvertiert werden.

Formularfelder lesen

Alle Formularfelder abrufen

Rust

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("form.pdf")?;
let fields = editor.get_form_fields()?;

for field in &fields {
    println!("Field: {} = {:?}", field.name(), field.value());
    if let Some(ft) = field.field_type() {
        println!("  Type: {:?}", ft);
    }
    if let Some(tooltip) = field.tooltip() {
        println!("  Tooltip: {}", tooltip);
    }
}

WASM

const doc = new WasmPdfDocument(bytes);
const fields = doc.getFormFields();

for (const f of fields) {
  console.log(`${f.name} (${f.fieldType}) = ${f.value}`);
}

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("form.pdf")
fields = doc.get_form_fields()

for field in fields:
    print(f"{field.name} ({field.field_type}) = {field.value}")

Go

doc, _ := pdfoxide.Open("form.pdf")
defer doc.Close()

fields, _ := doc.FormFields()
for _, f := range fields {
    fmt.Printf("%s (%s) = %s\n", f.Name, f.Type, f.Value)
}

C#

using var doc = PdfDocument.Open("form.pdf");
foreach (var f in doc.GetFormFields())
    Console.WriteLine($"{f.Name} ({f.Type}) = {f.Value}");

Java

try (PdfDocument doc = PdfDocument.open(java.nio.file.Path.of("form.pdf"))) {
    for (fyi.oxide.pdf.form.FormField f : doc.formFields()) {
        System.out.println(f.name() + " (" + f.type() + ") = " + f.value().orElse(""));
    }
}

Kotlin

PdfDocument.open(java.nio.file.Path.of("form.pdf")).use { doc ->
    for (f in doc.formFields()) {
        println("${f.name()} (${f.type()}) = ${f.value().orElse("")}")
    }
}

Scala

Using.resource(PdfDocument.open("form.pdf")) { doc =>
  doc.formFieldsSeq.foreach { f =>
    println(s"${f.name} (${f.`type`}) = ${f.valueOption.getOrElse("")}")
  }
}

Clojure

(with-open [doc (pdf/open "form.pdf")]
  (doseq [f (pdf/form-fields doc)]
    (println (.name f) "(" (.type f) ") =" (.orElse (.value f) ""))))

Ruby

PdfOxide::PdfDocument.open('form.pdf') do |doc|
  doc.form_fields.each do |f|
    puts "#{f[:name]} (#{f[:type]}) = #{f[:value]}"
  end
end

C++

auto doc = pdf_oxide::Document::open("form.pdf");
for (const auto& f : doc.get_form_fields())
    std::cout << f.name << " (" << f.type << ") = " << f.value << "\n";

Swift

let doc = try Document.open("form.pdf")
for f in try doc.formFields() {
    print("\(f.name) (\(f.type)) = \(f.value)")
}

Dart

final doc = PdfDocument.open('form.pdf');
for (final f in doc.getFormFields()) {
  print('${f.name} (${f.type}) = ${f.value}');
}

R

doc <- pdf_open("form.pdf")
for (f in pdf_get_form_fields(doc)) {
  cat(sprintf("%s (%s) = %s\n", f$name, f$type, f$value))
}

Julia

doc = open_document("form.pdf")
for f in get_form_fields(doc)
    println("$(f.name) ($(f.type)) = $(f.value)")
end

Zig

var doc = try pdf_oxide.Document.open("form.pdf");
var fields = try doc.formFields();
defer fields.deinit();
const n = try fields.count();
var i: i32 = 0;
while (i < n) : (i += 1) {
    const name = try fields.getName(a, i);
    defer a.free(name);
    const ftype = try fields.getType(a, i);
    defer a.free(ftype);
    const value = try fields.getValue(a, i);
    defer a.free(value);
    std.debug.print("{s} ({s}) = {s}\n", .{ name, ftype, value });
}

Objective-C

NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"form.pdf" error:&err];
for (POXFormField *f in [doc formFieldsWithError:&err]) {
    NSLog(@"%@ (%@) = %@", f.name, f.type, f.value);
}

Elixir

{:ok, doc} = PdfOxide.open("form.pdf")
{:ok, fields} = PdfOxide.form_fields(doc)
for f <- fields do
  IO.puts("#{f.name} (#{f.type}) = #{f.value}")
end

Wert eines bestimmten Felds abrufen

Rust

let mut editor = DocumentEditor::open("form.pdf")?;

let value = editor.get_form_field_value("first_name")?;
println!("First name: {:?}", value);

WASM

const value = doc.getFormFieldValue("first_name");
console.log(`First name: ${value}`);

Python

value = doc.get_form_field_value("first_name")
print(f"First name: {value}")

Prüfen, ob ein Feld existiert

let mut editor = DocumentEditor::open("form.pdf")?;

if editor.has_form_field("email")? {
    println!("Email field exists");
}

Formularfeldwerte setzen

Feldwert setzen

Rust

use pdf_oxide::editor::DocumentEditor;
use pdf_oxide::editor::form_fields::FormFieldValue;

let mut editor = DocumentEditor::open("form.pdf")?;

// Set a text field
editor.set_form_field_value("first_name", FormFieldValue::Text("Jane".to_string()))?;

// Set a checkbox
editor.set_form_field_value("agree_terms", FormFieldValue::Boolean(true))?;

// Set a choice field
editor.set_form_field_value("country", FormFieldValue::Choice("United States".to_string()))?;

editor.save("filled.pdf")?;

WASM

const doc = new WasmPdfDocument(bytes);

doc.setFormFieldValue("first_name", "Jane");
doc.setFormFieldValue("agree_terms", true);
doc.setFormFieldValue("country", "United States");

writeFileSync("filled.pdf", doc.save());
doc.free();

Python

doc = PdfDocument("form.pdf")

doc.set_form_field_value("first_name", "Jane")
doc.set_form_field_value("agree_terms", True)
doc.set_form_field_value("country", "United States")

doc.save("filled.pdf")

Go

editor, _ := pdfoxide.OpenEditor("form.pdf")
defer editor.Close()

_ = editor.SetFormFieldValue("first_name", "Jane")
_ = editor.SetFormFieldValue("agree_terms", "Yes")
_ = editor.SetFormFieldValue("country", "United States")

_ = editor.Save("filled.pdf")

C#

using var editor = DocumentEditor.Open("form.pdf");

editor.SetFormFieldValue("first_name", "Jane");
editor.SetFormFieldValue("agree_terms", "Yes");
editor.SetFormFieldValue("country", "United States");

editor.Save("filled.pdf");

Java

try (DocumentEditor editor = DocumentEditor.open("form.pdf")) {
    editor.setFormField("first_name", "Jane");
    editor.setFormField("agree_terms", true);
    editor.setFormField("country", "United States");
    editor.saveTo(java.nio.file.Path.of("filled.pdf"));
}

Kotlin

DocumentEditor.open("form.pdf").use { editor ->
    editor.setFormField("first_name", "Jane")
    editor.setFormField("agree_terms", true)
    editor.setFormField("country", "United States")
    editor.saveTo(java.nio.file.Path.of("filled.pdf"))
}

Scala

Using.resource(DocumentEditor.open("form.pdf")) { editor =>
  editor.setFormField("first_name", "Jane")
  editor.setFormField("agree_terms", true)
  editor.setFormField("country", "United States")
  editor.saveTo(java.nio.file.Path.of("filled.pdf"))
}

Clojure

(with-open [editor (pdf/editor "form.pdf")]
  (.setFormField editor "first_name" "Jane")
  (.setFormField editor "agree_terms" true)
  (.setFormField editor "country" "United States")
  (.saveTo editor (java.nio.file.Path/of "filled.pdf" (into-array String []))))

Ruby

PdfOxide::DocumentEditor.open('form.pdf') do |editor|
  editor.set_form_field('first_name', 'Jane')
  editor.set_form_field('agree_terms', true)
  editor.set_form_field('country', 'United States')
  editor.save_to('filled.pdf')
end

C++

auto editor = pdf_oxide::DocumentEditor::open("form.pdf");

editor.set_form_field_value("first_name", "Jane");
editor.set_form_field_value("agree_terms", "Yes");
editor.set_form_field_value("country", "United States");

editor.save("filled.pdf");

Swift

let editor = try DocumentEditor.open("form.pdf")

try editor.setFormFieldValue("first_name", "Jane")
try editor.setFormFieldValue("agree_terms", "Yes")
try editor.setFormFieldValue("country", "United States")

try editor.save("filled.pdf")

Dart

final editor = DocumentEditor.open('form.pdf');

editor.setFormFieldValue('first_name', 'Jane');
editor.setFormFieldValue('agree_terms', 'Yes');
editor.setFormFieldValue('country', 'United States');

editor.save('filled.pdf');

R

editor <- pdf_editor_open("form.pdf")

pdf_editor_set_form_field_value(editor, "first_name", "Jane")
pdf_editor_set_form_field_value(editor, "agree_terms", "Yes")
pdf_editor_set_form_field_value(editor, "country", "United States")

pdf_editor_save(editor, "filled.pdf")

Julia

editor = open_editor("form.pdf")

set_form_field_value(editor, "first_name", "Jane")
set_form_field_value(editor, "agree_terms", "Yes")
set_form_field_value(editor, "country", "United States")

save(editor, "filled.pdf")

Zig

var editor = try pdf_oxide.DocumentEditor.openEditor("form.pdf");
defer editor.deinit();

try editor.setFormFieldValue("first_name", "Jane");
try editor.setFormFieldValue("agree_terms", "Yes");
try editor.setFormFieldValue("country", "United States");

try editor.save("filled.pdf");

Objective-C

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"form.pdf" error:&err];

[editor setFormField:@"first_name" value:@"Jane" error:&err];
[editor setFormField:@"agree_terms" value:@"Yes" error:&err];
[editor setFormField:@"country" value:@"United States" error:&err];

[editor saveToPath:@"filled.pdf" error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("form.pdf")

PdfOxide.set_form_field_value(editor, "first_name", "Jane")
PdfOxide.set_form_field_value(editor, "agree_terms", "Yes")
PdfOxide.set_form_field_value(editor, "country", "United States")

PdfOxide.editor_save(editor, "filled.pdf")

FormFieldValue-Varianten

Variante Beschreibung Beispiel
Text(String) Textfeldwert FormFieldValue::Text("Hello".into())
Boolean(bool) Kontrollkästchen-/Radiostatus FormFieldValue::Boolean(true)
Choice(String) Einzelauswahl FormFieldValue::Choice("Option A".into())
MultiChoice(Vec<String>) Mehrfachauswahl FormFieldValue::MultiChoice(vec!["A".into(), "B".into()])
None Kein Wert / Feld leeren FormFieldValue::None

Formularfelder hinzufügen

Neues Formularfeld hinzufügen

use pdf_oxide::editor::DocumentEditor;
use pdf_oxide::writer::form_fields::TextFieldWidget;

let mut editor = DocumentEditor::open("document.pdf")?;

// Create a text input field on page 0
let widget = TextFieldWidget::new("user_name")
    .with_rect(100.0, 700.0, 200.0, 20.0)
    .with_default_value("Enter name");

editor.add_form_field(widget, 0)?;
editor.save("with-form.pdf")?;

Hierarchische Felder hinzufügen

Erstellen Sie Eltern-Kind-Feldbeziehungen für strukturierte Formulare.

use pdf_oxide::editor::form_fields::ParentFieldConfig;

let mut editor = DocumentEditor::open("document.pdf")?;

// Create a parent field
let parent = ParentFieldConfig::new("address");
editor.add_parent_field(parent)?;

// Add child fields under the parent
let street = TextFieldWidget::new("street")
    .with_rect(100.0, 600.0, 300.0, 20.0);
editor.add_child_field(street, 0, "address")?;

let city = TextFieldWidget::new("city")
    .with_rect(100.0, 570.0, 150.0, 20.0);
editor.add_child_field(city, 0, "address")?;

editor.save("hierarchical-form.pdf")?;

Formularfeld entfernen

let mut editor = DocumentEditor::open("form.pdf")?;
editor.remove_form_field("obsolete_field")?;
editor.save("cleaned.pdf")?;

Formularfeldeigenschaften

Eigenschaften festlegen

Konfigurieren Sie einzelne Feldeigenschaften nach Name.

let mut editor = DocumentEditor::open("form.pdf")?;

// Access control
editor.set_form_field_readonly("signature_date", true)?;
editor.set_form_field_required("email", true)?;

// Tooltip
editor.set_form_field_tooltip("phone", "Enter phone number with area code")?;

// Position and size
editor.set_form_field_rect("name", pdf_oxide::geometry::Rect::new(100.0, 700.0, 200.0, 20.0))?;

// Text constraints
editor.set_form_field_max_length("zip_code", 10)?;
editor.set_form_field_alignment("amount", 2)?;  // 0=left, 1=center, 2=right

// Appearance
editor.set_form_field_background_color("highlight_field", [1.0, 1.0, 0.8])?;
editor.set_form_field_border_color("name", [0.0, 0.0, 0.0])?;
editor.set_form_field_border_width("name", 1.0)?;
editor.set_form_field_default_appearance("name", "/Helv 12 Tf 0 g")?;

// Raw flags
editor.set_form_field_flags("options", 0x100000)?;

editor.save("styled-form.pdf")?;

FormFieldWrapper-Eigenschaften

Beim Arbeiten mit FormFieldWrapper-Objekten, die von get_form_fields() zurückgegeben werden:

Methode Gibt zurück Beschreibung
name() &str Vollständiger Feldname
partial_name() &str Teilname (ohne Eltern-Präfix)
value() FormFieldValue Aktueller Feldwert
set_value(value) () Feldwert setzen
field_type() Option<&FieldType> Feldtyp
page_index() usize Seite mit dem Feld
bounds() Option<Rect> Feldposition und -größe
tooltip() Option<&str> Tooltip-Text
is_modified() bool Ob der Wert geändert wurde
is_new() bool Ob das Feld neu hinzugefügt wurde
is_readonly() bool Schreibschutz-Flag
set_readonly(bool) () Schreibschutz-Flag setzen
is_required() bool Pflichtfeld-Flag
set_required(bool) () Pflichtfeld-Flag setzen
is_no_export() bool Kein-Export-Flag
set_no_export(bool) () Kein-Export-Flag setzen
set_tooltip(text) () Tooltip-Text setzen
set_rect(rect) () Position und Größe setzen
set_max_length(len) () Maximale Textlänge setzen
get_max_length() Option<u32> Maximale Textlänge abrufen
set_alignment(align) () Textausrichtung setzen
get_alignment() Option<u32> Textausrichtung abrufen
set_background_color(rgb) () Hintergrundfarbe setzen
get_background_color() Option<[f32; 3]> Hintergrundfarbe abrufen
set_border_color(rgb) () Rahmenfarbe setzen
get_border_color() Option<[f32; 3]> Rahmenfarbe abrufen
set_border_width(width) () Rahmenbreite setzen
get_border_width() Option<f32> Rahmenbreite abrufen
set_default_appearance(da) () Standard-Erscheinungszeichenfolge setzen
get_default_appearance() Option<&str> Standard-Erscheinungszeichenfolge abrufen
set_default_value(value) () Standardwert setzen
get_default_value() Option<&FormFieldValue> Standardwert abrufen
has_parent() bool Elternfeld prüfen
parent_name() Option<&str> Name des Elternfelds

Formulare reduzieren

Das Reduzieren wandelt interaktive Formularfelder in statischen Seiteninhalt um. Die Feldwerte werden Teil der Seitenzeichnung und können danach nicht mehr bearbeitet werden.

Einzelne Seite reduzieren

Rust

let mut editor = DocumentEditor::open("form.pdf")?;
editor.flatten_forms_on_page(0)?;
editor.save("flat-page0.pdf")?;

WASM

const doc = new WasmPdfDocument(bytes);
doc.flattenFormsOnPage(0);
writeFileSync("flat-page0.pdf", doc.save());
doc.free();

C++

auto editor = pdf_oxide::DocumentEditor::open("form.pdf");
editor.flatten_forms_on_page(0);
editor.save("flat-page0.pdf");

Swift

let editor = try DocumentEditor.open("form.pdf")
try editor.flattenFormsOnPage(0)
try editor.save("flat-page0.pdf")

Dart

final editor = DocumentEditor.open('form.pdf');
editor.flattenFormsOnPage(0);
editor.save('flat-page0.pdf');

R

editor <- pdf_editor_open("form.pdf")
pdf_editor_flatten_forms_on_page(editor, 0)
pdf_editor_save(editor, "flat-page0.pdf")

Julia

editor = open_editor("form.pdf")
flatten_forms_on_page(editor, 0)
save(editor, "flat-page0.pdf")

Zig

var editor = try pdf_oxide.DocumentEditor.openEditor("form.pdf");
defer editor.deinit();
try editor.flattenFormsOnPage(0);
try editor.save("flat-page0.pdf");

Objective-C

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"form.pdf" error:&err];
[editor flattenFormsOnPage:0 error:&err];
[editor saveToPath:@"flat-page0.pdf" error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("form.pdf")
PdfOxide.flatten_forms_on_page(editor, 0)
PdfOxide.editor_save(editor, "flat-page0.pdf")

Alle Formulare reduzieren

Rust

let mut editor = DocumentEditor::open("form.pdf")?;
editor.flatten_forms()?;
editor.save("flat.pdf")?;

WASM

const doc = new WasmPdfDocument(bytes);
doc.flattenForms();
writeFileSync("flat.pdf", doc.save());
doc.free();

Go

editor, _ := pdfoxide.OpenEditor("form.pdf")
defer editor.Close()

_ = editor.FlattenForms()
_ = editor.Save("flat.pdf")

C#

using var editor = DocumentEditor.Open("form.pdf");
editor.FlattenForms();
editor.Save("flat.pdf");

C++

auto editor = pdf_oxide::DocumentEditor::open("form.pdf");
editor.flatten_forms();
editor.save("flat.pdf");

Swift

let editor = try DocumentEditor.open("form.pdf")
try editor.flattenForms()
try editor.save("flat.pdf")

Dart

final editor = DocumentEditor.open('form.pdf');
editor.flattenForms();
editor.save('flat.pdf');

R

editor <- pdf_editor_open("form.pdf")
pdf_editor_flatten_forms(editor)
pdf_editor_save(editor, "flat.pdf")

Julia

editor = open_editor("form.pdf")
flatten_forms(editor)
save(editor, "flat.pdf")

Zig

var editor = try pdf_oxide.DocumentEditor.openEditor("form.pdf");
defer editor.deinit();
try editor.flattenForms();
try editor.save("flat.pdf");

Objective-C

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"form.pdf" error:&err];
[editor flattenForms:&err];
[editor saveToPath:@"flat.pdf" error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("form.pdf")
PdfOxide.flatten_forms(editor)
PdfOxide.editor_save(editor, "flat.pdf")

Reduzierungsstatus prüfen

editor.flatten_forms_on_page(0)?;
assert!(editor.is_page_marked_for_form_flatten(0));
assert!(editor.will_remove_acroform());

Formulardaten exportieren

Exportieren Sie Formularfeldwerte zur externen Verarbeitung im FDF- oder XFDF-Format.

Export als FDF

Rust

let mut editor = DocumentEditor::open("filled-form.pdf")?;
editor.export_form_data_fdf("form-data.fdf")?;

WASM

const doc = new WasmPdfDocument(bytes);
const fdfData = doc.exportFormData("fdf");
writeFileSync("form-data.fdf", fdfData);
doc.free();

Python

doc = PdfDocument("filled-form.pdf")
doc.export_form_data("form-data.fdf", format="fdf")

C++

auto doc = pdf_oxide::Document::open("filled-form.pdf");
auto fdf = doc.export_form_data_to_bytes(0);  // 0 = FDF
std::ofstream("form-data.fdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(fdf.data()), fdf.size());

Swift

let doc = try Document.open("filled-form.pdf")
let fdf = try doc.exportFormData(formatType: 0)  // 0 = FDF
try Data(fdf).write(to: URL(fileURLWithPath: "form-data.fdf"))

Dart

final doc = PdfDocument.open('filled-form.pdf');
final fdf = doc.exportFormDataToBytes(0);  // 0 = FDF
File('form-data.fdf').writeAsBytesSync(fdf);

R

doc <- pdf_open("filled-form.pdf")
fdf <- pdf_export_form_data_to_bytes(doc, 0)  # 0 = FDF
writeBin(fdf, "form-data.fdf")

Julia

doc = open_document("filled-form.pdf")
fdf = export_form_data_to_bytes(doc, 0)  # 0 = FDF
write("form-data.fdf", fdf)

Zig

var doc = try pdf_oxide.Document.open("filled-form.pdf");
const fdf = try doc.exportFormDataToBytes(a, 0);  // 0 = FDF
defer a.free(fdf);
try std.fs.cwd().writeFile(.{ .sub_path = "form-data.fdf", .data = fdf });

Objective-C

NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"filled-form.pdf" error:&err];
NSData *fdf = [doc exportFormDataToBytes:0 error:&err];  // 0 = FDF
[fdf writeToFile:@"form-data.fdf" atomically:YES];

Elixir

{:ok, doc} = PdfOxide.open("filled-form.pdf")
{:ok, fdf} = PdfOxide.export_form_data_to_bytes(doc, 0)  # 0 = FDF
File.write!("form-data.fdf", fdf)

Export als XFDF

Rust

let mut editor = DocumentEditor::open("filled-form.pdf")?;
editor.export_form_data_xfdf("form-data.xfdf")?;

WASM

const doc = new WasmPdfDocument(bytes);
const xfdfData = doc.exportFormData("xfdf");
writeFileSync("form-data.xfdf", xfdfData);
doc.free();

C++

auto doc = pdf_oxide::Document::open("filled-form.pdf");
auto xfdf = doc.export_form_data_to_bytes(1);  // 1 = XFDF
std::ofstream("form-data.xfdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(xfdf.data()), xfdf.size());

Swift

let doc = try Document.open("filled-form.pdf")
let xfdf = try doc.exportFormData(formatType: 1)  // 1 = XFDF
try Data(xfdf).write(to: URL(fileURLWithPath: "form-data.xfdf"))

Dart

final doc = PdfDocument.open('filled-form.pdf');
final xfdf = doc.exportFormDataToBytes(1);  // 1 = XFDF
File('form-data.xfdf').writeAsBytesSync(xfdf);

R

doc <- pdf_open("filled-form.pdf")
xfdf <- pdf_export_form_data_to_bytes(doc, 1)  # 1 = XFDF
writeBin(xfdf, "form-data.xfdf")

Julia

doc = open_document("filled-form.pdf")
xfdf = export_form_data_to_bytes(doc, 1)  # 1 = XFDF
write("form-data.xfdf", xfdf)

Zig

var doc = try pdf_oxide.Document.open("filled-form.pdf");
const xfdf = try doc.exportFormDataToBytes(a, 1);  // 1 = XFDF
defer a.free(xfdf);
try std.fs.cwd().writeFile(.{ .sub_path = "form-data.xfdf", .data = xfdf });

Objective-C

NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"filled-form.pdf" error:&err];
NSData *xfdf = [doc exportFormDataToBytes:1 error:&err];  // 1 = XFDF
[xfdf writeToFile:@"form-data.xfdf" atomically:YES];

Elixir

{:ok, doc} = PdfOxide.open("filled-form.pdf")
{:ok, xfdf} = PdfOxide.export_form_data_to_bytes(doc, 1)  # 1 = XFDF
File.write!("form-data.xfdf", xfdf)

Formulardaten importieren

Die Umkehrung des Exports: Feldwerte aus einer FDF- oder XFDF-Datei (oder aus rohen FDF/XFDF-Bytes) zurück in ein Dokument laden. So lassen sich Daten, die anderswo ausgefüllt wurden — in einem Desktop-PDF-Reader, einer anderen Bibliothek oder einer Server-Pipeline — auf AcroForm-Felder anwenden.

Wie importiere ich FDF- oder XFDF-Formulardaten in ein PDF?

Das C ABI deklariert eine dedizierte Import-Funktionsfamilie; der Swift-Wrapper stellt alle vier Einstiegspunkte bereit:

C-ABI-Symbol Swift-Methode Datenquelle
pdf_form_import_from_file importFormFromFile(_:) FDF/XFDF-Dateipfad
pdf_document_import_form_data importFormData(_:) FDF/XFDF-Dateipfad
pdf_editor_import_fdf_bytes importFdfBytes(_:) FDF-Bytes im Arbeitsspeicher
pdf_editor_import_xfdf_bytes importXfdfBytes(_:) XFDF-Bytes im Arbeitsspeicher

Exakte C-ABI-Signaturen (aus include/pdf_oxide_c/pdf_oxide.h):

bool    pdf_form_import_from_file(const void *document, const char *filename, int32_t *error_code);
int32_t pdf_document_import_form_data(const void *document, const char *data_path, int32_t *error_code);
int32_t pdf_editor_import_fdf_bytes(const void *document, const uint8_t *data, uintptr_t data_len, int32_t *error_code);
int32_t pdf_editor_import_xfdf_bytes(const void *document, const uint8_t *data, uintptr_t data_len, int32_t *error_code);

Verfügbarkeit in v0.3.69. Diese vier Import-Einstiegspunkte sind im C ABI deklariert und vom Swift-Wrapper bereitgestellt, aber die zugrunde liegende Implementierung ist noch nicht verbunden: In v0.3.69 gibt jeder zur Laufzeit den Status Unsupported (Fehlercode 8) zurück. Die Python-, Node.js-, Go- und WASM-Bindungen stellen sie gar nicht bereit, und es gibt auch keinen FDF/XFDF-Leser auf Rust-Ebene (das Modul pdf_oxide::fdf enthält nur die Exportseite FdfWriter/XfdfWriter). Bis der Importpfad implementiert ist, verwenden Sie die unten beschriebene „Parsen-und-Befüllen"-Umgehung — sie funktioniert heute in allen Bindungen.

Swift (Schnittstelle vorhanden; wirft Unsupported, bis das Backend kommt)

import PdfOxide

let editor = try DocumentEditor.open(path: "form.pdf")

// From a file on disk (FDF or XFDF):
try editor.importFormFromFile("submission.fdf")   // -> Bool
try editor.importFormData("submission.xfdf")      // -> Int32 status

// From in-memory bytes:
let fdf = Array("%FDF-1.2\n...".utf8)
try editor.importFdfBytes(fdf)                     // -> Int32 status

let xfdf = Array("<?xml version=\"1.0\"?><xfdf>...</xfdf>".utf8)
try editor.importXfdfBytes(xfdf)                   // -> Int32 status

try editor.save(to: "filled.pdf")

Jede Methode gibt den FFI-Statuscode zurück (oder Bool für importFormFromFile) und wirft PdfOxideError bei einem Fehlercode ungleich null — heute sollten Sie also einen Unsupported-Fehler erwarten statt geänderter Felder.

Wie wende ich FDF/XFDF-Daten heute an (sprachübergreifende Umgehung)?

Da alle Bindungen bereits set_form_field_value bereitstellen, besteht die portable Methode zum Importieren von Formulardaten in v0.3.69 darin, das FDF/XFDF selbst zu parsen und jedes Name -> Wert-Paar ins Dokument zu schreiben. Beide Formate sind kleine, gut spezifizierte Textformate: FDF verpackt Werte in PDF-Wörterbuch-Syntax, XFDF ist reines XML.

Python – eine XFDF-Datei importieren

# `defusedxml` guards against XXE and billion-laughs attacks when parsing
# untrusted XFDF (the stdlib xml parsers are unsafe by default):
#   pip install defusedxml
import defusedxml.ElementTree as ET
from pdf_oxide import PdfDocument

# XFDF: <xfdf><fields><field name="..."><value>...</value></field></fields></xfdf>
tree = ET.parse("submission.xfdf")
ns = {"x": "http://ns.adobe.com/xfdf/"}

doc = PdfDocument("form.pdf")
for field in tree.findall(".//x:field", ns) or tree.findall(".//field"):
    name = field.get("name")
    value_el = field.find("x:value", ns)
    if value_el is None:
        value_el = field.find("value")
    if name and value_el is not None:
        doc.set_form_field_value(name, value_el.text or "")

doc.save("filled.pdf")

Rust – eine XFDF-Datei über DocumentEditor importieren

use pdf_oxide::editor::DocumentEditor;
use pdf_oxide::editor::form_fields::FormFieldValue;

fn import_xfdf(pdf: &str, xfdf: &str, out: &str) -> Result<(), Box<dyn std::error::Error>> {
    let mut editor = DocumentEditor::open(pdf)?;
    let xml = std::fs::read_to_string(xfdf)?;

    // Minimal extraction of <field name="..."><value>...</value></field> pairs.
    for chunk in xml.split("<field ").skip(1) {
        let name = chunk
            .split("name=\"").nth(1)
            .and_then(|s| s.split('"').next());
        let value = chunk
            .split("<value>").nth(1)
            .and_then(|s| s.split("</value>").next());
        if let (Some(name), Some(value)) = (name, value) {
            editor.set_form_field_value(name, FormFieldValue::Text(value.to_string()))?;
        }
    }

    editor.save(out)?;
    Ok(())
}

Node.js – eine XFDF-Datei importieren

const fs = require("fs");
const { PdfDocument } = require("pdf-oxide");

const xfdf = fs.readFileSync("submission.xfdf", "utf8");
const doc = new PdfDocument("form.pdf");

const re = /<field\s+name="([^"]+)"[^>]*>\s*<value>([\s\S]*?)<\/value>/g;
let m;
while ((m = re.exec(xfdf)) !== null) {
  doc.setFormFieldValue(m[1], m[2]);
}

fs.writeFileSync("filled.pdf", doc.save());
doc.close();

Das gleiche Muster funktioniert für FDF: Parsen Sie jeden /T (name) /V (value)-Eintrag aus dem /Fields-Array und rufen Sie set_form_field_value auf. Sobald der native Importpfad implementiert ist, können Sie das manuelle Parsen weglassen und importFdfBytes / importXfdfBytes / importFormFromFile direkt aufrufen.

XFA-Formularunterstützung

PDF Oxide kann XFA-Formulare erkennen, analysieren und in Standard-AcroForm konvertieren.

XFA prüfen

Rust

let mut editor = DocumentEditor::open("xfa-form.pdf")?;

if editor.has_xfa()? {
    println!("Document contains XFA form data");
}

WASM

const doc = new WasmPdfDocument(bytes);
if (doc.hasXfa()) {
  console.log("Document contains XFA form data");
}

Python

doc = PdfDocument("xfa-form.pdf")
if doc.has_xfa():
    print("Document contains XFA form data")

C++

auto doc = pdf_oxide::Document::open("xfa-form.pdf");
if (doc.has_xfa())
    std::cout << "Document contains XFA form data\n";

Swift

let doc = try Document.open("xfa-form.pdf")
if try doc.hasXfa() {
    print("Document contains XFA form data")
}

Dart

final doc = PdfDocument.open('xfa-form.pdf');
if (doc.hasXfa()) {
  print('Document contains XFA form data');
}

R

doc <- pdf_open("xfa-form.pdf")
if (pdf_has_xfa(doc)) {
  cat("Document contains XFA form data\n")
}

Julia

doc = open_document("xfa-form.pdf")
if has_xfa(doc)
    println("Document contains XFA form data")
end

Zig

var doc = try pdf_oxide.Document.open("xfa-form.pdf");
if (doc.hasXfa()) {
    std.debug.print("Document contains XFA form data\n", .{});
}

Objective-C

NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"xfa-form.pdf" error:&err];
if ([doc hasXfa]) {
    NSLog(@"Document contains XFA form data");
}

Elixir

{:ok, doc} = PdfOxide.open("xfa-form.pdf")
if PdfOxide.has_xfa?(doc) do
  IO.puts("Document contains XFA form data")
end

XFA-Struktur analysieren

let mut editor = DocumentEditor::open("xfa-form.pdf")?;

let analysis = editor.analyze_xfa()?;
println!("XFA analysis: {:?}", analysis);

XFA in AcroForm konvertieren

Konvertieren Sie XFA-Formulare in Standard-AcroForm-Felder für breitere Kompatibilität.

let mut editor = DocumentEditor::open("xfa-form.pdf")?;
editor.convert_xfa_to_acroform(&Default::default())?;
editor.save("acroform.pdf")?;

Vollständige API-Referenz

Feldoperationen

Methode Gibt zurück Beschreibung
get_form_fields() Result<Vec<FormFieldWrapper>> Alle Formularfelder auflisten
get_form_field_value(name) Result<FormFieldValue> Feldwert abrufen
has_form_field(name) Result<bool> Prüfen, ob Feld existiert
set_form_field_value(name, value) Result<()> Feldwert setzen
add_form_field(widget, page) Result<()> Neues Feld hinzufügen
add_parent_field(config) Result<()> Elternfeld hinzufügen
add_child_field(widget, page, parent) Result<()> Kindfeld hinzufügen
remove_form_field(name) Result<()> Feld entfernen

Feldeigenschaften (nach Name)

Methode Gibt zurück Beschreibung
set_form_field_readonly(name, bool) Result<()> Schreibschutz setzen
set_form_field_required(name, bool) Result<()> Pflichtfeld setzen
set_form_field_tooltip(name, text) Result<()> Tooltip setzen
set_form_field_rect(name, rect) Result<()> Position und Größe setzen
set_form_field_max_length(name, len) Result<()> Maximale Textlänge setzen
set_form_field_alignment(name, align) Result<()> Textausrichtung setzen
set_form_field_background_color(name, rgb) Result<()> Hintergrundfarbe setzen
set_form_field_border_color(name, rgb) Result<()> Rahmenfarbe setzen
set_form_field_border_width(name, width) Result<()> Rahmenbreite setzen
set_form_field_default_appearance(name, da) Result<()> Standard-Erscheinungsbild setzen
set_form_field_flags(name, flags) Result<()> Rohe Feld-Flags setzen

Reduzieren

Methode Gibt zurück Beschreibung
flatten_forms_on_page(page) Result<()> Formulare auf einer Seite reduzieren
flatten_forms() Result<()> Alle Formulare reduzieren
is_page_marked_for_form_flatten(page) bool Reduzierungsstatus prüfen
will_remove_acroform() bool Prüfen, ob AcroForm entfernt wird

Export

Methode Gibt zurück Beschreibung
export_form_data_fdf(path) Result<()> Als FDF-Datei exportieren
export_form_data_xfdf(path) Result<()> Als XFDF-Datei exportieren

Import (C ABI + Swift; gibt zur Laufzeit Unsupported in v0.3.69 zurück)

C-ABI-Symbol Swift-Methode Gibt zurück Beschreibung
pdf_form_import_from_file importFormFromFile(_:) bool / Bool FDF/XFDF aus Dateipfad importieren
pdf_document_import_form_data importFormData(_:) int32_t / Int32 Formulardaten aus Dateipfad importieren
pdf_editor_import_fdf_bytes importFdfBytes(_:) int32_t / Int32 FDF aus Bytes im Arbeitsspeicher importieren
pdf_editor_import_xfdf_bytes importXfdfBytes(_:) int32_t / Int32 XFDF aus Bytes im Arbeitsspeicher importieren

Geben Fehlercode 8 (Unsupported) zurück, bis das native Import-Backend kommt; verwenden Sie set_form_field_value, um geparste FDF/XFDF-Daten heute anzuwenden.

XFA

Methode Gibt zurück Beschreibung
has_xfa() Result<bool> XFA-Formulardaten prüfen
analyze_xfa() Result<XfaAnalysis> XFA-Struktur analysieren
convert_xfa_to_acroform(options) Result<()> XFA in AcroForm konvertieren

Erweitertes Beispiel: Stapelweise Befüllung und Reduzierung

use pdf_oxide::editor::DocumentEditor;
use pdf_oxide::editor::form_fields::FormFieldValue;

let mut editor = DocumentEditor::open("template.pdf")?;

// Fill form fields
editor.set_form_field_value("name", FormFieldValue::Text("John Doe".to_string()))?;
editor.set_form_field_value("date", FormFieldValue::Text("2025-12-01".to_string()))?;
editor.set_form_field_value("approved", FormFieldValue::Boolean(true))?;

// Make the completed form non-editable
editor.flatten_forms()?;

// Export data before saving
editor.export_form_data_xfdf("submission.xfdf")?;

editor.save("completed.pdf")?;

Häufig gestellte Fragen

Kann PDF Oxide FDF/XFDF-Daten in v0.3.69 wieder in ein PDF importieren? Noch nicht über einen nativen Einzel-Import. Das C ABI deklariert pdf_form_import_from_file, pdf_document_import_form_data, pdf_editor_import_fdf_bytes und pdf_editor_import_xfdf_bytes, und der Swift-Wrapper stellt sie bereit, aber sie geben zur Laufzeit den Status Unsupported (Fehlercode 8) zurück. Parsen Sie das FDF/XFDF und rufen Sie set_form_field_value für jedes Feld auf — das funktioniert heute in allen Bindungen.

Welche Bindungen stellen die Import-Methoden bereit? Nur das C ABI und der Swift-Wrapper bieten die Import-Schnittstelle. Die Python-, Node.js-, Go- und WASM-Bindungen tun das nicht. Der Export (export_form_data_fdf / export_form_data_xfdf und export_form_data) ist in allen Bindungen vollständig implementiert.

Was ist der Unterschied zwischen FDF und XFDF? FDF ist ein von PDF abgeleiteter Binär-/Textcontainer (%FDF-1.2-Header, /Fields-Array). XFDF ist das XML-Äquivalent (<xfdf><fields>...), das mit Standardwerkzeugen leichter zu erzeugen und zu parsen ist. Beide enthalten dieselben Feldname -> Wert-Daten; PDF Oxide kann beide Formate exportieren.

Ist das Befüllen schnell genug für Stapelverarbeitungen? Ja. Der Extraktionskern von PDF Oxide läuft auf dem Benchmark-Korpus mit 0,8 ms Durchschnitt und 100 % Erfolgsrate, sodass Felder lesen, Werte setzen und neu speichern bei typischen Formularen weit unter einer Millisekunde Feldarbeit pro Dokument bleibt.

Verwandte Seiten