A form-based PDF keeps its whole value in what was filled in, but once the file is filed away or handed over, that data is locked inside the layout. To find out what a field holds you have to open a reader and copy it out one by one; with a few dozen fields, transcribing by hand is slow and easy to get wrong. Before those values can be validated, imported into a database, or used to track an order, the program has to be able to read them out first.
This article shows how to extract form field values from an existing PDF with Spire.PDF for JavaScript: walk the field collection, determine each field's type, then read the current value of each text box, list box, combo box, radio button, and check box by type. Spire.PDF for JavaScript is built on WebAssembly and opens and parses documents in the browser, so the whole read happens locally. Files are read and written through a virtual file system (VFS), with no backend involved.
This article covers one core feature:
For installation and project configuration, see Integrate Spire.PDF for JavaScript in a React Project. The examples below assume Spire.PDF is installed and the WebAssembly module is initialized.
Extract All Form Field Values
Spire.PDF for JavaScript provides PdfFormWidget to take over the form fields already present in a document; FieldsWidget is its field collection, and fields can be pulled out one by one by index. The value properties are not uniform across field types: a text box keeps its value on Text, a check box is judged by Checked, list boxes and combo boxes split into an option collection and a selected value, and a radio button is read straight from Value. So once a field is in hand, dispatch on its type and then read the matching value, writing the type name into the result alongside it — you never need to know in advance which fields the document contains.
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;
The values collected by walking every form field:

FAQ
A check box's Value doesn't give you its state
Cause: The check box widget (PdfCheckBoxWidgetFieldWidget) has no Value property — reading it gets you undefined. A check box tracks its state through export values: Off when it is not ticked, Yes or a custom export value when it is. A string value cannot tell you whether the box is checked.
Solution: Use Checked for the state:
// Check the state with Checked, not Value
const checked = field.Checked;
Should a list box or combo box be read with SelectedValue or Values
Cause: For these two fields Values is the full option set — walking it gives you every choice, and each entry is a PdfListWidgetItem whose .Value is the option text, so the item has to be unwrapped one more time; the item the user actually selected lives on SelectedValue. Treat Values as the value and what you get is not the filled-in result.
Solution: Read SelectedValue for the current value; walk Values only when you need to show the available range:
// 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);
}
Loading an encrypted PDF throws "Can not open an encrypted document. The password is invalid."
Cause: Reading a form means the document has to open first; when the document is password-protected, LoadFromFile without the password throws during loading, and no empty document comes back.
Solution: Pass the open password as the second argument to LoadFromFile:
doc.LoadFromFile(inputFileName, 'spire123');
Get a Free License
If you want to remove the evaluation message from the result document, or to get rid of the feature limitations, contact sales for a temporary license valid for 30 days.
