
Wenn jemand ein PDF-Formular ausfüllt und speichert, liegen die eingegebenen Werte in den Feldstrukturen des Dokuments – nicht als einfacher Text, den man durchsuchen oder in großen Mengen kopieren könnte. Bei einem Formular mit dreißig oder vierzig Feldern wird das manuelle Übertragen zum Engpass. Das eigentliche Problem ist, dass jeder Feldtyp seinen Wert anders speichert: Ein Textfeld liefert eine Zeichenkette, ein Kontrollkästchen meldet einen booleschen Wert, ein Kombinationsfeld trennt die Optionen von der Auswahl, und ein Optionsfeld speichert das gewählte Element. Einen einheitlichen Aufruf nach dem Motto "Gib mir den Wert" gibt es nicht.
Dieser Artikel zeigt Schritt für Schritt, wie man Formularfeldwerte aus einem PDF mit Spire.PDF for JavaScript extrahiert. Die Bibliothek läuft im Browser auf WebAssembly, sodass das Dokument lokal über ein virtuelles Dateisystem geparst wird – ohne Roundtrip zum Server. Sie sehen, wie Sie die Feldsammlung durchlaufen, anhand des Typs jedes Felds verzweigen und die richtige Eigenschaft für Textfelder, Listenfelder, Kombinationsfelder, Optionsfelder und Kontrollkästchen auslesen.
Informationen zur Einrichtung und Projektkonfiguration finden Sie unter Integrate Spire.PDF for JavaScript in a React Project. Der folgende Code setzt voraus, dass Spire.PDF installiert und das WASM-Modul initialisiert ist.
Feldtypen auf einen Blick
Bevor wir in die Implementierung einsteigen, ist es hilfreich, sich klarzumachen, wie jeder Feldtyp seinen Wert bereitstellt. Spire.PDF for JavaScript bildet Formularfelder als Widget-Klassen ab, und die Eigenschaft, die den aktuellen Wert enthält, unterscheidet sich von Typ zu Typ:
| Feldtyp | Widget-Klasse | Auszulesende Eigenschaft | Hinweise |
|---|---|---|---|
| Textfeld | PdfTextBoxFieldWidget |
Text |
Gibt die eingegebene Zeichenkette direkt zurück. |
| Listenfeld | PdfListBoxWidgetFieldWidget |
SelectedValue |
Values ist die vollständige Optionsliste, nicht die Auswahl des Benutzers. |
| Kombinationsfeld | PdfComboBoxWidgetFieldWidget |
SelectedValue |
Dasselbe Zwei-Eigenschaften-Modell wie beim Listenfeld. |
| Optionsfeld | PdfRadioButtonListFieldWidget |
Value |
Liefert die Zeichenkette des ausgewählten Elements in einem Schritt. |
| Kontrollkästchen | PdfCheckBoxWidgetFieldWidget |
Checked |
Boolescher Zustand. Value ist undefined – nicht verwenden. |
Das Muster ist klar: Es gibt keine einzige universelle Eigenschaft. Die Extraktionslogik muss den Typ jedes Felds prüfen und die passende Eigenschaft auslesen – genau das implementiert der nächste Abschnitt.
Felder durchlaufen und nach Typ auslesen
Der Kernablauf besteht aus drei Schritten: das PDF laden, sein Formular als PdfFormWidget abrufen und dann die FieldsWidget-Sammlung durchlaufen und mit instanceof nach der Klasse jedes Felds verzweigen. In jedem Zweig wird die typspezifische Eigenschaft gelesen und das Ergebnis an eine Berichtszeichenkette angehängt. Da die Verzweigung jeden unterstützten Typ abdeckt, müssen Sie nicht im Voraus wissen, welche Felder das Dokument enthält – nicht erkannte Felder fallen einfach auf eine Standardbezeichnung zurück.
function App() {
const getAllFieldValues = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check that the module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the PDF file to be read into the VFS
const inputFileName = 'ApplicationForm.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// Create a PdfDocument object and load the PDF document
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Build a PdfFormWidget from the document's form handle; FieldsWidget is its field collection
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
const fields = formWidget.FieldsWidget;
let report = '';
// Walk the field collection, check each type, and read the matching value
for (let i = 0; i < fields.Count; i++) {
const field = fields.get_Item({ index: i });
// Both the type name and the value are filled in by the type dispatch
let type = 'Unknown';
let value = '(Unrecognized field type)';
if (field instanceof pdfModule.PdfTextBoxFieldWidget) {
// Text box field: read Text directly
type = 'TextBox';
value = field.Text;
} else if (field instanceof pdfModule.PdfListBoxWidgetFieldWidget) {
// List box field: Values holds every option, SelectedValue is the current one
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
type = 'ListBox';
value = `Selected ${field.SelectedValue}, options ${options.join(', ')}`;
} else if (field instanceof pdfModule.PdfComboBoxWidgetFieldWidget) {
// Combo box field: like a list box, it has an option collection and a selected value
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
type = 'ComboBox';
value = `Selected ${field.SelectedValue}, options ${options.join(', ')}`;
} else if (field instanceof pdfModule.PdfRadioButtonListFieldWidget) {
// Radio button field: Value is the selected item
type = 'RadioButton';
value = `Selected ${field.Value}`;
} else if (field instanceof pdfModule.PdfCheckBoxWidgetFieldWidget) {
// Check box field: Checked gives the state, not Value
type = 'CheckBox';
value = field.Checked ? 'Checked' : 'Not checked';
}
report += `Field "${field.Name}" (${type}): ${value}\n`;
}
const outputFileName = 'AllFieldValues.txt';
window.dotnetRuntime.Module.FS.writeFile(outputFileName, report);
doc.Close();
// Read the generated file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Extract Form Field Values</h1>
<button onClick={getAllFieldValues}>
Extract values
</button>
</div>
);
}
export default App;
Nach dem Ende der Schleife enthält die Berichtszeichenkette eine Zeile pro Feld mit dessen Namen, Typ und aktuellem Wert. Die Datei wird in das virtuelle Dateisystem geschrieben und anschließend als Textdatei heruntergeladen:

