Dati dei moduli PDF round-trip: esportazione e importazione con JavaScript

2026-09-28 08:35:22 Allen Yang
AI Summarize:
ChatGPT
ChatGPT ✓
Claude ✓
Grok ✓
Perplexity ✓
Quick
Quick
Concise overview
Highlights
Key takeaways
Detailed
Structured explanation
Brief
One sentence summary
Summarize |

The exported XML form data file

Quando un modulo PDF viene compilato, i valori inseriti si fondono con il layout visivo in un artefatto sigillato. Trasferire quelle voci su un modello diverso significa ridigitare ogni campo a mano. La via d'uscita è trattare i dati del modulo come una risorsa portatile: estrarre i valori dei campi in un file di dati autonomo, quindi reinserirlo in una copia vuota del modulo per riprodurre tutte le voci in un'unica passata automatica. Questo ciclo esporta-poi-importa è ciò che Spire.PDF for JavaScript offre tramite PdfFormWidget.ExportData e PdfFormWidget.ImportData.

Entrambi i metodi accettano tre formati di file: XML, FDF e XFDF. Passare dall'uno all'altro non è altro che cambiare un valore dell'enumerazione DataFormat: la convenzione di chiamata resta identica; cambia solo la struttura su disco del file di output. Poiché Spire.PDF for JavaScript viene eseguito interamente nel browser sopra WebAssembly, l'intero ciclo viene eseguito localmente attraverso un file system virtuale (VFS), senza alcun server backend coinvolto e senza che alcun documento lasci mai il client.

Questo articolo illustra il flusso di dati completo:

Per l'installazione e la configurazione del progetto, consulta Integrare Spire.PDF for JavaScript in un progetto React. Gli esempi seguenti presuppongono che Spire.PDF sia installato e che il modulo WebAssembly sia inizializzato.


Tre formati di dati del modulo in breve

Prima di addentrarci nel codice, è utile comprendere i tre formati con cui lavorano ExportData e ImportData. Tutti e tre trasportano lo stesso contenuto — un insieme di coppie nome-campo/valore — ma lo confezionano in modi diversi. Scegliere quello giusto fin dall'inizio evita attriti successivi, quando il file di dati deve essere condiviso, ispezionato o inserito in un altro strumento.

Formato Valore enum Struttura del file Leggibile dall'uomo Ideale per
XML DataFormat.Xml XML dei dati di modulo Adobe; il nome del campo diventa il nome dell'elemento, il valore è il contenuto dell'elemento Sì Ispezione rapida, debug, strumenti semplici
FDF DataFormat.Fdf Forms Data Format; una struttura testuale che inizia con %FDF-, dove /T contiene il nome del campo e /V il valore No Trasferimento compatto tra programmi
XFDF DataFormat.XFdf XFDF, XML standard; un <field name="…"> per campo, con il valore all'interno di <value> Sì Controllo di versione, scambio tra sistemi

Tutti e tre sono senza perdita di dati rispetto ai valori dei campi: nulla viene eliminato o trasformato durante l'esportazione o l'importazione. La scelta tra loro riguarda esclusivamente l'idoneità al flusso di lavoro, aspetto a cui torniamo nella guida alla scelta del formato qui sotto.


Esportare i dati di un modulo PDF

La prima metà del ciclo è l'estrazione. PdfFormWidget.ExportData preleva ogni valore dei campi del modulo e lo scrive in un unico file di dati. Il secondo argomento — un'enumerazione DataFormat — controlla quale formato viene scritto. Il terzo argomento è il nome del modulo; per un AcroForm senza nome, passare una stringa vuota.

L'esempio seguente carica un modulo di informazioni cliente già compilato, avvolge il suo handle del modulo in un PdfFormWidget ed esporta i valori dei campi in un file XML. Le varianti FDF e XFDF sono incluse come righe commentate: basta togliere il commento a una di esse per cambiare formato senza toccare nient'altro:

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;

