表单类 PDF 的价值都压在填写结果上,可文件一旦归档或转交,数据就被锁在版式里面。想知道某个字段填了什么,只能打开阅读器逐个复制;字段一多,人工誊抄既慢又容易看错。要拿这些值去做校验、入库或者跟单,前提是程序能先把它们读出来。
本文用 Spire.PDF for JavaScript 从已有 PDF 中提取表单域的值:遍历字段集合,逐个判断字段类型,再按类型读出文本框、列表框、下拉框、单选按钮与复选框各自的当前取值。Spire.PDF for JavaScript 基于 WebAssembly 在浏览器端打开并解析文档,读取全程在本地完成,通过虚拟文件系统(VFS)读写文件,不需要后端配合。
本文介绍一个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
提取所有表单域的值
Spire.PDF for JavaScript 提供 PdfFormWidget,用于接管文档里已有的表单域;FieldsWidget 就是它的字段集合,可以按下标逐个取出。各类字段的取值属性并不统一:文本框在 Text 上,复选框要看 Checked,列表框与下拉框分选项集合和选中值两项,单选按钮则直接读 Value,所以取到字段后先按类型分派、再读对应的值,并把类型名一并写进结果,文档里有哪些字段不必事先知道。
function App() {
const getAllFieldValues = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待读取的 PDF 文件载入 VFS
const inputFileName = '申请表.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 用文档的表单句柄构造 PdfFormWidget,FieldsWidget 是它的字段集合
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
const fields = formWidget.FieldsWidget;
let report = '';
// 遍历字段集合,逐项判断类型并读取对应的值
for (let i = 0; i < fields.Count; i++) {
const field = fields.get_Item({ index: i });
// 类型名与取值都按字段类型分派填写
let type = 'Unknown';
let value = '(未识别的字段类型)';
if (field instanceof pdfModule.PdfTextBoxFieldWidget) {
// 文本框域:直接读 Text
type = 'TextBox';
value = field.Text;
} else if (field instanceof pdfModule.PdfListBoxWidgetFieldWidget) {
// 列表框域:Values 是全部选项,SelectedValue 是当前选中项
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
type = 'ListBox';
value = `选中 ${field.SelectedValue},可选 ${options.join('、')}`;
} else if (field instanceof pdfModule.PdfComboBoxWidgetFieldWidget) {
// 下拉框域:与列表框一样有选项集合与选中值
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
type = 'ComboBox';
value = `选中 ${field.SelectedValue},可选 ${options.join('、')}`;
} else if (field instanceof pdfModule.PdfRadioButtonListFieldWidget) {
// 单选按钮域:Value 是选中的那一项
type = 'RadioButton';
value = `选中 ${field.Value}`;
} else if (field instanceof pdfModule.PdfCheckBoxWidgetFieldWidget) {
// 复选框域:勾选状态由 Checked 给出,不是 Value
type = 'CheckBox';
value = field.Checked ? '已勾选' : '未勾选';
}
report += `字段 "${field.Name}"(${type}):${value}\n`;
}
const outputFileName = '所有字段的值.txt';
window.dotnetRuntime.Module.FS.writeFile(outputFileName, report);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
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>提取所有表单域的值</h1>
<button onClick={getAllFieldValues}>
开始提取
</button>
</div>
);
}
export default App;
遍历全部表单域汇总出的取值:

常见问题
复选框的 Value 读不到勾选状态
原因:复选框控件域(PdfCheckBoxWidgetFieldWidget)没有 Value 属性,读出来是 undefined。它在 PDF 里靠导出值(export value)表达状态:未勾选是 Off,勾选后是 Yes 或自定义的导出值,字符串形式的取值判断不了有没有勾上。
解决:勾选状态改用 Checked 判断:
// 是否勾选看 Checked,而不是 Value
const checked = field.Checked;
列表框与下拉框该读 SelectedValue 还是 Values
原因:这两个域的 Values 是选项全集,遍历它拿到的是全部可选项,而且每一项是 PdfListWidgetItem,还要再取 .Value 才是选项文本;用户实际选中的那一项在 SelectedValue 上。把 Values 当成取值来用,拿到的就不是填写结果。
解决:取当前值读 SelectedValue;需要展示可选范围时再遍历 Values:
// 当前选中项的文本
const selected = field.SelectedValue;
// 全部可选项
const options = [];
for (let j = 0; j < field.Values.Count; j++) {
options.push(field.Values.get_Item(j).Value);
}
载入加密 PDF 时抛出 "Can not open an encrypted document. The password is invalid."
原因:读取表单要先能把文档打开;文档受密码保护时,LoadFromFile 缺密码就会在加载阶段直接抛错,不会返回一个空文档。
解决:把打开密码作为 LoadFromFile 的第二个参数传入:
doc.LoadFromFile(inputFileName, 'spire123');
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