Die instanceof-Kette ist das Herzstück des Ansatzes. Jeder Zweig weiß genau, welche Eigenschaft auszulesen ist, sodass die Ausgabe korrekt ist, egal wie viele Feldtypen das Dokument kombiniert. Die nächsten drei Abschnitte behandeln die Fallstricke, die auftreten, wenn die Werte-Eigenschaft eines Felds nicht die erwartete ist.
Kontrollkästchen: Checked vs. Value
Ein häufiger Fehler beim Auslesen von Kontrollkästchen ist der Griff zur Eigenschaft Value. Das Kontrollkästchen-Widget – PdfCheckBoxWidgetFieldWidget – stellt Value überhaupt nicht bereit; ein Leseversuch liefert undefined. Intern verfolgt ein Kontrollkästchen seinen Zustand über Exportwerte: Off, wenn es nicht angekreuzt ist, und Yes oder eine benutzerdefinierte Exportzeichenkette, wenn es angekreuzt ist. Eine reine Zeichenkette kann zuverlässig nicht sagen, ob das Kästchen ausgewählt ist, daher lässt die API Value bewusst weg und bietet stattdessen Checked.
Die Lösung ist unkompliziert – verwenden Sie immer die boolesche Eigenschaft Checked:
// Check the state with Checked, not Value
const checked = field.Checked;
Dies gibt true zurück, wenn das Kästchen angekreuzt ist, und andernfalls false – ein sauberer boolescher Wert für die weitere Logik, ganz ohne Parsen von Zeichenketten.
Listenfelder und Kombinationsfelder: SelectedValue vs. Values
Listenfelder und Kombinationsfelder teilen ein zweiteiliges Datenmodell, über das viele Entwickler stolpern. Sowohl PdfListBoxWidgetFieldWidget als auch PdfComboBoxWidgetFieldWidget stellen eine Values-Sammlung und eine SelectedValue-Zeichenkette bereit, und man nimmt leicht an, dass Values die Eingabe des Benutzers enthält. Das ist nicht der Fall.
Values ist die vollständige Menge der verfügbaren Optionen. Jedes Element der Sammlung ist ein PdfListWidgetItem-Objekt, daher müssen Sie es mit .Value entpacken, um den Optionstext zu erhalten. Das Durchlaufen von Values zeigt Ihnen, was der Benutzer hätte wählen können, nicht, was er tatsächlich ausgewählt hat. Die tatsächliche Auswahl des Benutzers steht als einfache Zeichenkette in SelectedValue.
Verwenden Sie SelectedValue für den aktuellen Wert und durchlaufen Sie Values nur, wenn Sie die verfügbaren Auswahlmöglichkeiten auflisten müssen:
// The text of the currently selected item
const selected = field.SelectedValue;
// Every available option
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
Es ist unerlässlich, diese beiden Eigenschaften auseinanderzuhalten: Behandelt man Values als die Antwort, erhält man die Optionsliste statt des ausgefüllten Ergebnisses, und beide sind selten gleich lang.
Umgang mit verschlüsselten PDFs
Die Formularextraktion beginnt mit dem Öffnen des Dokuments. Ist das PDF passwortgeschützt, löst der Aufruf von LoadFromFile nur mit dem Dateinamen einen Fehler aus – "Can not open an encrypted document. The password is invalid." – und es wird kein Dokumentobjekt zurückgegeben. Die Formularfelder werden nie erreicht.
Die Lösung besteht darin, das Öffnungspasswort als zweites Argument zu übergeben:
doc.LoadFromFile(inputFileName, 'spire123');
Sobald das Dokument erfolgreich geöffnet ist, funktioniert der restliche Extraktionsablauf – das Erstellen des PdfFormWidget, das Durchlaufen der Felder, das Verzweigen nach Typ – genauso wie bei einer unverschlüsselten Datei. Das Passwort betrifft nur das initiale Laden; es ändert nichts daran, wie Feldwerte ausgelesen werden.
Siehe auch
- Integrate Spire.PDF for JavaScript in a React Project — Einrichtung, Installation und WASM-Initialisierung
- Fill PDF Form Fields with Spire.PDF for JavaScript — Werte programmatisch in Formularfelder schreiben
- Import and Export PDF Form Data with Spire.PDF for JavaScript — Formulardaten in FDF/XFDF-Dateien serialisieren
Wenn Sie die Evaluierungswarnung aus dem Ergebnisdokument entfernen oder die Funktionseinschränkungen beseitigen möchten, wenden Sie sich an den Vertrieb, um eine temporäre Lizenz mit 30 Tagen Gültigkeit zu erhalten.