Una volta terminata la chiamata di esportazione, il file di dati risiede nel file system virtuale. Il codice poi lo rilegge dal VFS e attiva il download nel browser, così il file può essere salvato, condiviso o archiviato insieme ad altri dati del modulo:

The exported XML form data file


Importare i dati di un modulo PDF

La seconda metà del ciclo è la reidratazione. PdfFormWidget.ImportData legge un file di dati e riscrive ogni valore nel campo del modulo corrispondente tramite il nome. Il parametro DataFormat indica al parser come interpretare il contenuto del file: non ha nulla a che vedere con l'estensione del file, quindi il formato dichiarato deve corrispondere al formato effettivo del file.

Il target qui è una copia vuota del modulo originale. Il modello parte vuoto; quando il file di dati ritorna, ogni campo viene popolato in un'unica passata: nessun reinserimento manuale, nessuna copia campo per campo, nessun bisogno di digitare tutto una seconda volta:

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;

Dopo il completamento della chiamata di importazione, il modulo precedentemente vuoto è completamente popolato e pronto per essere salvato o visualizzato. Il risultato è un nuovo PDF con ogni campo compilato a partire dal file di dati:

The form after the XML data has been imported


Scegliere il formato di dati giusto

Tutti e tre i formati contengono valori dei campi identici, quindi la decisione dipende dalla struttura e dal supporto degli strumenti, non dalla fedeltà dei dati. Ecco come considerare ciascuno di essi nel contesto di un ciclo di dati di un modulo:

  • FDF produce i file più piccoli. Inizia con %FDF- e usa una notazione testuale compatta in cui /T contiene il nome del campo e /V il valore. Questo lo rende efficiente per trasferire dati tra programmi che gestiscono moduli, ma il contenuto non è facilmente leggibile da una persona e non si integra bene con strumenti di testo o sistemi di controllo di versione.
  • XFDF è XML standard con un elemento <field> per campo. Poiché è XML ben formato, può essere confrontato, unito e ispezionato con comuni strumenti di testo, il che lo rende la scelta più sicura quando il file di dati entra nel controllo di versione, necessita di revisione umana o deve interoperare con un altro sistema.
  • XML (XML dei dati di modulo Adobe) inserisce il nome del campo direttamente nel nome dell'elemento, offrendo la struttura più semplice dei tre. È ideale quando si desidera semplicemente un elenco leggibile di nomi di campo e valori senza ulteriori formalità.

In breve: usa FDF per cicli che restano all'interno di un singolo programma; usa XFDF quando il file supera i confini di strumenti o team; usa XML quando la leggibilità è la priorità assoluta.


Domande frequenti

Alcuni campi sono ancora vuoti dopo l'importazione

Causa: ImportData esegue la corrispondenza tramite il nome del campo, quindi i nomi nel file di dati devono corrispondere esattamente ai nomi dei campi nel modulo, compresi maiuscole/minuscole e spazi. Un campo che non corrisponde viene saltato silenziosamente; non c'è alcun errore né valore di ritorno che indichi una mancata corrispondenza. Solo i campi i cui nomi coincidono ricevono un valore.

Soluzione: Prima di importare, scorri la raccolta dei campi del modulo e stampa i nomi effettivi, poi confrontali con il file di dati:

const fields = formWidget.FieldsWidget;
for (let i = 0; i < fields.Count; i++) {
  console.log(fields.get_Item({ index: i }).Name);
}

L'importazione genera Xml_MessageWithErrorPosition o "not a valid FDF file"

Causa: ImportData analizza il file in base al formato indicato dal secondo parametro e non ispeziona mai l'estensione del file. Quando il contenuto non corrisponde al formato dichiarato, l'analisi fallisce immediatamente: i file XML segnalano Xml_MessageWithErrorPosition, Xml_InvalidRootData, mentre un file non FDF segnala The source is not a valid FDF file because it does not start with "%FDF-".

Soluzione: Passa il DataFormat che corrisponde al contenuto effettivo del file e usa il file di dati esportato originale anziché uno che è stato risalvato in un formato diverso.


Vedi anche