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(Fehlercode8) 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 Modulpdf_oxide::fdfenthält nur die ExportseiteFdfWriter/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
- Bearbeitungsübersicht – Öffnen, Metadaten und Speichervorgang
- Textbearbeitung – Textinhalt direkt ändern
- Annotationsbearbeitung – Annotationen hinzufügen und verwalten
- Verschlüsselung und Sicherheit – Formularbearbeitung mit Berechtigungen einschränken