> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/get-started/samples/fdftest.md).

# XFDF - Forms Data Format (FDF) Import - Sample Code

Sample JavaScript code for using WebViewer, Apryse Web SDK, to programmatically merge forms data with the PDF in order to fill forms, or to extract form field data from the PDF. Apryse SDK has full su

{% hint style="info" %}
**Requirements**

*These packages are required to use these features in production. Trial keys have unlimited access to all features*

<a href="/web/get-started/readme.md" class="button primary">Web SDK</a><a href="/web/full-api/full-api-overview.md" class="button primary">Full API</a>
{% endhint %}

Sample JavaScript code for using Apryse SDK to programmatically merge forms data with the PDF in order to fill forms, or to extract form field data from the PDF. Apryse SDK has full support for Forms Data Format (FDF).

This sample is utilizing the option to [run code programmatically, without the Viewer.](https://docs.apryse.com/web/guides/get-started/without-viewer) Need functionality in another language? Check out [FDF with Server SDK.](/core/get-started/samples/fdftest.md)

Learn more about our [Web SDK](https://docs.apryse.com/web/guides) and [PDF Data Extraction SDK Capabilities](https://apryse.com/capabilities/extraction).

### **Implementation steps**

To merge data and fill forms in a PDF with WebViewer SDK:

Step 1: Follow [get started in your preferred web stack for WebViewer](https://docs.apryse.com/web/guides/get-started) Step 2: Follow set up to [implement Full API code without viewer](https://docs.apryse.com/web/guides/full-api/running-without-viewer) Step 3: Add the sample code provided in this guide

<pre class="language-js" data-line-numbers><code class="lang-js">//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

(exports => {

  const PDFNet = exports.Core.PDFNet;

  const createFDFFromXFDFURL = url =>
    new Promise((resolve, reject) => {
      const xhttp = new XMLHttpRequest();

      xhttp.onreadystatechange = function() {
        if (this.readyState === this.DONE) {
          if (xhttp.status === 200) {
            const data = xhttp.responseText;
            PDFNet.FDFDoc.createFromXFDF(data).then(
              fdfdoc => {
                resolve(fdfdoc);
              },
              e => {
                reject(e);
              }
            );
          } else {
            reject('Request for URL ' + url + ' received incorrect HTTP response code ' + xhttp.status);
          }
        }
      };
      xhttp.open('GET', url, true);
      xhttp.send();
    });

  exports.runFDFTest = () => {
    const main = async () => {
      console.log('Beginning FDF Test.');
      const inputUrl = '../TestFiles/';

      // Import XFDF into FDF, then update adjust the PDF annotations to match the FDF
      try {
        // Annotations
        console.log('Import annotations from XFDF to FDF.');
        const fdfDoc = await createFDFFromXFDFURL(inputUrl + 'form1_annots.xfdf');

        const doc = await PDFNet.PDFDoc.createFromURL(inputUrl + 'form1.pdf');
        doc.initSecurityHandler();

        console.log('Update annotations from fdf');
        doc.fdfUpdate(fdfDoc);

        const docbuf = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);
        saveBufferAsPDFDoc(docbuf, 'form1_with_annots.pdf');
        console.log('Done sample');
      } catch (err) {
        console.log(err);
      }

      try {
        console.log('Extract annotations from PDF.');
        const doc = await PDFNet.PDFDoc.createFromURL(`${inputUrl}form1.pdf`);
        doc.initSecurityHandler();

        // extract fdf
        const fdfDoc = await doc.fdfExtract(PDFNet.PDFDoc.ExtractFlag.e_both);
        // save as xfdf
        const xfdfStr = await fdfDoc.saveAsXFDFAsString();
        console.log('XFDF extracted from form1.pdf');
        console.log(xfdfStr);

        console.log('Done sample');
      } catch (err) {
        console.log(err);
      }

      try {
        console.log('Extract existing fields from PDF.');
        const doc = await PDFNet.PDFDoc.createFromURL(`${inputUrl}form1.pdf`);
        doc.initSecurityHandler();

        for (const itr = await doc.getFieldIteratorBegin(); await itr.hasNext(); itr.next()) {
          const field = await itr.current();
          console.log(await field.getName());
        }
        console.log('Done sample');
      } catch (err) {
        console.log(err);
      }
    };

    // add your own license key as the second parameter, e.g. PDFNet.runWithCleanup(main, '<code class="expression">visitor.claims.wvKey || "YOUR_LICENSE_KEY"</code>')
    PDFNet.runWithCleanup(main, '<code class="expression">visitor.claims.wvKey || "YOUR_LICENSE_KEY"</code>');
  };
})(window);
// eslint-disable-next-line spaced-comment
//# sourceURL=FDFTest.js
</code></pre>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/get-started/samples/fdftest.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
