> 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/core/get-started/samples/dataextractiontest.md).

# Smart Data Extraction

Use Apryse Server SDK and Data Extraction module to extract tabular data, document structure and form fields from PDF documents. Samples code provided in Python, C++, C#, Java, Node.js (JavaScript), P

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

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

<a href="/core/get-started/get-started.md" class="button primary">Server SDK</a><a href="https://apryse.com/capabilities#SmartDataExtraction" class="button primary">Package: Smart Data Extraction</a><a href="/core/learn-more/modules.md#data-extraction-module" class="button primary">Module: Data Extraction</a><a href="https://showcase.apryse.com/document-structure-extraction" class="button primary">Live demo</a>
{% endhint %}

Sample code shows how to use the Apryse Data Extraction module to extract tabular data, document structure and form fields from PDF documents. Sample code provided in Python, C++, C# (.Net), Java, Node.js (JavaScript), PHP, Ruby and VB.

Looking for data extraction + WebViewer UI? Check out our [Document Structure Extraction - Showcase Sample Code](/web/get-started/samples/showcase-demo-ocr-module.md)

Learn more about our [Server SDK](/core/get-started/get-started.md) and [Smart Data Extraction](/core/smart-data-extraction/smart-data-extraction.md).

### **Implementation steps**

1. [Get started with Server SDK](/core/get-started/get-started.md) in your language/framework
2. [Download the Data Extraction Module](/core/learn-more/modules.md#data-extraction-module)
3. Add the sample code provided in this guide

To use this feature in production, your license key will need the [Smart Data Extraction Package](https://apryse.com/capabilities#SmartDataExtraction). Trial keys already include all packages.

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

using System;

using pdftron;
using pdftron.Common;
using pdftron.PDF;
using pdftron.SDF;
using pdftron.Filters;

namespace DataExtractionTestCS
{
	/// <summary>
	///---------------------------------------------------------------------------------------
	/// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
	/// extract various types of data from PDF documents.
	///
	/// The Apryse SDK Data Extraction suite can be downloaded from https://docs.apryse.com/core/guides/info/modules#data-extraction-module
	//---------------------------------------------------------------------------------------
	/// </summary>
	class Class1
	{
		private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
		static Class1() { }

		// Relative path to the folder containing test files.
		static string input_path = "../../../../TestFiles/";
		static string output_path = "../../../../TestFiles/Output/";


		/// <summary>
		/// The following sample illustrates how to extract tables from PDF documents.
		/// </summary>
		static void TestTabularData()
		{
			// Test if the add-on is installed
			if (!DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_tabular))
			{
				Console.WriteLine();
				Console.WriteLine("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.");
				Console.WriteLine("---------------------------------------------------------------");
				Console.WriteLine("The Data Extraction suite is an optional add-on, available for download");
				Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module .  If you have already downloaded this");
				Console.WriteLine("module, ensure that the SDK is able to find the required files");
				Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
				Console.WriteLine();
				return;
			}

			try
			{
				// Extract tabular data as a JSON file
				DataExtractionModule.ExtractData(input_path + "table.pdf", output_path + "table.json", DataExtractionModule.DataExtractionEngine.e_tabular);

				// Extract tabular data as a JSON string
				string json = DataExtractionModule.ExtractData(input_path + "financial.pdf", DataExtractionModule.DataExtractionEngine.e_tabular);
				System.IO.File.WriteAllText(output_path + "financial.json", json);

				// Extract tabular data as an XLSX file
				DataExtractionModule.ExtractToXLSX(input_path + "table.pdf", output_path + "table.xlsx");

				// Extract tabular data as an XLSX stream (also known as filter)
				MemoryFilter output_xlsx_stream = new MemoryFilter(0, false);
				DataExtractionModule.ExtractToXLSX(input_path + "financial.pdf", output_xlsx_stream);
				output_xlsx_stream.SetAsInputFilter();
				output_xlsx_stream.WriteToFile(output_path + "financial.xlsx", false);
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		/// <summary>
		// The following sample illustrates how to extract document structure from PDF documents.
		/// </summary>
		static void TestDocumentStructure()
		{
			// Test if the add-on is installed
			if (!DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_structure))
			{
				Console.WriteLine();
				Console.WriteLine("Unable to run Data Extraction: Apryse SDK Structured Output module not available.");
				Console.WriteLine("---------------------------------------------------------------");
				Console.WriteLine("The Data Extraction suite is an optional add-on, available for download");
				Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				Console.WriteLine("module, ensure that the SDK is able to find the required files");
				Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
				Console.WriteLine();
				return;
			}

			try
			{
				// Extract document structure as a JSON file
				DataExtractionModule.ExtractData(input_path + "paragraphs_and_tables.pdf", output_path + "paragraphs_and_tables.json", DataExtractionModule.DataExtractionEngine.e_doc_structure);

				// Extract document structure as a JSON string
				string json = DataExtractionModule.ExtractData(input_path + "tagged.pdf", DataExtractionModule.DataExtractionEngine.e_doc_structure);
				System.IO.File.WriteAllText(output_path + "tagged.json", json);
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		/// <summary>
		// The following sample illustrates how to extract form fields from PDF documents.
		/// </summary>
		static void TestFormFields()
		{
			// Test if the add-on is installed
			if (!DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_form))
			{
				Console.WriteLine();
				Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.");
				Console.WriteLine("---------------------------------------------------------------");
				Console.WriteLine("The Data Extraction suite is an optional add-on, available for download");
				Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				Console.WriteLine("module, ensure that the SDK is able to find the required files");
				Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
				Console.WriteLine();
				return;
			}

			try
			{
				// Extract form fields as a JSON file
				DataExtractionModule.ExtractData(input_path + "formfields-scanned.pdf", output_path + "formfields-scanned.json", DataExtractionModule.DataExtractionEngine.e_form);

				// Extract form fields as a JSON string
				string json = DataExtractionModule.ExtractData(input_path + "formfields.pdf", DataExtractionModule.DataExtractionEngine.e_form);
				System.IO.File.WriteAllText(output_path + "formfields.json", json);

				// Detect and add form fields to a PDF document.
				// PDF document already has form fields, and this sample will update to new found fields.
				using (PDFDoc doc = new PDFDoc(input_path + "formfields-scanned-withfields.pdf"))
				{
					DataExtractionModule.DetectAndAddFormFieldsToPDF(doc);
					doc.Save(output_path + "formfields-scanned-fields-new.pdf", SDFDoc.SaveOptions.e_linearized);
				}

				// Detect and add form fields to a PDF document.
				// PDF document already has form fields, and this sample will keep the original fields.
				using (PDFDoc doc = new PDFDoc(input_path + "formfields-scanned-withfields.pdf"))
				{
					DataExtractionOptions options = new DataExtractionOptions();
					options.SetOverlappingFormFieldBehavior("KeepOld");

					DataExtractionModule.DetectAndAddFormFieldsToPDF(doc, options);
					doc.Save(output_path + "formfields-scanned-fields-old.pdf", SDFDoc.SaveOptions.e_linearized);
				}
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
		}

		/// <summary>
		// The following sample illustrates how to extract key-value pairs from PDF documents.
		/// </summary>
		static void TestGenericKeyValue()
		{
			if (!DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_generic_key_value))
				{
					Console.WriteLine();
					Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.");
					Console.WriteLine("---------------------------------------------------------------");
					Console.WriteLine("The Data Extraction suite is an optional add-on, available for download");
					Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
					Console.WriteLine("module, ensure that the SDK is able to find the required files");
					Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
					Console.WriteLine();
					return;
				}

			try 
			{				
				// Simple example: Extract Keys & Values as a JSON file
				DataExtractionModule.ExtractData(input_path + "newsletter.pdf", output_path + "newsletter_key_val.json", DataExtractionModule.DataExtractionEngine.e_generic_key_value);

				// Example with customized options:
				// Extract Keys & Values from pages 2-4, excluding ads
				DataExtractionOptions options = new DataExtractionOptions();
				options.SetPages("2-4");

				RectCollection p2ExclusionZones = new RectCollection();
				// Exclude the add-on on page 2
				// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
				// Coordinates rotate with the page, if it has rotation applied.
				p2ExclusionZones.AddRect(166, 47, 562, 222);
				options.AddExclusionZonesForPage(p2ExclusionZones, 2);

				RectCollection p4InclusionZones = new RectCollection();
				RectCollection p4ExclusionZones = new RectCollection();
				// Only include the article text for page 4, exclude ads and headings
				p4InclusionZones.AddRect(30, 432, 562, 684);
				p4ExclusionZones.AddRect(30, 657, 295, 684);
				options.AddInclusionZonesForPage(p4InclusionZones, 4);
				options.AddExclusionZonesForPage(p4ExclusionZones, 4);

				DataExtractionModule.ExtractData(input_path + "newsletter.pdf", output_path + "newsletter_key_val_with_zones.json", DataExtractionModule.DataExtractionEngine.e_generic_key_value, options);
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
		}



		/// <summary>
		// The following sample illustrates how to extract document classes from PDF documents.
		/// </summary>
		static void TestDocClassifier()
		{
			// Test if the add-on is installed
			if (!DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_classification))
			{
				Console.WriteLine();
				Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.");
				Console.WriteLine("---------------------------------------------------------------");
				Console.WriteLine("The Data Extraction suite is an optional add-on, available for download");
				Console.WriteLine("at http://www.pdftron.com/. If you have already downloaded this");
				Console.WriteLine("module, ensure that the SDK is able to find the required files");
				Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.");
				Console.WriteLine();
				return;
			}

			try
			{
				// Simple example: classify pages as a JSON file
				DataExtractionModule.ExtractData(input_path + "Invoice.pdf", output_path + "Invoice_Classified.json", DataExtractionModule.DataExtractionEngine.e_doc_classification);

				// Classify pages as a JSON string
				string json = DataExtractionModule.ExtractData(input_path + "Scientific_Publication.pdf", DataExtractionModule.DataExtractionEngine.e_doc_classification);
				System.IO.File.WriteAllText(output_path + "Scientific_Publication_Classified.json", json);

				// Example with customized options:
				DataExtractionOptions options = new DataExtractionOptions();
				// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
				options.SetMinimumConfidenceThreshold(0.7);
				DataExtractionModule.ExtractData(input_path + "Email.pdf", output_path + "Email_Classified.json", DataExtractionModule.DataExtractionEngine.e_doc_classification, options);
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
		}


		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static void Main(string[] args)
		{
			// The first step in every application using PDFNet is to initialize the 
			// library and set the path to common PDF resources. The library is usually 
			// initialized only once, but calling Initialize() multiple times is also fine.
			PDFNet.Initialize(PDFTronLicense.Key);
			PDFNet.AddResourceSearchPath("../../../../../Lib/");

			TestTabularData();
			TestDocumentStructure();
			TestFormFields();
			TestGenericKeyValue();
			TestDocClassifier();

			PDFNet.Terminate();
		}
	}
}

```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

#include <PDF/DataExtractionModule.h>
#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <PDF/Convert.h>
#include <Filters/MemoryFilter.h>
#include <string>
#include <iostream>
#include <fstream>
#include "../../LicenseKey/CPP/LicenseKey.h"

using namespace pdftron;
using namespace PDF;
using namespace Filters;
using namespace std;

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from https://docs.apryse.com/core/guides/info/modules#data-extraction-module
//---------------------------------------------------------------------------------------

void WriteTextToFile(const std::string& filename, const UString& text)
{
	ofstream out_file(filename.c_str(), ofstream::binary);
	string out_buf = text.ConvertToUtf8();
	out_file.write(out_buf.c_str(), out_buf.size());
	out_file.close();
}


string input_path("../../TestFiles/");
string output_path("../../TestFiles/Output/");

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract tables from PDF documents.
//---------------------------------------------------------------------------------------
void TestTabularData()
{
	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_Tabular))
	{
		cout << endl;
		cout << "Unable to run Data Extraction: Apryse SDK Tabular Data module not available." << endl;
		cout << "---------------------------------------------------------------" << endl;
		cout << "The Data Extraction suite is an optional add-on, available for download" << endl;
		cout << "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this" << endl;
		cout << "module, ensure that the SDK is able to find the required files" << endl;
		cout << "using the PDFNet::AddResourceSearchPath() function." << endl << endl;
		return;
	}

	// Extract tabular data as a JSON file
	DataExtractionModule::ExtractData(input_path + UString("table.pdf"), output_path + UString("table.json"), DataExtractionModule::e_Tabular);

	// Extract tabular data as a JSON string
	UString json = DataExtractionModule::ExtractData(input_path + UString("financial.pdf"), DataExtractionModule::e_Tabular);
	WriteTextToFile((output_path + "financial.json").c_str(), json);

	// Extract tabular data as an XLSX file
	DataExtractionModule::ExtractToXLSX(input_path + UString("table.pdf"), output_path + UString("table.xlsx"));

	// Extract tabular data as an XLSX stream (also known as filter)
	MemoryFilter output_xlsx_stream(0, false);
	DataExtractionOptions options;
	options.SetPages("1"); // extract page 1
	DataExtractionModule::ExtractToXLSX(input_path + UString("financial.pdf"), output_xlsx_stream, &options);
	output_xlsx_stream.SetAsInputFilter();
	output_xlsx_stream.WriteToFile(output_path + UString("financial.xlsx"), false);
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract document structure from PDF documents.
//---------------------------------------------------------------------------------------
void TestDocumentStructure()
{
	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_DocStructure))
	{
		cout << endl;
		cout << "Unable to run Data Extraction: Apryse SDK Structured Output module not available." << endl;
		cout << "---------------------------------------------------------------" << endl;
		cout << "The Data Extraction suite is an optional add-on, available for download" << endl;
		cout << "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this" << endl;
		cout << "module, ensure that the SDK is able to find the required files" << endl;
		cout << "using the PDFNet::AddResourceSearchPath() function." << endl << endl;
		return;
	}

	// Extract document structure as a JSON file
	DataExtractionModule::ExtractData(input_path + UString("paragraphs_and_tables.pdf"), output_path + UString("paragraphs_and_tables.json"), DataExtractionModule::e_DocStructure);

	// Extract document structure as a JSON string
	UString json = DataExtractionModule::ExtractData(input_path + UString("tagged.pdf"), DataExtractionModule::e_DocStructure);
	WriteTextToFile((output_path + "tagged.json").c_str(), json);
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract form fields from PDF documents.
//---------------------------------------------------------------------------------------
void TestFormFields()
{
	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_Form))
	{
		cout << endl;
		cout << "Unable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available." << endl;
		cout << "---------------------------------------------------------------" << endl;
		cout << "The Data Extraction suite is an optional add-on, available for download" << endl;
		cout << "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this" << endl;
		cout << "module, ensure that the SDK is able to find the required files" << endl;
		cout << "using the PDFNet::AddResourceSearchPath() function." << endl << endl;
		return;
	}

	// Extract form fields as a JSON file
	DataExtractionModule::ExtractData(input_path + UString("formfields-scanned.pdf"), output_path + UString("formfields-scanned.json"), DataExtractionModule::e_Form);

	// Extract form fields as a JSON string
	UString json = DataExtractionModule::ExtractData(input_path + UString("formfields.pdf"), DataExtractionModule::e_Form);
	WriteTextToFile((output_path + "formfields.json").c_str(), json);

	//---------------------------------------------------------------------------------------
	// Detect and add form fields to a PDF document.
	// PDF document already has form fields, and this sample will update to new found fields.
	//---------------------------------------------------------------------------------------
	{
		PDFDoc doc(input_path + "formfields-scanned-withfields.pdf");

		DataExtractionModule::DetectAndAddFormFieldsToPDF(doc);

		// Save the modfied pdf document
		doc.Save(output_path + "formfields-scanned-fields-new.pdf", SDF::SDFDoc::e_linearized, NULL);
	}

	//---------------------------------------------------------------------------------------
	// Detect and add form fields to a PDF document.
	// PDF document already has form fields, and this sample will keep the original fields.
	//---------------------------------------------------------------------------------------
	{
		PDFDoc doc(input_path + "formfields-scanned-withfields.pdf");

		// Setup DataExtractionOptions to keep old fields
		DataExtractionOptions options;
		options.SetOverlappingFormFieldBehavior("KeepOld");

		DataExtractionModule::DetectAndAddFormFieldsToPDF(doc, &options);

		// Save the modfied pdf document
		doc.Save(output_path + "formfields-scanned-fields-old.pdf", SDF::SDFDoc::e_linearized, NULL);
	}
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract key-value pairs from PDF documents.
//---------------------------------------------------------------------------------------
void TestGenericKeyValue() {

	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_GenericKeyValue))
	{
		cout << endl;
		cout << "Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available." << endl;
		cout << "---------------------------------------------------------------" << endl;
		cout << "The Data Extraction suite is an optional add-on, available for download" << endl;
		cout << "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this" << endl;
		cout << "module, ensure that the SDK is able to find the required files" << endl;
		cout << "using the PDFNet::AddResourceSearchPath() function." << endl << endl;
		return;
	}

	// Simple example: Extract Keys & Values as a JSON file
	DataExtractionModule::ExtractData(input_path + UString("newsletter.pdf"), output_path + UString("newsletter_key_val.json"), DataExtractionModule::e_GenericKeyValue);

	// Example with customized options:
	// Extract Keys & Values from pages 2-4, excluding ads
	DataExtractionOptions options;
	options.SetPages("2-4");
	RectCollection p2_exclusion_zones;
	// Exclude the add-on on page 2
	// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
	// Coordinates rotate with the page, if it has rotation applied.
	p2_exclusion_zones.AddRect(166, 47, 562, 222);
	options.AddExclusionZonesForPage(p2_exclusion_zones, 2);

	RectCollection p4_inclusion_zones, p4_exclusion_zones;
	// Only include the article text for page 4, exclude ads and headings
	p4_inclusion_zones.AddRect(30, 432, 562, 684);
	p4_exclusion_zones.AddRect(30, 657, 295, 684);
	options.AddInclusionZonesForPage(p4_inclusion_zones, 4);
	options.AddExclusionZonesForPage(p4_exclusion_zones, 4);

	DataExtractionModule::ExtractData(input_path + UString("newsletter.pdf"), output_path + UString("newsletter_key_val_with_zones.json"), DataExtractionModule::e_GenericKeyValue, &options);
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract document classes from PDF documents.
//---------------------------------------------------------------------------------------
void TestDocClassifier()
{
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_DocClassification))
	{
		cout << endl;
		cout << "Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available." << endl;
		cout << "---------------------------------------------------------------" << endl;
		cout << "The Data Extraction suite is an optional add-on, available for download" << endl;
		cout << "at http://www.pdftron.com/. If you have already downloaded this" << endl;
		cout << "module, ensure that the SDK is able to find the required files" << endl;
		cout << "using the PDFNet::AddResourceSearchPath() function." << endl << endl;
		return;
	}

	// Simple example: classify pages as a JSON file
	DataExtractionModule::ExtractData(input_path + UString("Invoice.pdf"), output_path + UString("Invoice_Classified.json"), DataExtractionModule::e_DocClassification);

	// Classify pages as a JSON string
	UString json = DataExtractionModule::ExtractData(input_path + UString("Scientific_Publication.pdf"), DataExtractionModule::e_DocClassification);
	WriteTextToFile((output_path + "Scientific_Publication_Classified.json").c_str(), json);

	// Example with customized options:
	DataExtractionOptions options;
	// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
	options.SetMinimumConfidenceThreshold(0.7);
	DataExtractionModule::ExtractData(input_path + UString("Email.pdf"), output_path + UString("Email_Classified.json"), DataExtractionModule::e_DocClassification, &options);
}

int main(int argc, char* argv[])
{
	// The first step in every application using PDFNet is to initialize the 
	// library and set the path to common PDF resources. The library is usually 
	// initialized only once, but calling Initialize() multiple times is also fine.
	PDFNet::Initialize(LicenseKey);

	int ret = 0;

	try
	{
		PDFNet::AddResourceSearchPath("../../../Lib/");

		TestTabularData();
		TestDocumentStructure();
		TestFormFields();
		TestGenericKeyValue();
		TestDocClassifier();
	}
	catch (Common::Exception& e)
	{
		cout << e << endl;
		ret = 1;
	}
	catch (...)
	{
		cout << "Unknown Exception" << endl;
		ret = 1;
	}

	PDFNet::Terminate();

	return ret;
}

```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------

package main
import (
	"fmt"
	"testing"
	"os"
	"flag"
	. "github.com/pdftron/pdftron-go/v2"
)

var licenseKey string
var modulePath string

func init() {
    flag.StringVar(&licenseKey, "license", "", "License key for Apryse SDK")
    flag.StringVar(&modulePath, "modulePath", "", "Path for downloaded modules")
}

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from
// https://docs.apryse.com/core/guides/info/modules#data-extraction-module
//
// Please contact us if you have any questions.
//---------------------------------------------------------------------------------------

// Relative path to the folder containing the test files.
var inputPath = "../TestFiles/"
var outputPath = "../TestFiles/Output/"

//---------------------------------------------------------------------------------------

func catch(err *error) {
	if r := recover(); r != nil {
		*err = fmt.Errorf("%v", r)
	}
}

//---------------------------------------------------------------------------------------

func WriteTextToFile(outputFile string, text string) {
	f, err := os.Create(outputFile)
	if err != nil {
		fmt.Println(err)
	}

	defer f.Close()

	_, err2 := f.WriteString(text)
	if err2 != nil {
		fmt.Println(err2)
	}
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract tables from PDF documents.
//---------------------------------------------------------------------------------------

func TabularDataTest() (err error) {
	defer catch(&err)

    PDFNetAddResourceSearchPath(modulePath)

	// Test if the add-on is installed
	if !DataExtractionModuleIsModuleAvailable(DataExtractionModuleE_Tabular) {
		fmt.Println("")
		fmt.Println("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.")
		fmt.Println("-----------------------------------------------------------------------------")
		fmt.Println("The Data Extraction suite is an optional add-on, available for download")
		fmt.Println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
		fmt.Println("downloaded this module, ensure that the SDK is able to find the required files")
		fmt.Println("using the PDFNetAddResourceSearchPath() function.")
		fmt.Println("")
		return nil
	}

	// Extract tabular data as a JSON file
	fmt.Println("Extract tabular data as a JSON file")

	inputFile := inputPath + "table.pdf"
	outputFile := outputPath + "table.json"
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_Tabular)

	fmt.Println("Result saved in " + outputFile)

	// Extract tabular data as a JSON string
	fmt.Println("Extract tabular data as a JSON string")

	inputFile = inputPath + "financial.pdf"
	outputFile = outputPath + "financial.json"

	json := DataExtractionModuleExtractData(inputFile, DataExtractionModuleE_Tabular).(string)
	WriteTextToFile(outputFile, json)

	fmt.Println("Result saved in " + outputFile)

	// Extract tabular data as an XLSX file
	fmt.Println("Extract tabular data as an XLSX file")

	inputFile = inputPath + "table.pdf"
	outputFile = outputPath + "table.xlsx"
	DataExtractionModuleExtractToXLSX(inputFile, outputFile)

	fmt.Println("Result saved in " + outputFile)

	// Extract tabular data as an XLSX stream (also known as filter)
	fmt.Println("Extract tabular data as an XLSX stream")

	inputFile = inputPath + "financial.pdf"
	outputFile = outputPath + "financial.xlsx"
	outputXlsxStream := NewMemoryFilter(0, false)
	outputFilter := NewFilter(outputXlsxStream)
	options := NewDataExtractionOptions()
	options.SetPages("1"); // page 1
	DataExtractionModuleExtractToXLSX(inputFile, outputFilter, options)
	outputXlsxStream.SetAsInputFilter()
	outputXlsxStream.WriteToFile(outputFile, false)

	fmt.Println("Result saved in " + outputFile)

	return nil
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract document structure from PDF documents.
//---------------------------------------------------------------------------------------

func DocumentStructureTest() (err error) {
	defer catch(&err)

	// Test if the add-on is installed
	if !DataExtractionModuleIsModuleAvailable(DataExtractionModuleE_DocStructure) {
		fmt.Println("")
		fmt.Println("Unable to run Data Extraction: PDFTron SDK Structured Output module not available.")
		fmt.Println("-----------------------------------------------------------------------------")
		fmt.Println("The Data Extraction suite is an optional add-on, available for download")
		fmt.Println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
		fmt.Println("downloaded this module, ensure that the SDK is able to find the required files")
		fmt.Println("using the PDFNetAddResourceSearchPath() function.")
		fmt.Println("")
		return nil
	}

	// Extract document structure as a JSON file
	fmt.Println("Extract document structure as a JSON file")

	inputFile := inputPath + "paragraphs_and_tables.pdf"
	outputFile := outputPath + "paragraphs_and_tables.json"
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_DocStructure)

	fmt.Println("Result saved in " + outputFile)

	// Extract document structure as a JSON string
	fmt.Println("Extract document structure as a JSON string")

	inputFile = inputPath + "tagged.pdf"
	outputFile = outputPath + "tagged.json"
	json := DataExtractionModuleExtractData(inputFile, DataExtractionModuleE_DocStructure).(string)
	WriteTextToFile(outputFile, json)

	fmt.Println("Result saved in " + outputFile)

	return nil
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract form fields from PDF documents.
//---------------------------------------------------------------------------------------

func FormFieldsTest() (err error) {
	defer catch(&err)

	// Test if the add-on is installed
	if !DataExtractionModuleIsModuleAvailable(DataExtractionModuleE_Form) {
		fmt.Println("")
		fmt.Println("Unable to run Data Extraction: PDFTron SDK AIFormFieldExtractor module not available.")
		fmt.Println("-----------------------------------------------------------------------------")
		fmt.Println("The Data Extraction suite is an optional add-on, available for download")
		fmt.Println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
		fmt.Println("downloaded this module, ensure that the SDK is able to find the required files")
		fmt.Println("using the PDFNetAddResourceSearchPath() function.")
		fmt.Println("")
		return nil
	}

	// Extract form fields as a JSON file
	fmt.Println("Extract form fields as a JSON file")

	inputFile := inputPath + "formfields-scanned.pdf"
	outputFile := outputPath + "formfields-scanned.json"
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_Form)

	fmt.Println("Result saved in " + outputFile)

	// Extract form fields as a JSON string
	fmt.Println("Extract form fields as a JSON string")

	inputFile = inputPath + "formfields.pdf"
	outputFile = outputPath + "formfields.json"

	json := DataExtractionModuleExtractData(inputFile, DataExtractionModuleE_Form).(string)
	WriteTextToFile(outputFile, json)

	fmt.Println("Result saved in " + outputFile)

	//////////////////////////////////////////////////////////////////////////
	// Detect and add form fields to a PDF document.
	// PDF document already has form fields, and this sample will update to new found fields.
	doc := NewPDFDoc(inputPath + "formfields-scanned-withfields.pdf")

	fmt.Println("Extract form fields as a PDF file, keep new fields")
	DataExtractionModuleDetectAndAddFormFieldsToPDF(doc)

	outputFile = outputPath + "formfields-scanned-fields-new.pdf"
	doc.Save(outputFile, uint(SDFDocE_linearized))
	doc.Close()

	fmt.Println("Result saved in " + outputFile)

	//////////////////////////////////////////////////////////////////////////
	// Detect and add form fields to a PDF document.
	// PDF document already has form fields, and this sample will keep the original fields.
	doc = NewPDFDoc(inputPath + "formfields-scanned-withfields.pdf")

	// Setup DataExtractionOptions to keep old fields
	options := NewDataExtractionOptions()
	options.SetOverlappingFormFieldBehavior("KeepOld")

	fmt.Println("Extract form fields as a PDF file, keep old fields")
	DataExtractionModuleDetectAndAddFormFieldsToPDF(doc, options)

	outputFile = outputPath + "formfields-scanned-fields-old.pdf"
	doc.Save(outputFile, uint(SDFDocE_linearized))
	doc.Close()

	fmt.Println("Result saved in " + outputFile)

	return nil
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract key-value pairs from PDF documents.
//---------------------------------------------------------------------------------------

func GenericKeyValueTest() (err error) {
	defer catch(&err)

	// Test if the add-on is installed
	if !DataExtractionModuleIsModuleAvailable(DataExtractionModuleE_GenericKeyValue) {
		fmt.Println("")
		fmt.Println("Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available.")
		fmt.Println("-----------------------------------------------------------------------------")
		fmt.Println("The Data Extraction suite is an optional add-on, available for download")
		fmt.Println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
		fmt.Println("downloaded this module, ensure that the SDK is able to find the required files")
		fmt.Println("using the PDFNetAddResourceSearchPath() function.")
		fmt.Println("")
		return nil
	}

	fmt.Println("Extract key-value pairs from a PDF")

	inputFile := inputPath + "newsletter.pdf"
	outputFile := outputPath + "newsletter_key_val.json"
	// Simple example: Extract Keys & Values as a JSON file
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_GenericKeyValue)

	fmt.Println("Result saved in " + outputFile)

	// Example with customized options:
	// Extract Keys & Values from pages 2-4, excluding ads
	options := NewDataExtractionOptions()
	options.SetPages("2-4")
	
	p2ExclusionZones := NewRectCollection()
	// Exclude the add-on on page 2
	// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
	// Coordinates rotate with the page, if it has rotation applied.
	p2ExclusionZones.AddRect(NewRect(166, 47, 562, 222))
	options.AddExclusionZonesForPage(p2ExclusionZones, 2)

	p4InclusionZones := NewRectCollection()
	p4ExclusionZones := NewRectCollection()
	// Only include the article text for page 4, exclude ads and headings
	p4InclusionZones.AddRect(NewRect(30, 432, 562, 684))
	p4ExclusionZones.AddRect(NewRect(30, 657, 295, 684))
	options.AddInclusionZonesForPage(p4InclusionZones, 4)
	options.AddExclusionZonesForPage(p4ExclusionZones, 4)
	
	fmt.Println("Extract Key-Value pairs from specific pages and zones as a JSON file")
	outputFile = outputPath + "newsletter_key_val_with_zones.json"
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_GenericKeyValue, options)

	fmt.Println("Result saved in " + outputFile)

	return nil
}

//---------------------------------------------------------------------------------------
// The following sample illustrates how to extract document classes from PDF documents.
//---------------------------------------------------------------------------------------

func DocClassifierTest() (err error) {
	defer catch(&err)

	// Test if the add-on is installed
	if !DataExtractionModuleIsModuleAvailable(DataExtractionModuleE_DocClassification) {
		fmt.Println("")
		fmt.Println("Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available.")
		fmt.Println("-----------------------------------------------------------------------------")
		fmt.Println("The Data Extraction suite is an optional add-on, available for download")
		fmt.Println("at https://docs.apryse.com/documentation/core/info/modules/. If you have already")
		fmt.Println("downloaded this module, ensure that the SDK is able to find the required files")
		fmt.Println("using the PDFNetAddResourceSearchPath() function.")
		fmt.Println("")
		return nil
	}

	// Simple example: classify pages as a JSON file
	fmt.Println("Classify pages as a JSON file")

	inputFile := inputPath + "Invoice.pdf"
	outputFile := outputPath + "Invoice_Classified.json"
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_DocClassification)

	fmt.Println("Result saved in " + outputFile)

	// Classify pages as a JSON string
	fmt.Println("Classify pages as a JSON string")

	inputFile = inputPath + "Scientific_Publication.pdf"
	outputFile = outputPath + "Scientific_Publication_Classified.json"
	json := DataExtractionModuleExtractData(inputFile, DataExtractionModuleE_DocClassification).(string)
	WriteTextToFile(outputFile, json)

	fmt.Println("Result saved in " + outputFile)

	// Example with customized options:
	fmt.Println("Classify pages with customized options")

	inputFile = inputPath + "Email.pdf"
	outputFile = outputPath + "Email_Classified.json"
	options := NewDataExtractionOptions()
	// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
	options.SetMinimumConfidenceThreshold(0.7)
	DataExtractionModuleExtractData(inputFile, outputFile, DataExtractionModuleE_DocClassification, options)

	fmt.Println("Result saved in " + outputFile)

	return nil
}

//---------------------------------------------------------------------------------------

func TestDataExtraction(t *testing.T) {
	// The first step in every application using PDFNet is to initialize the 
	// library. The library is usually initialized only once, but calling 
	// Initialize() multiple times is also fine.
	PDFNetInitialize(licenseKey)

	//-----------------------------------------------------------------------------------

	PDFNetAddResourceSearchPath("../../../PDFNetC/Lib/")

	//-----------------------------------------------------------------------------------

	err := TabularDataTest()
	if err != nil {
		fmt.Println(fmt.Errorf("Unable to extract tabular data, error: %s", err))
	}

	//-----------------------------------------------------------------------------------

	err = DocumentStructureTest()
	if err != nil {
		fmt.Println(fmt.Errorf("Unable to extract document structure data, error: %s", err))
	}

	//-----------------------------------------------------------------------------------

	err = FormFieldsTest()
	if err != nil {
		fmt.Println(fmt.Errorf("Unable to extract form fields data, error: %s", err))
	}

	err = GenericKeyValueTest()
	if err != nil {
		fmt.Println(fmt.Errorf("Unable to extract key-value pairs, error: %s", err))
	}

	//-----------------------------------------------------------------------------------

	err = DocClassifierTest()
	if err != nil {
		fmt.Println(fmt.Errorf("Unable to extract document classifications, error: %s", err))
	}

	//-----------------------------------------------------------------------------------

	PDFNetTerminate()
	fmt.Println("Done.")
}

```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;

import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.*;
import com.pdftron.filters.*;
import com.pdftron.sdf.SDFDoc;

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from https://docs.apryse.com/core/guides/info/modules#data-extraction-module
//---------------------------------------------------------------------------------------

public class DataExtractionTest {

	static void writeTextToFile(String filename, String text) throws IOException
	{
		BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
		writer.write(text);
		writer.close();
	}

	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to extract tables from PDF documents.
	//---------------------------------------------------------------------------------------
	static void testTabularData()
	{
		try {
			// Test if the add-on is installed
			if (!DataExtractionModule.isModuleAvailable(DataExtractionModule.DataExtractionEngine.e_tabular))
			{
				System.out.println();
				System.out.println("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.");
				System.out.println("---------------------------------------------------------------");
				System.out.println("The Data Extraction suite is an optional add-on, available for download");
				System.out.println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				System.out.println("module, ensure that the SDK is able to find the required files");
				System.out.println("using the PDFNet.addResourceSearchPath() function." );
				System.out.println();
				return;
			}
		} catch (PDFNetException e) {
			System.out.println("Data Extraction module not available, error:");
			e.printStackTrace();
			System.out.println(e);
		}

		// Relative path to the folder containing test files.
		String input_path = "../../TestFiles/";
		String output_path = "../../TestFiles/Output/";

		try {
			// Extract tabular data as a JSON file
			DataExtractionModule.extractData(input_path + "table.pdf", output_path + "table.json", DataExtractionModule.DataExtractionEngine.e_tabular);

			// Extract tabular data as a JSON string
			String json = DataExtractionModule.extractData(input_path + "financial.pdf", DataExtractionModule.DataExtractionEngine.e_tabular);
			writeTextToFile(output_path + "financial.json", json);

			// Extract tabular data as an XLSX file
			DataExtractionModule.extractToXLSX(input_path + "table.pdf", output_path + "table.xlsx");

			// Extract tabular data as an XLSX stream (also known as filter)
			DataExtractionOptions options = new DataExtractionOptions();
			options.setPages("1");
			MemoryFilter output_xlsx_stream = new MemoryFilter(0, false);
			DataExtractionModule.extractToXLSX(input_path + "financial.pdf", output_xlsx_stream, options);
			output_xlsx_stream.setAsInputFilter();
			output_xlsx_stream.writeToFile(output_path + "financial.xlsx", false);

		} catch (PDFNetException e) {
			System.out.println(e);
		}
		catch (IOException e) {
			System.out.println(e);
		}
	}

	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to extract document structure from PDF documents.
	//---------------------------------------------------------------------------------------
	static void testDocumentStructure()
	{
		// Test if the add-on is installed
		try {
			if (!DataExtractionModule.isModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_structure))
			{
				System.out.println();
				System.out.println("Unable to run Data Extraction: Apryse SDK Structured Output module not available.");
				System.out.println("---------------------------------------------------------------");
				System.out.println("The Data Extraction suite is an optional add-on, available for download");
				System.out.println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				System.out.println("module, ensure that the SDK is able to find the required files");
				System.out.println("using the PDFNet.addResourceSearchPath() function." );
				System.out.println();
				return;
			}
		} catch (PDFNetException e) {
			System.out.println("Data Extraction module not available, error:");
			e.printStackTrace();
			System.out.println(e);
		}

		// Relative path to the folder containing test files.
		String input_path = "../../TestFiles/";
		String output_path = "../../TestFiles/Output/";

		try {
			// Extract document structure as a JSON file
			DataExtractionModule.extractData(input_path + "paragraphs_and_tables.pdf", output_path + "paragraphs_and_tables.json", DataExtractionModule.DataExtractionEngine.e_doc_structure);

			// Extract document structure as a JSON string
			String json = DataExtractionModule.extractData(input_path + "tagged.pdf", DataExtractionModule.DataExtractionEngine.e_doc_structure);
			writeTextToFile(output_path + "tagged.json", json);

		} catch (PDFNetException e) {
			System.out.println(e);
		}
		catch (IOException e) {
			System.out.println(e);
		}
	}

	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to extract form fields from PDF documents.
	//---------------------------------------------------------------------------------------
	static void testFormFields()
	{
		try {
			// Test if the add-on is installed
			if (!DataExtractionModule.isModuleAvailable(DataExtractionModule.DataExtractionEngine.e_form))
			{
				System.out.println();
				System.out.println("Unable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.");
				System.out.println("---------------------------------------------------------------");
				System.out.println("The Data Extraction suite is an optional add-on, available for download");
				System.out.println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				System.out.println("module, ensure that the SDK is able to find the required files");
				System.out.println("using the PDFNet.addResourceSearchPath() function." );
				System.out.println();
				return;
			}
		} catch (PDFNetException e) {
			System.out.println("Data Extraction module not available, error:");
			e.printStackTrace();
			System.out.println(e);
		}

		// Relative path to the folder containing test files.
		String input_path = "../../TestFiles/";
		String output_path = "../../TestFiles/Output/";

		try {
			// Extract form fields as a JSON file
			DataExtractionModule.extractData(input_path + "formfields-scanned.pdf", output_path + "formfields-scanned.json", DataExtractionModule.DataExtractionEngine.e_form);

			// Extract form fields as a JSON string
			String json = DataExtractionModule.extractData(input_path + "formfields.pdf", DataExtractionModule.DataExtractionEngine.e_form);
			writeTextToFile(output_path + "formfields.json", json);

			//---------------------------------------------------------------------------------------
			// Detect and add form fields to a PDF document.
			// PDF document already has form fields, and this sample will update to new found fields.
			//---------------------------------------------------------------------------------------
			try (PDFDoc doc = new PDFDoc(input_path + "formfields-scanned-withfields.pdf"))
			{
				DataExtractionModule.detectAndAddFormFieldsToPDF(doc);

				// Save the modfied pdf document
				doc.save(output_path + "formfields-scanned-fields-new.pdf", SDFDoc.SaveMode.LINEARIZED, null);
			} catch (Exception e) {
				e.printStackTrace();
			}

			//---------------------------------------------------------------------------------------
			// Detect and add form fields to a PDF document.
			// PDF document already has form fields, and this sample will keep the original fields.
			//---------------------------------------------------------------------------------------
			try (PDFDoc doc = new PDFDoc(input_path + "formfields-scanned-withfields.pdf"))
			{
				// Setup DataExtractionOptions to keep old fields
				DataExtractionOptions options = new DataExtractionOptions();
				options.setOverlappingFormFieldBehavior("KeepOld");

				DataExtractionModule.detectAndAddFormFieldsToPDF(doc, options);

				// Save the modfied pdf document
				doc.save(output_path + "formfields-scanned-fields-old.pdf", SDFDoc.SaveMode.LINEARIZED, null);
			} catch (Exception e) {
				e.printStackTrace();
			}

		} catch (PDFNetException e) {
			System.out.println(e);
		}
		catch (IOException e) {
			System.out.println(e);
		}
	}

	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to extract key-value pairs from PDF documents.
	//---------------------------------------------------------------------------------------
	public static void testGenericKeyValue() {
		try {
			// Test if the add-on is installed
			if (!DataExtractionModule.isModuleAvailable(DataExtractionModule.DataExtractionEngine.e_form))
			{
				System.out.println();
				System.out.println("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.");
				System.out.println("---------------------------------------------------------------");
				System.out.println("The Data Extraction suite is an optional add-on, available for download");
				System.out.println("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this");
				System.out.println("module, ensure that the SDK is able to find the required files");
				System.out.println("using the PDFNet.addResourceSearchPath() function." );
				System.out.println();
				return;
			}
		} catch (PDFNetException e) {
			System.out.println("Data Extraction module not available, error:");
			e.printStackTrace();
			System.out.println(e);
		}

		// Relative path to the folder containing test files.
		String input_path = "../../TestFiles/";
		String output_path = "../../TestFiles/Output/";

		try {

			// Simple example: Extract Keys & Values as a JSON file
			DataExtractionModule.extractData(input_path + "newsletter.pdf", output_path + "newsletter_key_val.json", DataExtractionModule.DataExtractionEngine.e_generic_key_value);

			// Example with customized options:
			// Extract Keys & Values from pages 2-4, excluding ads
			DataExtractionOptions options = new DataExtractionOptions();
			options.setPages("2-4");

			RectCollection p2ExclusionZones = new RectCollection();
			// Exclude the add-on on page 2
			// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
			// Coordinates rotate with the page, if it has rotation applied.
			p2ExclusionZones.addRect(166, 47, 562, 222);
			options.addExclusionZonesForPage(p2ExclusionZones, 2);

			RectCollection p4InclusionZones = new RectCollection();
			RectCollection p4ExclusionZones = new RectCollection();
			// Only include the article text for page 4, exclude ads and headings
			p4InclusionZones.addRect(30, 432, 562, 684);
			p4ExclusionZones.addRect(30, 657, 295, 684);
			options.addInclusionZonesForPage(p4InclusionZones, 4);
			options.addExclusionZonesForPage(p4ExclusionZones, 4);

			DataExtractionModule.extractData(input_path + "newsletter.pdf", output_path + "newsletter_key_val_with_zones.json", DataExtractionModule.DataExtractionEngine.e_generic_key_value, options);

		} catch (Exception e) {
			System.out.println(e);
		}        
  }

	//---------------------------------------------------------------------------------------
	// The following sample illustrates how to extract document classes from PDF documents.
	//---------------------------------------------------------------------------------------
	public static void testDocClassifier() {
		try {
			// Test if the add-on is installed
			if (!DataExtractionModule.isModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_classification))
			{
				System.out.println();
				System.out.println("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.");
				System.out.println("---------------------------------------------------------------");
				System.out.println("The Data Extraction suite is an optional add-on, available for download");
				System.out.println("at http://www.pdftron.com/. If you have already downloaded this");
				System.out.println("module, ensure that the SDK is able to find the required files");
				System.out.println("using the PDFNet.addResourceSearchPath() function." );
				System.out.println();
				return;
			}
		} catch (PDFNetException e) {
			System.out.println("Data Extraction module not available, error:");
			e.printStackTrace();
			System.out.println(e);
		}

		// Relative path to the folder containing test files.
		String input_path = "../../TestFiles/";
		String output_path = "../../TestFiles/Output/";

		try {

			// Simple example: classify pages as a JSON file
			DataExtractionModule.extractData(input_path + "Invoice.pdf", output_path + "Invoice_Classified.json", DataExtractionModule.DataExtractionEngine.e_doc_classification);

			// Classify pages as a JSON string
			String json = DataExtractionModule.extractData(input_path + "Scientific_Publication.pdf", DataExtractionModule.DataExtractionEngine.e_doc_classification);
			writeTextToFile(output_path + "Scientific_Publication_Classified.json", json);

			// Example with customized options:
			DataExtractionOptions options = new DataExtractionOptions();
			// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
			options.setMinimumConfidenceThreshold(0.7);
			DataExtractionModule.extractData(input_path + "Email.pdf", output_path + "Email_Classified.json", DataExtractionModule.DataExtractionEngine.e_doc_classification, options);

		} catch (Exception e) {
			System.out.println(e);
		}        
  }

	public static void main(String[] args)
	{
		// The first step in every application using PDFNet is to initialize the 
		// library and set the path to common PDF resources. The library is usually 
		// initialized only once, but calling initialize() multiple times is also fine.
		PDFNet.initialize(PDFTronLicense.Key());
		PDFNet.addResourceSearchPath("../../../Lib/");

		testTabularData();
		testDocumentStructure();
		testFormFields();
		testGenericKeyValue();
		testDocClassifier();

		PDFNet.terminate();
	}
}

```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
 <?php
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------
if(file_exists("../../../PDFNetC/Lib/PDFNetPHP.php"))
include("../../../PDFNetC/Lib/PDFNetPHP.php");
include("../../LicenseKey/PHP/LicenseKey.php");

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from
// https://docs.apryse.com/core/guides/info/modules
//
// Please contact us if you have any questions.
//---------------------------------------------------------------------------------------

function WriteTextToFile($outputFile, $text)
{
	$outfile = fopen($outputFile, "w");
	fwrite($outfile, $text);
	fclose($outfile);
}

function main()
{
	// Relative path to the folder containing the test files.
	$inputPath = getcwd()."/../../TestFiles/";
	$outputPath = $inputPath."Output/";

	// The first step in every application using PDFNet is to initialize the 
	// library. The library is usually initialized only once, but calling 
	// Initialize() multiple times is also fine.
	global $LicenseKey;
	PDFNet::Initialize($LicenseKey);
	PDFNet::GetSystemFontList();    // Wait for fonts to be loaded if they haven't already. This is done because PHP can run into errors when shutting down if font loading is still in progress.
	
	//-----------------------------------------------------------------------------------

	PDFNet::AddResourceSearchPath("../../../PDFNetC/Lib/");

	//////////////////////////////////////////////////////////////////////////
	// The following sample illustrates how to extract tables from PDF documents.
	//////////////////////////////////////////////////////////////////////////

	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_Tabular)) {
		echo(nl2br("\n"));
		echo(nl2br("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.\n"));
		echo(nl2br("-----------------------------------------------------------------------------\n"));
		echo(nl2br("The Data Extraction suite is an optional add-on, available for download\n"));
		echo(nl2br("at https://docs.apryse.com/core/guides/info/modules. If you have already\n"));
		echo(nl2br("downloaded this module, ensure that the SDK is able to find the required files\n"));
		echo(nl2br("using the PDFNet::AddResourceSearchPath() function.\n"));
		echo(nl2br("\n"));
	}
	else {
		try {
			// Extract tabular data as a JSON file
			echo(nl2br("Extract tabular data as a JSON file\n"));

			$outputFile = $outputPath."table.json";
			DataExtractionModule::ExtractData($inputPath."table.pdf", $outputFile, DataExtractionModule::e_Tabular);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Extract tabular data as a JSON string
			echo(nl2br("Extract tabular data as a JSON string\n"));

			$outputFile = $outputPath."financial.json";
			$json = DataExtractionModule::ExtractData($inputPath."financial.pdf", DataExtractionModule::e_Tabular);
			WriteTextToFile($outputFile, $json);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Extract tabular data as an XLSX file
			echo(nl2br("Extract tabular data as an XLSX file\n"));

			$outputFile = $outputPath."table.xlsx";
			DataExtractionModule::ExtractToXLSX($inputPath."table.pdf", $outputFile);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Extract tabular data as an XLSX stream (also known as filter)
			echo(nl2br("Extract tabular data as an XLSX stream\n"));

			$outputFile = $outputPath."financial.xlsx";
			$outputXlsxStream = new MemoryFilter(0, false);
			$options = new DataExtractionOptions();
			$options->SetPages("1"); // page 1
			DataExtractionModule::ExtractToXLSX($inputPath."financial.pdf", $outputXlsxStream, $options);
			$outputXlsxStream->SetAsInputFilter();
			$outputXlsxStream->WriteToFile($outputFile, false);

			echo(nl2br("Result saved in " . $outputFile . "\n"));
		}
		catch(Exception $e) {
			echo(nl2br("Unable to extract tabular data, error: " . $e->getMessage() . "\n"));
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// The following sample illustrates how to extract document structure from PDF documents.
	//////////////////////////////////////////////////////////////////////////

	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_DocStructure)) {
		echo(nl2br("\n"));
		echo(nl2br("Unable to run Data Extraction: PDFTron SDK Structured Output module not available.\n"));
		echo(nl2br("-----------------------------------------------------------------------------\n"));
		echo(nl2br("The Data Extraction suite is an optional add-on, available for download\n"));
		echo(nl2br("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module. If you have already\n"));
		echo(nl2br("downloaded this module, ensure that the SDK is able to find the required files\n"));
		echo(nl2br("using the PDFNet::AddResourceSearchPath() function.\n"));
		echo(nl2br("\n"));
	}
	else {
		try {
			// Extract document structure as a JSON file
			echo(nl2br("Extract document structure as a JSON file\n"));

			$outputFile = $outputPath."paragraphs_and_tables.json";
			DataExtractionModule::ExtractData($inputPath."paragraphs_and_tables.pdf", $outputFile, DataExtractionModule::e_DocStructure);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Extract document structure as a JSON string
			echo(nl2br("Extract document structure as a JSON string\n"));

			$outputFile = $outputPath."tagged.json";
			$json = DataExtractionModule::ExtractData($inputPath."tagged.pdf", DataExtractionModule::e_DocStructure);
			WriteTextToFile($outputFile, $json);

			echo(nl2br("Result saved in " . $outputFile . "\n"));
		}
		catch(Exception $e) {
			echo(nl2br("Unable to extract document structure data, error: " . $e->getMessage() . "\n"));
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// The following sample illustrates how to extract form fields from PDF documents.
	//////////////////////////////////////////////////////////////////////////

	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_Form)) {
		echo(nl2br("\n"));
		echo(nl2br("Unable to run Data Extraction: PDFTron SDK AIFormFieldExtractor module not available.\n"));
		echo(nl2br("-----------------------------------------------------------------------------\n"));
		echo(nl2br("The Data Extraction suite is an optional add-on, available for download\n"));
		echo(nl2br("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already\n"));
		echo(nl2br("downloaded this module, ensure that the SDK is able to find the required files\n"));
		echo(nl2br("using the PDFNet::AddResourceSearchPath() function.\n"));
		echo(nl2br("\n"));
	}
	else {
		try {
			// Extract form fields as a JSON file
			echo(nl2br("Extract form fields as a JSON file\n"));

			$outputFile = $outputPath."formfields-scanned.json";
			DataExtractionModule::ExtractData($inputPath."formfields-scanned.pdf", $outputFile, DataExtractionModule::e_Form);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Extract form fields as a JSON string
			echo(nl2br("Extract form fields as a JSON string\n"));

			$outputFile = $outputPath."formfields.json";
			$json = DataExtractionModule::ExtractData($inputPath."formfields.pdf", DataExtractionModule::e_Form);
			WriteTextToFile($outputFile, $json);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Detect and add form fields to a PDF document.
			// PDF document already has form fields, and this sample will update to new found fields.
			echo(nl2br("Extract form fields as a PDF file\n"));

			$doc = new PDFDoc($inputPath."formfields-scanned-withfields.pdf");
			DataExtractionModule::DetectAndAddFormFieldsToPDF($doc);
			$doc->Save($outputPath."formfields-scanned-fields-new.pdf", SDFDoc::e_linearized);
			$doc->Close();

			echo(nl2br("Result saved in " . $outputPath ."formfields-scanned-fields-new.pdf" . "\n"));

			///////////////////////////////////////////////////////
			// Detect and add form fields to a PDF document.
			// PDF document already has form fields, and this sample will keep the original fields.
			echo(nl2br("Extract form fields as a PDF file\n"));
			
			$doc = new PDFDoc($inputPath."formfields-scanned-withfields.pdf");
			$options = new DataExtractionOptions();
			$options->SetOverlappingFormFieldBehavior("KeepOld");
			DataExtractionModule::DetectAndAddFormFieldsToPDF($doc, $options);
			$doc->Save($outputPath."formfields-scanned-fields-old.pdf", SDFDoc::e_linearized);
			$doc->Close();

			echo(nl2br("Result saved in " . $outputPath ."formfields-scanned-fields-old.pdf" . "\n"));

		}
		catch(Exception $e) {
			echo(nl2br("Unable to extract form fields data, error: " . $e->getMessage() . "\n"));
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// The following sample illustrates how to extract document structure from PDF documents.
	//////////////////////////////////////////////////////////////////////////

	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_GenericKeyValue)) {
		echo(nl2br("\n"));
		echo(nl2br("Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available.\n"));
		echo(nl2br("-----------------------------------------------------------------------------\n"));
		echo(nl2br("The Data Extraction suite is an optional add-on, available for download\n"));
		echo(nl2br("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already\n"));
		echo(nl2br("downloaded this module, ensure that the SDK is able to find the required files\n"));
		echo(nl2br("using the PDFNet::AddResourceSearchPath() function.\n"));
		echo(nl2br("\n"));
	}
	else {
		try {
			
			echo(nl2br("Extract key-value pairs from a PDF\n"));
			// Simple example: Extract Keys & Values as a JSON file
			$outputFile = $outputPath."newsletter_key_val.json";
			DataExtractionModule::ExtractData($inputPath."newsletter.pdf", $outputFile, DataExtractionModule::e_GenericKeyValue);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			// Example with customized options:
			// Extract Keys & Values from pages 2-4, excluding ads
			$options = new DataExtractionOptions();
			$options->setPages("2-4");

			$p2ExclusionZones = new RectCollection();
			// Exclude the add-on page 2
			// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
			// Coordinates rotate with the page, if it has rotation applied.
			$p2ExclusionZones->AddRect(new Rect(166.0, 47.0, 562.0, 222.0));
			$options->AddExclusionZonesForPage($p2ExclusionZones, 2);

			$p4InclusionZones = new RectCollection();
			$p4ExclusionZones = new RectCollection();
			// Only include the article text for page 4, exclude ads and headings
			$p4InclusionZones->AddRect(new Rect(30.0, 432.0, 562.0, 684.0));
			$p4ExclusionZones->AddRect(new Rect(30.0, 657.0, 295.0, 684.0));
			$options->AddInclusionZonesForPage($p4InclusionZones, 4);
			$options->AddExclusionZonesForPage($p4ExclusionZones, 4);

			echo(nl2br("Extract Key-Value pairs from specific pages and zones as a JSON file\n"));
			$outputFile = $outputPath."newsletter_key_val_with_zones.json";
			DataExtractionModule::ExtractData($inputPath."newsletter.pdf", $outputFile, DataExtractionModule::e_GenericKeyValue, $options);

			echo(nl2br("Result saved in " . $outputFile . "\n"));
		}
		catch(Exception $e) {
			echo(nl2br("Unable to extract document structure data, error: " . $e->getMessage() . "\n"));
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// The following sample illustrates how to extract document classes from PDF documents.
	//////////////////////////////////////////////////////////////////////////

	// Test if the add-on is installed
	if (!DataExtractionModule::IsModuleAvailable(DataExtractionModule::e_DocClassification)) {
		echo(nl2br("\n"));
		echo(nl2br("Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available.\n"));
		echo(nl2br("-----------------------------------------------------------------------------\n"));
		echo(nl2br("The Data Extraction suite is an optional add-on, available for download\n"));
		echo(nl2br("at https://docs.apryse.com/documentation/core/info/modules/. If you have already\n"));
		echo(nl2br("downloaded this module, ensure that the SDK is able to find the required files\n"));
		echo(nl2br("using the PDFNet::AddResourceSearchPath() function.\n"));
		echo(nl2br("\n"));
	}
	else {
		try {
			// Simple example: classify pages as a JSON file
			echo(nl2br("Classify pages as a JSON file\n"));

			$outputFile = $outputPath."Invoice_Classified.json";
			DataExtractionModule::ExtractData($inputPath."Invoice.pdf", $outputFile, DataExtractionModule::e_DocClassification);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Classify pages as a JSON string
			echo(nl2br("Classify pages as a JSON string\n"));

			$outputFile = $outputPath."Scientific_Publication_Classified.json";
			$json = DataExtractionModule::ExtractData($inputPath."Scientific_Publication.pdf", DataExtractionModule::e_DocClassification);
			WriteTextToFile($outputFile, $json);

			echo(nl2br("Result saved in " . $outputFile . "\n"));

			///////////////////////////////////////////////////////
			// Example with customized options:
			echo(nl2br("Classify pages with customized options\n"));

			$options = new DataExtractionOptions();
			// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
			$options->SetMinimumConfidenceThreshold(0.7);
			$outputFile = $outputPath."Email_Classified.json";
			DataExtractionModule::ExtractData($inputPath."Email.pdf", $outputFile, DataExtractionModule::e_DocClassification, $options);

			echo(nl2br("Result saved in " . $outputFile . "\n"));
		}
		catch(Exception $e) {
			echo(nl2br("Unable to extract document structure data, error: " . $e->getMessage() . "\n"));
		}
	}

	//-----------------------------------------------------------------------------------

	PDFNet::Terminate();
	echo(nl2br("Done.\n"));
}

main();
?>

```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from https://docs.apryse.com/core/guides/info/modules#data-extraction-module
//---------------------------------------------------------------------------------------

const fs = require('fs');
const { PDFNet } = require('../../lib/pdfnet.js');
const PDFTronLicense = require('../../LicenseKey/NODEJS/LicenseKey');

((exports) => {
	'use strict';

	exports.runDataExtractionTest = () => {

		const main = async () => {

			const inputPath = '../TestFiles/';
			const outputPath = '../TestFiles/Output/';

			//////////////////////////////////////////////////////////////////////////

			await PDFNet.addResourceSearchPath('../../lib/');

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract tables from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK Tabular Data module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract tabular data as a JSON file
					console.log('Extract tabular data as a JSON file');

					let outputFile = outputPath + 'table.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'table.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as a JSON string
					console.log('Extract tabular data as a JSON string');

					outputFile = outputPath + 'financial.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'financial.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as an XLSX file
					console.log('Extract tabular data as an XLSX file');

					outputFile = outputPath + 'table.xlsx';
					await PDFNet.DataExtractionModule.extractToXLSX(inputPath + 'table.pdf', outputFile);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as an XLSX stream (also known as filter)
					console.log('Extract tabular data as an XLSX stream');

					outputFile = outputPath + 'financial.xlsx';
					const outputXlsxStream = await PDFNet.Filter.createMemoryFilter(0, false);
					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					options.setPages('1'); // page 1
					await PDFNet.DataExtractionModule.extractToXLSXWithFilter(inputPath + 'financial.pdf', outputXlsxStream, options);
					outputXlsxStream.memoryFilterSetAsInputFilter();
					outputXlsxStream.writeToFile(outputFile, false);

					console.log('Result saved in ' + outputFile);
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract document structure from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK Structured Output module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract document structure as a JSON file
					console.log('Extract document structure as a JSON file');

					let outputFile = outputPath + 'paragraphs_and_tables.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'paragraphs_and_tables.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract document structure as a JSON string
					console.log('Extract document structure as a JSON string');

					outputFile = outputPath + 'tagged.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'tagged.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract form fields from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Form)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract form fields as a JSON file
					console.log('Extract form fields as a JSON file');

					let outputFile = outputPath + 'formfields-scanned.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'formfields-scanned.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_Form);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract form fields as a JSON string
					console.log('Extract form fields as a JSON string');

					outputFile = outputPath + 'formfields.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'formfields.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_Form);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);

					//////////////////////////////////////////////////////////////////////////
					// Detect and add form fields to a PDF document.
					// Document already has form fields, and this sample will update to new found fields.
					{
						console.log('Detect and add form fields in a PDF file, keep new fields');

						const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');

						await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc);
						outputFile = outputPath + 'formfields-scanned-fields-new.pdf';
						await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);

						console.log('Result saved in ' + outputFile);
					}

					//////////////////////////////////////////////////////////////////////////
					// Detect and add form fields to a PDF document.
					// Document already has form fields, and this sample will keep the original fields.
					{
						console.log('Detect and add form fields in a PDF file, keep old fields');

						const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');

						const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
						options.setOverlappingFormFieldBehavior('KeepOld');

						await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc, options);
						outputFile = outputPath + 'formfields-scanned-fields-old.pdf';
						await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);
					}

					console.log('Result saved in ' + outputFile);

				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract key-value pairs from PDF documents.
			//////////////////////////////////////////////////////////////////////////
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue)) {
				console.log();
				console.log('Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this');
				console.log('module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.');
				console.log();
			}
			else
			{
				try {
					// Simple example: Extract Keys & Values as a JSON file
					console.log('Extract Key-Value pairs as a JSON file');
					await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue);
					console.log('Result saved in ' + outputPath + 'newsletter_key_val.json');
					
					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					options.setPages('2-4');
				
					const p2ExclusionZones = [];
					// Exclude the add-on page 2
					// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
					// Coordinates rotate with the page, if it has rotation applied.
					p2ExclusionZones.push(new PDFNet.Rect(166, 47, 562, 222));
					options.addExclusionZonesForPage(p2ExclusionZones, 2);
				
					const p4InclusionZones = [];
					const p4ExclusionZones = [];
					// Only include the article text for page 4, exclude ads and headings
					p4InclusionZones.push(new PDFNet.Rect(30, 432, 562, 684));
					p4ExclusionZones.push(new PDFNet.Rect(30, 657, 295, 684));
					options.addInclusionZonesForPage(p4InclusionZones, 4);
					options.addExclusionZonesForPage(p4ExclusionZones, 4);
					console.log('Extract Key-Value pairs from specific pages and zones as a JSON file');
					await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val_with_zones.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue, options);
					console.log('Result saved in ' + outputPath + 'newsletter_key_val_with_zones.json');
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract document classes from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Simple example: classify pages as a JSON file
					console.log('Classify pages as a JSON file');

					let outputFile = outputPath + 'Invoice_Classified.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'Invoice.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Classify pages as a JSON string
					console.log('Classify pages as a JSON string');

					outputFile = outputPath + 'Scientific_Publication_Classified.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'Scientific_Publication.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);
					
					///////////////////////////////////////////////////////
					// Example with customized options:
					console.log('Classify pages with customized options');

					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
					options.setMinimumConfidenceThreshold(0.7);
					outputFile = outputPath + 'Email_Classified.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'Email.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification, options);

					console.log('Result saved in ' + outputFile);
					
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////

			console.log('Done.');
		};

		PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function (error) {
			console.log('Error: ' + JSON.stringify(error));
		}).then(function () { return PDFNet.shutdown(); });
	};
	exports.runDataExtractionTest();
})(exports);
// eslint-disable-next-line spaced-comment
//# sourceURL=DataExtractionTest.js

```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

import site
site.addsitedir("../../../PDFNetC/Lib")
import sys
from PDFNetPython import *

import platform

sys.path.append("../../LicenseKey/PYTHON")
from LicenseKey import *

#---------------------------------------------------------------------------------------
# The Data Extraction suite is an optional PDFNet add-on collection that can be used to
# extract various types of data from PDF documents.
#
# The Apryse SDK Data Extraction suite can be downloaded from
# https://docs.apryse.com/core/guides/info/modules#data-extraction-module
#
# Please contact us if you have any questions.
#---------------------------------------------------------------------------------------

# Relative path to the folder containing the test files.
inputPath = "../../TestFiles/"
outputPath = "../../TestFiles/Output/"

def WriteTextToFile(outputFile, text):
    # Write the contents of text to the disk
    f = open(outputFile, "w")
    try:
        f.write(text)
    finally:
        f.close()

def main():
    # The first step in every application using PDFNet is to initialize the 
    # library. The library is usually initialized only once, but calling 
    # Initialize() multiple times is also fine.
    PDFNet.Initialize(LicenseKey)
    
    PDFNet.AddResourceSearchPath("../../../PDFNetC/Lib/")

    #-----------------------------------------------------------------------------------
    # The following sample illustrates how to extract tables from PDF documents.
    #-----------------------------------------------------------------------------------

    # Test if the add-on is installed
    if not DataExtractionModule.IsModuleAvailable(DataExtractionModule.e_Tabular):
        print("")
        print("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.")
        print("-----------------------------------------------------------------------------")
        print("The Data Extraction suite is an optional add-on, available for download")
        print("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
        print("downloaded this module, ensure that the SDK is able to find the required files")
        print("using the PDFNet.AddResourceSearchPath() function.")
        print("")
    else:
        try:
            # Extract tabular data as a JSON file
            print("Extract tabular data as a JSON file")

            outputFile = outputPath + "table.json"
            DataExtractionModule.ExtractData(inputPath + "table.pdf", outputFile, DataExtractionModule.e_Tabular)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Extract tabular data as a JSON string
            print("Extract tabular data as a JSON string")

            outputFile = outputPath + "financial.json"
            json = DataExtractionModule.ExtractData(inputPath + "financial.pdf", DataExtractionModule.e_Tabular)
            WriteTextToFile(outputFile, json)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Extract tabular data as an XLSX file
            print("Extract tabular data as an XLSX file")

            outputFile = outputPath + "table.xlsx"
            DataExtractionModule.ExtractToXLSX(inputPath + "table.pdf", outputFile)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Extract tabular data as an XLSX stream (also known as filter)
            print("Extract tabular data as an XLSX stream")

            outputFile = outputPath + "financial.xlsx"
            options = DataExtractionOptions()
            options.SetPages("1") # page 1
            outputXlsxStream = MemoryFilter(0, False)
            DataExtractionModule.ExtractToXLSX(inputPath + "financial.pdf", outputXlsxStream, options)
            outputXlsxStream.SetAsInputFilter()
            outputXlsxStream.WriteToFile(outputFile, False)

            print("Result saved in " + outputFile)
        except Exception as e:
            print("Unable to extract tabular data, error: " + str(e))

    #-----------------------------------------------------------------------------------
    # The following sample illustrates how to extract document structure from PDF documents.
    #-----------------------------------------------------------------------------------

    # Test if the add-on is installed
    if not DataExtractionModule.IsModuleAvailable(DataExtractionModule.e_DocStructure):
        print("")
        print("Unable to run Data Extraction: PDFTron SDK Structured Output module not available.")
        print("-----------------------------------------------------------------------------")
        print("The Data Extraction suite is an optional add-on, available for download")
        print("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
        print("downloaded this module, ensure that the SDK is able to find the required files")
        print("using the PDFNet.AddResourceSearchPath() function.")
        print("")
    else:
        try:
            # Extract document structure as a JSON file
            print("Extract document structure as a JSON file")

            outputFile = outputPath + "paragraphs_and_tables.json"
            DataExtractionModule.ExtractData(inputPath + "paragraphs_and_tables.pdf", outputFile, DataExtractionModule.e_DocStructure)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Extract document structure as a JSON string
            print("Extract document structure as a JSON string")

            outputFile = outputPath + "tagged.json"
            json = DataExtractionModule.ExtractData(inputPath + "tagged.pdf", DataExtractionModule.e_DocStructure)
            WriteTextToFile(outputFile, json)

            print("Result saved in " + outputFile)
        except Exception as e:
            print("Unable to extract document structure data, error: " + str(e))

    #-----------------------------------------------------------------------------------
    # The following sample illustrates how to extract form fields from PDF documents.
    #-----------------------------------------------------------------------------------

    # Test if the add-on is installed
    if not DataExtractionModule.IsModuleAvailable(DataExtractionModule.e_Form):
        print("")
        print("Unable to run Data Extraction: PDFTron SDK AIFormFieldExtractor module not available.")
        print("-----------------------------------------------------------------------------")
        print("The Data Extraction suite is an optional add-on, available for download")
        print("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already")
        print("downloaded this module, ensure that the SDK is able to find the required files")
        print("using the PDFNet.AddResourceSearchPath() function.")
        print("")
    else:
        try:
            # Extract form fields as a JSON file
            print("Extract form fields as a JSON file")

            outputFile = outputPath + "formfields-scanned.json"
            DataExtractionModule.ExtractData(inputPath + "formfields-scanned.pdf", outputFile, DataExtractionModule.e_Form)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Extract form fields as a JSON string
            print("Extract form fields as a JSON string")

            outputFile = outputPath + "formfields.json"
            json = DataExtractionModule.ExtractData(inputPath + "formfields.pdf", DataExtractionModule.e_Form)
            WriteTextToFile(outputFile, json)

            print("Result saved in " + outputFile)

            #-----------------------------------------------------------------------------------
            # Detect and add form fields to a PDF document.
            # PDF document already has form fields, and this sample will update to new found fields.
            print("Extract form fields as a pdf file, update to new")

            doc = PDFDoc(inputPath + "formfields-scanned-withfields.pdf")
            
            DataExtractionModule.DetectAndAddFormFieldsToPDF(doc)
            
            outputFile = outputPath + "formfields-scanned-fields-new.pdf"
            doc.Save(outputFile, SDFDoc.e_linearized)
            doc.Close()
            
            print("Result saved in " + outputFile)

            #-----------------------------------------------------------------------------------
            # Detect and add form fields to a PDF document.
            # PDF document already has form fields, and this sample will keep the original fields.
            print("Extract form fields as a pdf file, keep original")

            doc = PDFDoc(inputPath + "formfields-scanned-withfields.pdf")
            
            options = DataExtractionOptions()
            options.SetOverlappingFormFieldBehavior("KeepOld")
            DataExtractionModule.DetectAndAddFormFieldsToPDF(doc, options)
            
            outputFile = outputPath + "formfields-scanned-fields-old.pdf"
            doc.Save(outputFile, SDFDoc.e_linearized)
            doc.Close()
            
            print("Result saved in " + outputFile)

        except Exception as e:
            print("Unable to extract form fields data, error: " + str(e))

    #---------------------------------------------------------------------------------------
    # The following sample illustrates how to extract key-value pairs from PDF documents.
    #---------------------------------------------------------------------------------------
    if not DataExtractionModule.IsModuleAvailable(DataExtractionModule.e_GenericKeyValue):
        print()
        print("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.")
        print("---------------------------------------------------------------")
        print("The Data Extraction suite is an optional add-on, available for download")
        print("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this")
        print("module, ensure that the SDK is able to find the required files")
        print("using the PDFNet.AddResourceSearchPath() function.")
        print()
    else:
        try:
            print("Extract key-value pairs from a PDF")
            # Simple example: Extract Keys & Values as a JSON file
            DataExtractionModule.ExtractData(inputPath + "newsletter.pdf", outputPath + "newsletter_key_val.json", DataExtractionModule.e_GenericKeyValue)
            print("Result saved in " + outputPath + "newsletter_key_val.json")

            # Example with customized options:
            # Extract Keys & Values from pages 2-4, excluding ads
            options = DataExtractionOptions()
            options.SetPages("2-4")

            p2_exclusion_zones = RectCollection()
            # Exclude the add-on on page 2
            # These coordinates are in PDF user space, with the origin at the bottom left corner of the page
            # Coordinates rotate with the page, if it has rotation applied.
            p2_exclusion_zones.AddRect(Rect(166, 47, 562, 222))
            options.AddExclusionZonesForPage(p2_exclusion_zones, 2)

            p4_inclusion_zones = RectCollection()
            p4_exclusion_zones = RectCollection()
            # Only include the article text for page 4, exclude ads and headings
            p4_inclusion_zones.AddRect(Rect(30, 432, 562, 684))
            p4_exclusion_zones.AddRect(Rect(30, 657, 295, 684))
            options.AddInclusionZonesForPage(p4_inclusion_zones, 4)
            options.AddExclusionZonesForPage(p4_exclusion_zones, 4)
            print("Extract Key-Value pairs from specific pages and zones as a JSON file")
            DataExtractionModule.ExtractData(inputPath + "newsletter.pdf", outputPath + "newsletter_key_val_with_zones.json", DataExtractionModule.e_GenericKeyValue, options)
            print("Result saved in " + outputPath + "newsletter_key_val_with_zones.json")
        except Exception as e:
                print("Unable to extract key-value data, error: " + str(e))


    #-----------------------------------------------------------------------------------
    # The following sample illustrates how to extract document classes from PDF documents.
    #-----------------------------------------------------------------------------------

    # Test if the add-on is installed
    if not DataExtractionModule.IsModuleAvailable(DataExtractionModule.e_DocClassification):
        print("")
        print("Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available.")
        print("-----------------------------------------------------------------------------")
        print("The Data Extraction suite is an optional add-on, available for download")
        print("at https://docs.apryse.com/documentation/core/info/modules/. If you have already")
        print("downloaded this module, ensure that the SDK is able to find the required files")
        print("using the PDFNet.AddResourceSearchPath() function.")
        print("")
    else:
        try:
            # Simple example: classify pages as a JSON file
            print("Classify pages as a JSON file")

            outputFile = outputPath + "Invoice_Classified.json"
            DataExtractionModule.ExtractData(inputPath + "Invoice.pdf", outputFile, DataExtractionModule.e_DocClassification)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Classify pages as a JSON string
            print("Classify pages as a JSON string")

            outputFile = outputPath + "Scientific_Publication_Classified.json"
            json = DataExtractionModule.ExtractData(inputPath + "Scientific_Publication.pdf", DataExtractionModule.e_DocClassification)
            WriteTextToFile(outputFile, json)

            print("Result saved in " + outputFile)

            #------------------------------------------------------
            # Example with customized options:
            print("Classify pages with customized options")

            options = DataExtractionOptions()
            # Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
            options.SetMinimumConfidenceThreshold(0.7)
            outputFile = outputPath + "Email_Classified.json"
            DataExtractionModule.ExtractData(inputPath + "Email.pdf", outputFile, DataExtractionModule.e_DocClassification, options)

            print("Result saved in " + outputFile)

        except Exception as e:
            print("Unable to extract document structure data, error: " + str(e))

    PDFNet.Terminate()
    print("Done.")
    
if __name__ == '__main__':
    main()

```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

require '../../../PDFNetC/Lib/PDFNetRuby'
include PDFNetRuby
require '../../LicenseKey/RUBY/LicenseKey'

$stdout.sync = true

#---------------------------------------------------------------------------------------
# The Data Extraction suite is an optional PDFNet add-on collection that can be used to
# extract various types of data from PDF documents.
#
# The Apryse SDK Data Extraction suite can be downloaded from
# https://docs.apryse.com/core/guides/info/modules#data-extraction-module
#
# Please contact us if you have any questions.
#---------------------------------------------------------------------------------------

# Relative path to the folder containing the test files.
$inputPath = "../../TestFiles/"
$outputPath = "../../TestFiles/Output/"
	
def main()
	# The first step in every application using PDFNet is to initialize the 
	# library. The library is usually initialized only once, but calling 
	# Initialize() multiple times is also fine.
	PDFNet.Initialize(PDFTronLicense.Key)

	PDFNet.AddResourceSearchPath("../../../PDFNetC/Lib/")

	#-----------------------------------------------------------------------------------
	# The following sample illustrates how to extract tables from PDF documents.
	#-----------------------------------------------------------------------------------

	# Test if the add-on is installed
	if !DataExtractionModule.IsModuleAvailable(DataExtractionModule::E_Tabular) then
		puts ""
		puts "Unable to run Data Extraction: Apryse SDK Tabular Data module not available."
		puts "-----------------------------------------------------------------------------"
		puts "The Data Extraction suite is an optional add-on, available for download"
		puts "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already"
		puts "downloaded this module, ensure that the SDK is able to find the required files"
		puts "using the PDFNet.AddResourceSearchPath() function."
		puts ""
	else
		begin
			# Extract tabular data as a JSON file
			puts "Extract tabular data as a JSON file"
	
			outputFile = $outputPath + "table.json"
			DataExtractionModule.ExtractData($inputPath + "table.pdf", outputFile, DataExtractionModule::E_Tabular)

			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Extract tabular data as a JSON string
			puts "Extract tabular data as a JSON string"
	
			outputFile = $outputPath + "financial.json"
			json = DataExtractionModule.ExtractData($inputPath + "financial.pdf", DataExtractionModule::E_Tabular)
			File.open(outputFile, 'w') { |file| file.write(json) }
	
			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Extract tabular data as an XLSX file
			puts "Extract tabular data as an XLSX file"
	
			outputFile = $outputPath + "table.xlsx"
			DataExtractionModule.ExtractToXLSX($inputPath + "table.pdf", outputFile)
	
			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Extract tabular data as an XLSX stream (also known as filter)
			puts "Extract tabular data as an XLSX stream"
	
			outputFile = $outputPath + "financial.xlsx"
			outputXlsxStream = MemoryFilter.new(0, false)
			options = DataExtractionOptions.new()
			options.SetPages("1") # page 1
			DataExtractionModule.ExtractToXLSX($inputPath + "financial.pdf", outputXlsxStream, options)
			outputXlsxStream.SetAsInputFilter()
			outputXlsxStream.WriteToFile(outputFile, false)
	
			puts "Result saved in " + outputFile
		rescue => error
			puts "Unable to extract tabular data, error: " + error.message
		end
	end

	#-----------------------------------------------------------------------------------
	# The following sample illustrates how to extract document structure from PDF documents.
	#-----------------------------------------------------------------------------------

	# Test if the add-on is installed
	if !DataExtractionModule.IsModuleAvailable(DataExtractionModule::E_DocStructure) then
		puts ""
		puts "Unable to run Data Extraction: PDFTron SDK Structured Output module not available."
		puts "-----------------------------------------------------------------------------"
		puts "The Data Extraction suite is an optional add-on, available for download"
		puts "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already"
		puts "downloaded this module, ensure that the SDK is able to find the required files"
		puts "using the PDFNet.AddResourceSearchPath() function."
		puts ""
	else
		begin
			# Extract document structure as a JSON file
			puts "Extract document structure as a JSON file"
	
			outputFile = $outputPath + "paragraphs_and_tables.json"
			DataExtractionModule.ExtractData($inputPath + "paragraphs_and_tables.pdf", outputFile, DataExtractionModule::E_DocStructure)

			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Extract document structure as a JSON string
			puts "Extract document structure as a JSON string"
	
			outputFile = $outputPath + "tagged.json"
			json = DataExtractionModule.ExtractData($inputPath + "tagged.pdf", DataExtractionModule::E_DocStructure)
			File.open(outputFile, 'w') { |file| file.write(json) }
	
			puts "Result saved in " + outputFile
		rescue => error
			puts "Unable to extract document structure data, error: " + error.message
		end
	end

	#-----------------------------------------------------------------------------------
	# The following sample illustrates how to extract form fields from PDF documents.
	#-----------------------------------------------------------------------------------

	# Test if the add-on is installed
	if !DataExtractionModule.IsModuleAvailable(DataExtractionModule::E_Form) then
		puts ""
		puts "Unable to run Data Extraction: PDFTron SDK AIFormFieldExtractor module not available."
		puts "-----------------------------------------------------------------------------"
		puts "The Data Extraction suite is an optional add-on, available for download"
		puts "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already"
		puts "downloaded this module, ensure that the SDK is able to find the required files"
		puts "using the PDFNet.AddResourceSearchPath() function."
		puts ""
	else
		begin
			# Extract form fields as a JSON file
			puts "Extract form fields as a JSON file"
	
			outputFile = $outputPath + "formfields-scanned.json"
			DataExtractionModule.ExtractData($inputPath + "formfields-scanned.pdf", outputFile, DataExtractionModule::E_Form)

			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Extract form fields as a JSON string
			puts "Extract form fields as a JSON string"
	
			outputFile = $outputPath + "formfields.json"
			json = DataExtractionModule.ExtractData($inputPath + "formfields.pdf", DataExtractionModule::E_Form)
			File.open(outputFile, 'w') { |file| file.write(json) }
	
			puts "Result saved in " + outputFile
			
			#-----------------------------------------------------------------------------------
			# Detect and add form fields to a PDF document.
			# PDF document already has form fields, and this sample will update to the new fields.
			puts "Extract document structure as a PDF file"
			doc = PDFDoc.new($inputPath + "formfields-scanned-withfields.pdf")
	
			outputFile = $outputPath + "formfields-scanned-fields-new.pdf"
			
			DataExtractionModule.DetectAndAddFormFieldsToPDF(doc)
			doc.Save(outputFile, SDFDoc::E_linearized);
			doc.Close

			puts "Result saved in " + outputFile

			#-----------------------------------------------------------------------------------
			# Detect and add form fields to a PDF document.
			# PDF document already has form fields, and this sample will keep the original fields.
			puts "Extract document structure as a PDF file"
			doc = PDFDoc.new($inputPath + "formfields-scanned-withfields.pdf")
	
			outputFile = $outputPath + "formfields-scanned-fields-old.pdf"
			
			options = DataExtractionOptions.new()
			options.SetOverlappingFormFieldBehavior("KeepOld")
			DataExtractionModule.DetectAndAddFormFieldsToPDF(doc, options)
			doc.Save(outputFile, SDFDoc::E_linearized);
			doc.Close

			puts "Result saved in " + outputFile


		rescue => error
			puts "Unable to extract form fields data, error: " + error.message
		end
	end

	if !DataExtractionModule.IsModuleAvailable(DataExtractionModule::E_GenericKeyValue) then
		puts ""
		puts "Unable to run Data Extraction: PDFTron SDK AIFormFieldExtractor module not available."
		puts "-----------------------------------------------------------------------------"
		puts "The Data Extraction suite is an optional add-on, available for download"
		puts "at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already"
		puts "downloaded this module, ensure that the SDK is able to find the required files"
		puts "using the PDFNet.AddResourceSearchPath() function."
		puts ""
	else
		begin
        	puts "Extract key-value pairs from a PDF"
			# Simple example: Extract Keys & Values as a JSON file
			DataExtractionModule.ExtractData($inputPath + "newsletter.pdf", $outputPath + "newsletter_key_val.json", DataExtractionModule::E_GenericKeyValue)
			puts "Result saved in " + $outputPath + "newsletter_key_val.json"

			# Example with customized options:
			# Extract Keys & Values from pages 2-4, excluding ads
			options = DataExtractionOptions.new()
			options.SetPages("2-4")

			p2_exclusion_zones = RectCollection.new()
			# Exclude the add-on on page 2
			# These coordinates are in PDF user space, with the origin at the bottom left corner of the page
			# Coordinates rotate with the page, if it has rotation applied.
			p2_exclusion_zones.AddRect(Rect.new(166, 47, 562, 222))
			options.AddExclusionZonesForPage(p2_exclusion_zones, 2)

			p4_inclusion_zones = RectCollection.new()
			p4_exclusion_zones = RectCollection.new()
			# Only include the article text for page 4, exclude ads and headings
			p4_inclusion_zones.AddRect(Rect.new(30, 432, 562, 684))
			p4_exclusion_zones.AddRect(Rect.new(30, 657, 295, 684))
			options.AddInclusionZonesForPage(p4_inclusion_zones, 4)
			options.AddExclusionZonesForPage(p4_exclusion_zones, 4)
			puts "Extract Key-Value pairs from specific pages and zones as a JSON file"
			DataExtractionModule.ExtractData($inputPath + "newsletter.pdf", $outputPath + "newsletter_key_val_with_zones.json", DataExtractionModule::E_GenericKeyValue, options)
			puts "Result saved in " + $outputPath + "newsletter_key_val_with_zones.json"

		rescue => error
			puts "Unable to extract form fields data, error: " + error.message
		end
	end

	#-----------------------------------------------------------------------------------
	# The following sample illustrates how to extract document classes from PDF documents.
	#-----------------------------------------------------------------------------------

	# Test if the add-on is installed
	if !DataExtractionModule.IsModuleAvailable(DataExtractionModule::E_DocClassification) then
		puts ""
		puts "Unable to run Data Extraction: PDFTron SDK AIPageObjectExtractor module not available."
		puts "-----------------------------------------------------------------------------"
		puts "The Data Extraction suite is an optional add-on, available for download"
		puts "at https://docs.apryse.com/documentation/core/info/modules/. If you have already"
		puts "downloaded this module, ensure that the SDK is able to find the required files"
		puts "using the PDFNet.AddResourceSearchPath() function."
		puts ""
	else
		begin
			# Simple example: classify pages as a JSON file
			puts "Classify pages as a JSON file"
	
			outputFile = $outputPath + "Invoice_Classified.json"
			DataExtractionModule.ExtractData($inputPath + "Invoice.pdf", outputFile, DataExtractionModule::E_DocClassification)

			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Classify pages as a JSON string
			puts "Classify pages as a JSON string"
	
			outputFile = $outputPath + "Scientific_Publication_Classified.json"
			json = DataExtractionModule.ExtractData($inputPath + "Scientific_Publication.pdf", DataExtractionModule::E_DocClassification)
			File.open(outputFile, 'w') { |file| file.write(json) }
	
			puts "Result saved in " + outputFile

			#------------------------------------------------------
			# Example with customized options:
			puts "Classify pages with customized options"
	
			options = DataExtractionOptions.new()
			# Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
			options.SetMinimumConfidenceThreshold(0.7)
			outputFile = $outputPath + "Email_Classified.json"
			DataExtractionModule.ExtractData($inputPath + "Email.pdf", outputFile, DataExtractionModule::E_DocClassification, options)

			puts "Result saved in " + outputFile
			
		rescue => error
			puts "Unable to extract document structure data, error: " + error.message
		end
	end

	#-----------------------------------------------------------------------------------

	PDFNet.Terminate
	puts "Done."
end

main()

```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
'
' Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved.
'

Imports pdftron
Imports pdftron.Common
Imports pdftron.PDF
Imports pdftron.Filters

' The Data Extraction suite is an optional PDFNet add-on collection that can be used to
' extract various types of data from PDF documents.
' The Apryse SDK Data Extraction suite can be downloaded from https://docs.apryse.com/core/guides/info/modules#data-extraction-module

Module DataExtractionTestVB
	Dim pdfNetLoader As PDFNetLoader
	Sub New()
		pdfNetLoader = pdftron.PDFNetLoader.Instance()
	End Sub

	' Relative path to the folder containing test files.
	Dim input_path As String = "../../../../TestFiles/"
	Dim output_path As String = "../../../../TestFiles/Output/"

	Sub Main()
		PDFNet.Initialize(PDFTronLicense.Key)
		PDFNet.AddResourceSearchPath("../../../../../Lib/")

		TestTabularData()
		TestDocumentStructure()
		TestFormFields()
		TestGenericKeyValue()
		TestDocClassifier()

		PDFNet.Terminate()
	End Sub


	' The following sample illustrates how to extract tables from PDF documents.
	Sub TestTabularData()
		' Test if the add-on is installed
		If Not DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_tabular) Then
			Console.WriteLine()
			Console.WriteLine("Unable to run Data Extraction: Apryse SDK Tabular Data module not available.")
			Console.WriteLine("---------------------------------------------------------------")
			Console.WriteLine("The Data Extraction suite is an optional add-on, available for download")
			Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this")
			Console.WriteLine("module, ensure that the SDK is able to find the required files")
			Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.")
			Console.WriteLine()
			Return
		End If

		Try
			' Extract tabular data as a JSON file
			DataExtractionModule.ExtractData(input_path & "table.pdf", output_path & "table.json", DataExtractionModule.DataExtractionEngine.e_tabular)

			' Extract tabular data as a JSON string
			Dim json As String = DataExtractionModule.ExtractData(input_path & "financial.pdf", DataExtractionModule.DataExtractionEngine.e_tabular)
			System.IO.File.WriteAllText(output_path & "financial.json", json)

			' Extract tabular data as an XLSX file
			DataExtractionModule.ExtractToXLSX(input_path & "table.pdf", output_path & "table.xlsx")

			' Extract tabular data as an XLSX stream (also known as filter)
			Dim output_xlsx_stream As MemoryFilter = New MemoryFilter(0, False)
			DataExtractionModule.ExtractToXLSX(input_path & "financial.pdf", output_xlsx_stream)
			output_xlsx_stream.SetAsInputFilter()
			output_xlsx_stream.WriteToFile(output_path & "financial.xlsx", False)

		Catch e As PDFNetException
			Console.WriteLine(e.Message)
		End Try
	End Sub


	' The following sample illustrates how to extract document structure from PDF documents.
	Sub TestDocumentStructure()
		' Test if the add-on is installed
		If Not DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_structure) Then
			Console.WriteLine()
			Console.WriteLine("Unable to run Data Extraction: Apryse SDK Structured Output module not available.")
			Console.WriteLine("---------------------------------------------------------------")
			Console.WriteLine("The Data Extraction suite is an optional add-on, available for download")
			Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this")
			Console.WriteLine("module, ensure that the SDK is able to find the required files")
			Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.")
			Console.WriteLine()
			Return
		End If

		Try
			' Extract document structure as a JSON file
			DataExtractionModule.ExtractData(input_path & "paragraphs_and_tables.pdf", output_path & "paragraphs_and_tables.json", DataExtractionModule.DataExtractionEngine.e_doc_structure)

			' Extract document structure as a JSON string
			Dim json As String = DataExtractionModule.ExtractData(input_path & "tagged.pdf", DataExtractionModule.DataExtractionEngine.e_doc_structure)
			System.IO.File.WriteAllText(output_path & "tagged.json", json)

		Catch e As PDFNetException
			Console.WriteLine(e.Message)
		End Try
	End Sub


	' The following sample illustrates how to extract form fields from PDF documents.
	Sub TestFormFields()
		' Test if the add-on is installed
		If Not DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_form) Then
			Console.WriteLine()
			Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.")
			Console.WriteLine("---------------------------------------------------------------")
			Console.WriteLine("The Data Extraction suite is an optional add-on, available for download")
			Console.WriteLine("at https://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this")
			Console.WriteLine("module, ensure that the SDK is able to find the required files")
			Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.")
			Console.WriteLine()
			Return
		End If

		Try
			' Extract form fields as a JSON file
			DataExtractionModule.ExtractData(input_path & "formfields-scanned.pdf", output_path & "formfields-scanned.json", DataExtractionModule.DataExtractionEngine.e_form)

			' Extract form fields as a JSON string
			Dim json As String = DataExtractionModule.ExtractData(input_path & "formfields.pdf", DataExtractionModule.DataExtractionEngine.e_form)
			System.IO.File.WriteAllText(output_path & "formfields.json", json)

			' Detect and add form fields to a PDF document.
			' PDF document already has form fields, and this sample will update to new found fields.
			Using doc = New PDFDoc(input_path & "formfields-scanned-withfields.pdf")
				DataExtractionModule.DetectAndAddFormFieldsToPDF(doc)
				doc.Save(output_path & "formfields-scanned-fields-new.pdf", SDF.SDFDoc.SaveOptions.e_linearized)
			End Using

			' Detect and add form fields to a PDF document.
			' PDF document already has form fields, and this sample will keep the original fields.
			Using doc = New PDFDoc(input_path & "formfields-scanned-withfields.pdf")
				Dim options = New DataExtractionOptions()
				options.SetOverlappingFormFieldBehavior("KeepOld")
				DataExtractionModule.DetectAndAddFormFieldsToPDF(doc, options)
				doc.Save(output_path & "formfields-scanned-fields-old.pdf", SDF.SDFDoc.SaveOptions.e_linearized)
			End Using

		Catch e As PDFNetException
			Console.WriteLine(e.Message)
		End Try

	End Sub

	' The following sample illustrates how to extract key-value pairs from PDF documents.
	Sub TestGenericKeyValue()
		If Not DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_generic_key_value) Then
			Console.WriteLine()
			Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.")
			Console.WriteLine("---------------------------------------------------------------")
			Console.WriteLine("Thehttps://docs.apryse.com/core/guides/info/modules#data-extraction-module . If you have already downloaded this")
			Console.WriteLine("module, ensure that the SDK is able to find the required files")
			Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.")
			Console.WriteLine()
			Return
		End If

		' Simple example: Extract Keys & Values as a JSON file
		DataExtractionModule.ExtractData(input_path & "newsletter.pdf", output_path & "newsletter_key_val.json", DataExtractionModule.DataExtractionEngine.e_generic_key_value)

		' Example with customized options:
		' Extract Keys & Values from pages 2-4, excluding ads
		Dim options As New DataExtractionOptions()
		options.SetPages("2-4")

		Dim p2ExclusionZones As New RectCollection()
		' Exclude the add-on on page 2
		' These coordinates are in PDF user space, with the origin at the bottom left corner of the page
		' Coordinates rotate with the page, if it has rotation applied.
		p2ExclusionZones.AddRect(166, 47, 562, 222)
		options.AddExclusionZonesForPage(p2ExclusionZones, 2)

		Dim p4InclusionZones As New RectCollection()
		Dim p4ExclusionZones As New RectCollection()
		' Only include the article text for page 4, exclude ads and headings
		p4InclusionZones.AddRect(30, 432, 562, 684)
		p4ExclusionZones.AddRect(30, 657, 295, 684)
		options.AddInclusionZonesForPage(p4InclusionZones, 4)
		options.AddExclusionZonesForPage(p4ExclusionZones, 4)

		DataExtractionModule.ExtractData(input_path & "newsletter.pdf", output_path & "newsletter_key_val_with_zones.json",DataExtractionModule.DataExtractionEngine.e_generic_key_value, options)
	End Sub

	' The following sample illustrates how to extract document classes from PDF documents.
	Sub TestDocClassifier()
		' Test if the add-on is installed
		If Not DataExtractionModule.IsModuleAvailable(DataExtractionModule.DataExtractionEngine.e_doc_classification) Then
			Console.WriteLine()
			Console.WriteLine("Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.")
			Console.WriteLine("---------------------------------------------------------------")
			Console.WriteLine("The Data Extraction suite is an optional add-on, available for download")
			Console.WriteLine("at http://www.pdftron.com/. If you have already downloaded this")
			Console.WriteLine("module, ensure that the SDK is able to find the required files")
			Console.WriteLine("using the PDFNet.AddResourceSearchPath() function.")
			Console.WriteLine()
			Return
		End If

		Try
			' Simple example: classify pages as a JSON file
			DataExtractionModule.ExtractData(input_path & "Invoice.pdf", output_path & "Invoice_Classified.json", DataExtractionModule.DataExtractionEngine.e_doc_classification)

			' Classify pages as a JSON string
			Dim json As String = DataExtractionModule.ExtractData(input_path & "Scientific_Publication.pdf", DataExtractionModule.DataExtractionEngine.e_doc_classification)
			System.IO.File.WriteAllText(output_path & "Scientific_Publication_Classified.json", json)

			' Example with customized options:
			Dim options As New DataExtractionOptions()
			' Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
			options.SetMinimumConfidenceThreshold(0.7)
			DataExtractionModule.ExtractData(input_path & "Email.pdf", output_path & "Email_Classified.json",DataExtractionModule.DataExtractionEngine.e_doc_classification, options)

		Catch e As PDFNetException
			Console.WriteLine(e.Message)
		End Try
	End Sub

End Module

```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# 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/core/get-started/samples/dataextractiontest.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.
