
Quando um formulário PDF é preenchido, os valores inseridos se fundem com o layout visual em um artefato fechado. Migrar essas entradas para um modelo diferente significa redigitar cada campo manualmente. A saída é tratar os dados do formulário como um ativo portátil: extrair os valores dos campos para um arquivo de dados independente e, em seguida, alimentá-lo de volta em uma cópia em branco do formulário para reproduzir todas as entradas em uma única passagem automática. Esse ciclo de exportação e importação é o que o Spire.PDF for JavaScript oferece por meio de PdfFormWidget.ExportData e PdfFormWidget.ImportData.
Ambos os métodos aceitam três formatos de arquivo: XML, FDF e XFDF. Alternar entre eles não é mais do que alterar um valor de enum DataFormat — a convenção de chamada permanece idêntica; apenas a estrutura em disco do arquivo de saída muda. Como o Spire.PDF for JavaScript é executado inteiramente no navegador sobre WebAssembly, todo o ciclo é executado localmente por meio de um sistema de arquivos virtual (VFS), sem envolvimento de servidor backend e sem que qualquer documento saia do cliente.
Este artigo percorre o fluxo de dados completo:
- Exportar dados do formulário — extrair valores de campos de um formulário preenchido
- Importar dados do formulário — inserir esses valores de volta em um formulário em branco
Para instalação e configuração do projeto, consulte Integrar o Spire.PDF for JavaScript em um projeto React. Os exemplos abaixo pressupõem que o Spire.PDF está instalado e o módulo WebAssembly foi inicializado.
Três formatos de dados de formulário em resumo
Antes de mergulhar no código, ajuda entender os três formatos com os quais ExportData e ImportData trabalham. Todos os três carregam a mesma carga útil — um conjunto de pares nome de campo/valor —, mas a empacotam de maneiras diferentes. Escolher o formato certo desde o início economiza atrito depois, quando o arquivo de dados precisa ser compartilhado, inspecionado ou alimentado em outra ferramenta.
| Formato | Valor do enum | Estrutura do arquivo | Legível por humanos | Melhor para |
|---|---|---|---|---|
| XML | DataFormat.Xml |
XML de dados de formulário Adobe; o nome do campo se torna o nome do elemento, o valor fica como conteúdo do elemento | Sim | Inspeção rápida, depuração, ferramentas simples |
| FDF | DataFormat.Fdf |
Forms Data Format; uma estrutura de texto que começa com %FDF-, em que /T contém o nome do campo e /V o valor |
Não | Transferência compacta entre programas |
| XFDF | DataFormat.XFdf |
XFDF, XML padrão; um <field name="…"> por campo, com o valor dentro de <value>
|
Sim | Controle de versão, intercâmbio entre sistemas |
Todos os três são sem perdas em relação aos valores dos campos — nada é descartado ou transformado durante a exportação ou importação. A escolha entre eles é puramente uma questão de adequação ao fluxo de trabalho, à qual voltamos no guia de seleção de formato abaixo.
Exportar dados de formulário PDF
A primeira metade do ciclo é a extração. PdfFormWidget.ExportData pega cada valor de campo no formulário e o grava em um único arquivo de dados. O segundo argumento — um enum DataFormat — controla qual formato é gravado. O terceiro argumento é o nome do formulário; para um AcroForm sem nome, passe uma string vazia.
O exemplo abaixo carrega um formulário de informações do cliente preenchido, envolve seu identificador de formulário em um PdfFormWidget e exporta os valores dos campos para um arquivo XML. As variantes FDF e XFDF são incluídas como linhas comentadas — descomente qualquer uma para alternar os formatos sem tocar em qualquer outra coisa:
function App() {
const exportFormData = 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 exported into the VFS
const inputFileName = 'CustomerInformationForm.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 to reach the data export API
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
// This demo exports XML
const dataFiles = [
{ fileName: 'FormData.xml', format: pdfModule.DataFormat.Xml },
// { fileName: 'FormData.fdf', format: pdfModule.DataFormat.Fdf },
// { fileName: 'FormData.xfdf', format: pdfModule.DataFormat.XFdf },
];
for (const item of dataFiles) {
// The third parameter is the form name; pass an empty string for an unnamed form
formWidget.ExportData(item.fileName, item.format, '');
}
doc.Close();
// Read the generated file from the VFS and trigger the download
for (const item of dataFiles) {
const fileArray = window.dotnetRuntime.Module.FS.readFile(item.fileName);
const blob = new Blob([fileArray], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = item.fileName;
a.click();
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Export Form Data</h1>
<button onClick={exportFormData}>
Export
</button>
</div>
);
}
export default App;
Depois que a chamada de exportação termina, o arquivo de dados reside no sistema de arquivos virtual. O código então o lê de volta do VFS e aciona um download do navegador para que o arquivo possa ser salvo, compartilhado ou arquivado junto com outros dados de formulário:

Importar dados de formulário PDF
A segunda metade do ciclo é a reidratação. PdfFormWidget.ImportData lê um arquivo de dados e grava cada valor de volta no campo de formulário correspondente por nome. O parâmetro DataFormat informa ao analisador como interpretar o conteúdo do arquivo — ele não tem nada a ver com a extensão do arquivo, então o formato declarado deve corresponder ao formato real do arquivo.
O alvo aqui é uma cópia em branco do formulário original. O modelo é enviado vazio; quando o arquivo de dados retorna, todos os campos são preenchidos em uma única passagem — sem redigitação manual, sem cópia campo por campo, sem necessidade de digitar tudo uma segunda vez:
function App() {
const importFormData = 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 blank form to be filled into the VFS
const inputFileName = 'BlankCustomerInformationForm.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// This demo refills from the XML data file
const dataFiles = [
{ fileName: 'FormData.xml', format: pdfModule.DataFormat.Xml, outputFileName: 'ImportedXMLData.pdf' },
// { fileName: 'FormData.fdf', format: pdfModule.DataFormat.Fdf, outputFileName: 'ImportedFDFData.pdf' },
// { fileName: 'FormData.xfdf', format: pdfModule.DataFormat.XFdf, outputFileName: 'ImportedXFDFData.pdf' },
];
for (const item of dataFiles) {
// The data file also has to be loaded into the VFS first
await window.spire.FetchFileToVFS(item.fileName, "", `${process.env.PUBLIC_URL}/data/`);
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Read the data file and write the values back into the fields by name
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
formWidget.ImportData(item.fileName, item.format);
doc.SaveToFile(item.outputFileName);
doc.Close();
// Read the generated file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(item.outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = item.outputFileName;
a.click();
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Import Form Data</h1>
<button onClick={importFormData}>
Import
</button>
</div>
);
}
export default App;
Depois que a chamada de importação é concluída, o formulário antes em branco fica totalmente preenchido e pronto para ser salvo ou exibido. O resultado é um novo PDF com todos os campos preenchidos a partir do arquivo de dados:

Escolhendo o formato de dados certo
Todos os três formatos contêm valores de campo idênticos, então a decisão se resume à estrutura e ao suporte de ferramentas, em vez da fidelidade dos dados. Veja como pensar em cada um no contexto de um ciclo de dados de formulário:
-
FDF produz os menores arquivos. Ele começa com
%FDF-e usa uma notação de texto compacta em que/Tcarrega o nome do campo e/Vo valor. Isso o torna eficiente para passar dados entre programas de manipulação de formulários, mas o conteúdo não é facilmente lido por uma pessoa e não se dá bem com ferramentas de texto ou sistemas de controle de versão. -
XFDF é XML padrão com um elemento
<field>por campo. Por ser XML bem formado, pode ser comparado, mesclado e inspecionado com ferramentas de texto comuns, tornando-o a escolha mais segura quando o arquivo de dados entra em controle de versão, precisa de revisão humana ou deve interoperar com outro sistema. - XML (XML de dados de formulário Adobe) coloca o nome do campo diretamente no nome do elemento, proporcionando a estrutura mais direta dos três. É ideal quando você simplesmente quer uma lista legível de nomes de campos e valores sem qualquer formalidade extra.
Em resumo: use FDF para ciclos que permanecem dentro de um único programa; use XFDF quando o arquivo cruza limites de ferramentas ou equipes; use XML quando a legibilidade é a prioridade máxima.
Perguntas frequentes
Alguns campos ainda estão vazios após a importação
Causa: ImportData faz correspondência por nome de campo, então os nomes no arquivo de dados devem corresponder exatamente aos nomes dos campos no formulário — incluindo maiúsculas e minúsculas e espaços em branco. Um campo que não corresponde é silenciosamente ignorado; não há erro nem valor de retorno indicando uma incompatibilidade. Somente os campos cujos nomes coincidem recebem um valor.
Solução: Antes de importar, percorra a coleção de campos do formulário e imprima os nomes reais, depois compare-os com o arquivo de dados:
const fields = formWidget.FieldsWidget;
for (let i = 0; i < fields.Count; i++) {
console.log(fields.get_Item({ index: i }).Name);
}
A importação lança Xml_MessageWithErrorPosition ou "not a valid FDF file"
Causa: ImportData analisa o arquivo de acordo com o formato indicado pelo segundo parâmetro e nunca inspeciona a extensão do arquivo. Quando o conteúdo não corresponde ao formato declarado, a análise falha imediatamente: arquivos XML relatam Xml_MessageWithErrorPosition, Xml_InvalidRootData, e um arquivo não FDF relata The source is not a valid FDF file because it does not start with "%FDF-".
Solução: Passe o DataFormat que corresponde ao conteúdo real do arquivo e use o arquivo de dados exportado original, em vez de um que tenha sido salvo novamente em um formato diferente.