> 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/textextracttest.md).

# Extract Text, Read, Parse PDF - TextExtract

Sample code for using Apryse SDK to read a PDF (parse and extract text), provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby, Go and VB.

Sample code for using Apryse SDK to read a PDF (parse and extract text), provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby, Go and VB. If you'd like to search text on PDF pages, see our [code sample for text search](/core/get-started/samples/textsearchtest.md).

Learn more about our full [PDF Data Extraction SDK Capabilities](https://apryse.com/capabilities/extraction).

To start your free trial, [get stated with Server SDK](/core/get-started/get-started.md).

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

```csharp
//
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
//

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


namespace TextExtractTestCS
{
	// This sample illustrates various text extraction capabilities of PDFNet.

	class Class1
	{		
		private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
		static Class1() {}
		
		static void Main(string[] args)
		{
			PDFNet.Initialize(PDFTronLicense.Key);

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

			bool example1_basic     = false;
			bool example2_xml       = false;
			bool example3_wordlist  = false;
			bool example4_advanced  = true;
			bool example5_low_level = false;

			// Sample code showing how to use high-level text extraction APIs.
			try	
			{
				using (PDFDoc doc = new PDFDoc(input_path + "newsletter.pdf"))
				{
					doc.InitSecurityHandler();

					Page page = doc.GetPage(1);
					if (page == null) {
						Console.WriteLine("Page not found.");
						return;
					}

					using (TextExtractor txt = new TextExtractor())
					{
						txt.Begin(page);  // Read the page.
						// Other options you may want to consider...
						// txt.Begin(page, null, TextExtractor.ProcessingFlags.e_no_dup_remove);
						// txt.Begin(page, null, TextExtractor.ProcessingFlags.e_remove_hidden_text);
						// ...

						// Example 1. Get all text on the page in a single string.
						// Words will be separated with space or new line characters.
						if (example1_basic) 
						{
							// Get the word count.
							Console.WriteLine("Word Count: {0}", txt.GetWordCount());
						
							Console.WriteLine("\n\n- GetAsText --------------------------\n{0}", txt.GetAsText());
							Console.WriteLine("-----------------------------------------------------------");
						}

						// Example 2. Get XML logical structure for the page.
						if (example2_xml) 
						{
							String text = txt.GetAsXML(TextExtractor.XMLOutputFlags.e_words_as_elements | TextExtractor.XMLOutputFlags.e_output_bbox | TextExtractor.XMLOutputFlags.e_output_style_info);
							Console.WriteLine("\n\n- GetAsXML  --------------------------\n{0}", text);
							Console.WriteLine("-----------------------------------------------------------");
						}

						// Example 3. Extract words one by one.
						if (example3_wordlist) 
						{
							TextExtractor.Word word;
							for (TextExtractor.Line line = txt.GetFirstLine(); line.IsValid(); line=line.GetNextLine())	
							{
								for (word=line.GetFirstWord(); word.IsValid(); word=word.GetNextWord()) 
								{
									Console.WriteLine(word.GetString());
								}
							}
							Console.WriteLine("-----------------------------------------------------------");
						}

						// Example 3. A more advanced text extraction example. 
						// The output is XML structure containing paragraphs, lines, words, 
						// as well as style and positioning information.
						if (example4_advanced) 
						{
							Rect bbox;
							int cur_flow_id=-1, cur_para_id=-1;

							TextExtractor.Line line;
							TextExtractor.Word word;
							TextExtractor.Style s, line_style;

							Console.WriteLine("<PDFText>");
							// For each line on the page...
							for (line=txt.GetFirstLine(); line.IsValid(); line=line.GetNextLine())
							{
								if (line.GetNumWords() == 0)
								{
									continue;
								}

								if (cur_flow_id != line.GetFlowID()) {
									if (cur_flow_id != -1) {
										if (cur_para_id != -1) {
											cur_para_id = -1;
											Console.WriteLine("</Para>");
										}
										Console.WriteLine("</Flow>");
									}
									cur_flow_id = line.GetFlowID();
									Console.WriteLine("<Flow id=\"{0}\">", cur_flow_id);
								}

								if (cur_para_id != line.GetParagraphID()) {
									if (cur_para_id != -1)
										Console.WriteLine("</Para>");
									cur_para_id = line.GetParagraphID();
									Console.WriteLine("<Para id=\"{0}\">", cur_para_id);
								}	

								bbox = line.GetBBox();
								line_style = line.GetStyle();
								Console.Write("<Line box=\"{0}, {1}, {2}, {3}\"", bbox.x1.ToString("0.00"), bbox.y1.ToString("0.00"), bbox.x2.ToString("0.00"), bbox.y2.ToString("0.00"));
								PrintStyle(line_style);
								Console.Write(" cur_num=\"" + line.GetCurrentNum() + "\"" + ">\n");

								// For each word in the line...
								for (word=line.GetFirstWord(); word.IsValid(); word=word.GetNextWord())
								{
									// Output the bounding box for the word.
									bbox = word.GetBBox();
									Console.Write("<Word box=\"{0}, {1}, {2}, {3}\"", bbox.x1.ToString("0.00"), bbox.y1.ToString("0.00"), bbox.x2.ToString("0.00"), bbox.y2.ToString("0.00"));
									Console.Write(" cur_num=\"" + word.GetCurrentNum() + "\"");
									int sz = word.GetStringLen();
									if (sz == 0) continue;

									// If the word style is different from the parent style, output the new style.
									s = word.GetStyle();
									if (s != line_style) {
										PrintStyle(s);
									}

									Console.Write(">{0}", word.GetString());
									Console.WriteLine("</Word>");
								}
								Console.WriteLine("</Line>");
							}

							if (cur_flow_id != -1) {
								if (cur_para_id != -1) {
									cur_para_id = -1;
									Console.WriteLine("</Para>");
								}
								Console.WriteLine("</Flow>");
							}
						}

					}
					Console.WriteLine("</PDFText>");
				}
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}

			// Sample code showing how to use low-level text extraction APIs.
			if (example5_low_level)
			{
				try	
				{
					LowLevelTextExtractUtils util = new LowLevelTextExtractUtils();
					using (PDFDoc doc = new PDFDoc(input_path + "newsletter.pdf"))
					{
						doc.InitSecurityHandler();

						// Example 1. Extract all text content from the document
						using (ElementReader reader = new ElementReader())
						{
							PageIterator itr = doc.GetPageIterator();
							//for (; itr.HasNext(); itr.Next()) //  Read every page
							{				
								reader.Begin(itr.Current());
								LowLevelTextExtractUtils.DumpAllText(reader);
								reader.End();
							}

							// Example 2. Extract text based on the selection rectangle.
							Console.WriteLine("----------------------------------------------------");
							Console.WriteLine("Extract text based on the selection rectangle.");
							Console.WriteLine("----------------------------------------------------");

							Page first_page = doc.GetPage(1);
							string field1 = util.ReadTextFromRect(first_page, new Rect(27, 392, 563, 534), reader);
							string field2 = util.ReadTextFromRect(first_page, new Rect(28, 551, 106, 623), reader);
							string field3 = util.ReadTextFromRect(first_page, new Rect(208, 550, 387, 621), reader);

							Console.WriteLine("Field 1: {0}", field1);
							Console.WriteLine("Field 2: {0}", field2);
							Console.WriteLine("Field 3: {0}", field3);
							// ... 

							Console.WriteLine("Done.");
						}
					}
				}
				catch (PDFNetException e)
				{
					Console.WriteLine(e.Message);
				}	
			}
			PDFNet.Terminate();
		}

		static void PrintStyle(TextExtractor.Style s) {
			Color rgb = s.GetColor();
			String rgb_hex = String.Format("{0:X02}{1:X02}{2:X02};", rgb.R, rgb.G, rgb.B);
			Console.Write(" style=\"font-family:{0}; font-size:{1};{2} color:#{3}\"", s.GetFontName(), s.GetFontSize(), (s.IsSerif() ? " sans-serif;" : ""), rgb_hex); 
		}
	}

	class LowLevelTextExtractUtils
	{
		// A utility method used to dump all text content in the 
		// console window.
		public static void DumpAllText(ElementReader reader) 
		{
			Element element; 
			while ((element = reader.Next()) != null)
			{
				switch (element.GetType()) 
				{
					case Element.Type.e_text_begin:
						Console.WriteLine("\n--> Text Block Begin");
						break;
					case Element.Type.e_text_end:
						Console.WriteLine("\n--> Text Block End");
						break;
					case Element.Type.e_text:
					{
						Rect bbox = new Rect();
						element.GetBBox(bbox);
						// Console.WriteLine("\n--> BBox: {0}, {1}, {2}, {3}", bbox.x1, bbox.y1, bbox.x2, bbox.y2);

						String txt = element.GetTextString();
						Console.Write(txt);
						Console.WriteLine("");
						break;
					}
					case Element.Type.e_text_new_line:
					{
						// Console.WriteLine("\n--> New Line");
						break;
					}
					case Element.Type.e_form: // Process form XObjects
					{
						reader.FormBegin(); 
						DumpAllText(reader);
						reader.End(); 
						break; 
					}
				}
			}
		}


		private string _srch_str;

		// A helper method for ReadTextFromRect
		void RectTextSearch(ElementReader reader, Rect pos) 
		{			
			Element element; 
			while ((element = reader.Next()) != null)
			{
				switch (element.GetType()) 
				{
					case Element.Type.e_text:
					{
						Rect bbox = new Rect();
						element.GetBBox(bbox);
						if(bbox.IntersectRect(bbox, pos))
						{
							_srch_str += element.GetTextString();
							_srch_str += "\n"; // add a new line?
						}
						break;
					}
					case Element.Type.e_text_new_line:
					{
						break;
					}
					case Element.Type.e_form: // Process form XObjects
					{
						reader.FormBegin(); 
						RectTextSearch(reader, pos);
						reader.End(); 
						break; 
					}
				}
			}
		}

		// A utility method used to extract all text content from
		// a given selection rectangle. The rectangle coordinates are
		// expressed in PDF user/page coordinate system.
		public string ReadTextFromRect(Page page, Rect pos, ElementReader reader)
		{
			_srch_str = "";
			reader.Begin(page);
			RectTextSearch(reader, pos);
			reader.End();
			return _srch_str;
		}
	}
}
```

{% endcode %}
{% endtab %}

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

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

#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <PDF/ElementReader.h>
#include <PDF/Element.h>
#include <PDF/Font.h>
#include <Filters/FilterReader.h>
#include <PDF/Image/Image2RGB.h>
#include <PDF/TextExtractor.h>

// This sample illustrates the basic text extraction capabilities of PDFNet.

#include <iostream>
#include "../../LicenseKey/CPP/LicenseKey.h"

using namespace std;

using namespace pdftron;
using namespace PDF;
using namespace SDF;
using namespace Common;
using namespace Filters; 

// A utility method used to dump all text content in the console window.
void DumpAllText(ElementReader& reader) 
{
	Element element; 
	while ((element = reader.Next()) != 0)
	{
		switch (element.GetType()) 
		{
		case Element::e_text_begin: 
			cout << "\n--> Text Block Begin\n";
			break;
		case Element::e_text_end:
			cout << "\n--> Text Block End\n";
			break;
		case Element::e_text:
			{
				Rect bbox;
				element.GetBBox(bbox);
				cout << "\n--> BBox: " << bbox.x1 << ", " 
									   << bbox.y1 << ", " 
									   << bbox.x2 << ", " 
									   << bbox.y2 << "\n";

				UString arr = element.GetTextString();
				cout << arr << "\n";
			}
			break;
		case Element::e_text_new_line:
			cout << "\n--> New Line\n";
			break;
		case Element::e_form:				// Process form XObjects
			reader.FormBegin(); 
			DumpAllText(reader);
			reader.End(); 
			break; 
		}
	}
}

// A helper method for ReadTextFromRect
void RectTextSearch(ElementReader& reader, const Rect& pos, UString& srch_str) 
{			
	Element element; 
	while (element = reader.Next())
	{
		switch (element.GetType()) 
		{
		case Element::e_text:
			{
				Rect bbox;
				element.GetBBox(bbox);
				if(bbox.IntersectRect(bbox, pos)) 
				{
					UString arr = element.GetTextString();
					srch_str += arr;
					srch_str += "\n"; // add a new line?
				}
				break;
			}
		case Element::e_text_new_line:
			{
				break;
			}
		case Element::e_form: // Process form XObjects
			{
				reader.FormBegin(); 
				RectTextSearch(reader, pos, srch_str);
				reader.End(); 
				break; 
			}
		}
	}
}

// A utility method used to extract all text content from
// a given selection rectangle. The rectangle coordinates are
// expressed in PDF user/page coordinate system.
UString ReadTextFromRect(Page& page, const Rect& pos, ElementReader& reader)
{
	UString srch_str;
	reader.Begin(page);
	RectTextSearch(reader, pos, srch_str);
	reader.End();
	return srch_str;
}


void PrintStyle(TextExtractor::Style& s)
{
	UInt8 rgb[3];
	char rgb_hex[24];

	s.GetColor(rgb);
	sprintf(rgb_hex, "%02X%02X%02X;", rgb[0], rgb[1], rgb[2]);
	cout << " style=\"font-family:" << s.GetFontName() << "; "	<< "font-size:" << s.GetFontSize() << ";" 
		 << (s.IsSerif() ? " sans-serif; " : " ") << "color:#" << rgb_hex << "\"";
}

int main(int argc, char *argv[])
{
	int ret = 0;
	PDFNet::Initialize(LicenseKey);
	// Relative path to the folder containing test files.
	string input_path =  "../../TestFiles/newsletter.pdf";



	
	const char* filein = argc>1 ? argv[1] : input_path.c_str();

	bool example1_basic = false;
	bool example2_xml = false;
	bool example3_wordlist = false;
	bool example4_advanced  = true;
	bool example5_low_level = false;

	// Sample code showing how to use high-level text extraction APIs.
	try
	{
		PDFDoc doc(filein);
		doc.InitSecurityHandler();

		Page page = doc.GetPage(1);
		if (!page){
			cout << "Page not found." << endl;
			return 1;
		}

		TextExtractor txt;
		txt.Begin(page); // Read the page.
		// Other options you may want to consider...
		// txt.Begin(*itr, 0, TextExtractor::e_no_dup_remove);
		// txt.Begin(*itr, 0, TextExtractor::e_remove_hidden_text);


		// Example 1. Get all text on the page in a single string.
		// Words will be separated with space or new line characters.
		if (example1_basic) 
		{
			// Get the word count.
			cout << "Word Count: " << txt.GetWordCount() << endl;

			UString text;
			txt.GetAsText(text);
			cout << "\n\n- GetAsText --------------------------\n" << text << endl;
			cout << "-----------------------------------------------------------" << endl;
		}

		// Example 2. Get XML logical structure for the page.
		if (example2_xml) 
		{
			UString text;
			txt.GetAsXML(text, TextExtractor::e_words_as_elements | TextExtractor::e_output_bbox | TextExtractor::e_output_style_info);
			cout << "\n\n- GetAsXML  --------------------------\n" << text << endl;
			cout << "-----------------------------------------------------------" << endl;
		}

		// Example 3. Extract words one by one.
		if (example3_wordlist) 
		{
			UString text;
			TextExtractor::Line line = txt.GetFirstLine();
			TextExtractor::Word word;
			for (; line.IsValid(); line=line.GetNextLine())	{
				for (word=line.GetFirstWord(); word.IsValid(); word=word.GetNextWord()) {
					text.Assign(word.GetString(), word.GetStringLen());
					cout << text << '\n';
				}
			}
			cout << "-----------------------------------------------------------" << endl;
		}

		// Example 4. A more advanced text extraction example. 
		// The output is XML structure containing paragraphs, lines, words, 
		// as well as style and positioning information.
		if (example4_advanced) 
		{
			const double *b;
			double q[8];
			int cur_flow_id=-1, cur_para_id=-1;

			UString uni_str;
			TextExtractor::Line line;
			TextExtractor::Word word;
			TextExtractor::Style s, line_style;

			cout << "<PDFText>\n";

			// For each line on the page...
			for (line=txt.GetFirstLine(); line.IsValid(); line=line.GetNextLine())
			{
				if ( line.GetNumWords() == 0 ) {
					continue;
				}

				if (cur_flow_id != line.GetFlowID()) {
					if (cur_flow_id != -1) {
						if (cur_para_id != -1) {
							cur_para_id = -1;
							cout << "</Para>\n";
						}
						cout << "</Flow>\n";
					}
					cur_flow_id = line.GetFlowID();
					cout << "<Flow id=\""<< cur_flow_id << "\">\n";
				}

				if (cur_para_id != line.GetParagraphID()) {
					if (cur_para_id != -1)
						cout << "</Para>\n";
					cur_para_id = line.GetParagraphID();
					cout << "<Para id=\""<< cur_para_id << "\">\n";
				}	
				
				b = line.GetBBox();
				line_style = line.GetStyle();
				printf("<Line box=\"%.2f, %.2f, %.2f, %.2f\"", b[0], b[1], b[2], b[3]);
				PrintStyle(line_style);
				cout << " cur_num=\"" << line.GetCurrentNum() << "\"";
				cout << ">\n";

				// For each word in the line...
				for (word=line.GetFirstWord(); word.IsValid(); word=word.GetNextWord())
				{
					// Output the bounding box for the word.
					word.GetBBox(q);
					printf("<Word box=\"%.2f, %.2f, %.2f, %.2f\"", q[0], q[1], q[2], q[3]);
					cout << " cur_num=\"" << word.GetCurrentNum() << "\"";
					int sz = word.GetStringLen();
					if (sz == 0) continue;

					// If the word style is different from the parent style, output the new style.
					s = word.GetStyle();
					if (s != line_style) {
						PrintStyle(s);
					}

					uni_str.Assign(word.GetString(), sz);
					cout << ">" << uni_str;
					cout << "</Word>\n";
				}
				cout << "</Line>\n";
			}

			if (cur_flow_id != -1) {
				if (cur_para_id != -1) {
					cur_para_id = -1;
					cout << "</Para>\n";
				}
				cout << "</Flow>\n";
			}
			cout << "</PDFText>\n";
		}
	}
	catch(Exception& e)
	{
		cout << e << endl;
		ret = 1;
	}
	catch(...)
	{
		cout << "Unknown Exception" << endl;
		ret = 1;
	}


	if(example5_low_level)
	{
		try	
		{
			PDFDoc doc(filein);
			doc.InitSecurityHandler();

			// Example 1. Extract all text content from the document

			ElementReader reader;
			//  Read every page
			for (PageIterator itr=doc.GetPageIterator(); itr.HasNext(); itr.Next()) 
			{				
				reader.Begin(itr.Current());
				DumpAllText(reader);
				reader.End();
			}

			// Example 2. Extract text content based on the 
			// selection rectangle.
			cout << "\n----------------------------------------------------";
			cout << "\nExtract text based on the selection rectangle.";
			cout << "\n----------------------------------------------------\n";

			Page first_page = doc.GetPageIterator().Current();
			UString s1 = ReadTextFromRect(first_page, Rect(27, 392, 563, 534), reader);
			cout << "\nField 1: " << s1;

			s1 = ReadTextFromRect(first_page, Rect(28, 551, 106, 623), reader);
			cout << "\nField 2: " << s1;

			s1 = ReadTextFromRect(first_page, Rect(208, 550, 387, 621), reader);
			cout << "\nField 3: " << s1;

			// ... 
			cout << "Done." << endl;
		}
		catch(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-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------

package main
import (
	"fmt"
	"strconv"
	"os"
	. "pdftron"
)

import  "pdftron/Samples/LicenseKey/GO"

func PrintStyle (style Style){
    sansSerifStr := ""
    if style.IsSerif(){
        sansSerifStr = " sans-serif;"
	}
    rgb := style.GetColor()
    rgbHex := fmt.Sprintf("%02X%02X%02X;", rgb.Get(0), rgb.Get(1), rgb.Get(2))
    fontStr := fmt.Sprintf("%g", style.GetFontSize())
    os.Stdout.Write([]byte(" style=\"font-family:" + style.GetFontName() + "; font-size:" + fontStr + ";" + sansSerifStr + " color:#" + rgbHex + "\""))
}

func DumpAllText (reader ElementReader){
    element := reader.Next()

    for element.GetMp_elem().Swigcptr() != 0{
        etype := element.GetType()
        if etype == ElementE_text_begin{
            fmt.Println("Text Block Begin")
        }else if etype == ElementE_text_end{
            fmt.Println("Text Block End")
        }else if etype == ElementE_text{
            bbox := element.GetBBox()
            fmt.Println("BBox: " + fmt.Sprintf("%f", bbox.GetX1()) + ", " + fmt.Sprintf("%f", bbox.GetY1()) + ", " +
						fmt.Sprintf("%f", bbox.GetX2()) + ", " + fmt.Sprintf("%f", bbox.GetY2()))
            textString := element.GetTextString()
            fmt.Println(textString)
        }else if etype == ElementE_text_new_line{
            fmt.Println("New Line")
        }else if etype == ElementE_form{
            reader.FormBegin()
            DumpAllText(reader)
            reader.End()
		}
        element = reader.Next()
	}
}

// A utility method used to extract all text content from
// a given selection rectangle. The recnagle coordinates are
// expressed in PDF user/page coordinate system.
func ReadTextFromRect (page Page, pos Rect, reader ElementReader) string{
    reader.Begin(page)
    srchStr := RectTextSearch(reader, pos)
    reader.End()
    return srchStr
}
//A helper method for ReadTextFromRect
func RectTextSearch (reader ElementReader, pos Rect) string{
    element := reader.Next()
    srchStr2 := ""
    for element.GetMp_elem().Swigcptr() != 0{
        etype := element.GetType()
        if etype == ElementE_text{
            bbox := element.GetBBox()
            if (bbox.IntersectRect(bbox, pos)){
                arr := element.GetTextString()
                srchStr2 += arr
                srchStr2 += "\n"
			}
        }else if etype == ElementE_text_new_line{
            //handle text new line here
        }else if etype == ElementE_form{
            reader.FormBegin()
            srchStr2 += RectTextSearch(reader, pos)
            fmt.Println(srchStr2)
            reader.End()
		}
        element = reader.Next()
	}
    return srchStr2
}

func main(){
    PDFNetInitialize(PDFTronLicense.Key)
    
    // Relative path to the folder containing test files.
    inputPath :=  "../../TestFiles/newsletter.pdf"
    example1Basic := false
    example2Xml := false
    example3Wordlist := false
    example4Advanced := true
    example5LowLevel := false
   
    // Sample code showing how to use high-level text extraction APIs.
    doc := NewPDFDoc(inputPath)
    doc.InitSecurityHandler()
    
    page := doc.GetPage(1)
    if page == nil{
        fmt.Println("page no found")
    }    
    txt := NewTextExtractor()
    txt.Begin(page) // Read the page
    
    // Example 1. Get all text on the page in a single string.
    // Words will be separated witht space or new line characters.
    if example1Basic{
        fmt.Println("Word count: " + strconv.Itoa(txt.GetWordCount()))
        txtAsText := txt.GetAsText()
        fmt.Println("- GetAsText --------------------------" + txtAsText)
        fmt.Println("-----------------------------------------------------------")
	}
    // Example 2. Get XML logical structure for the page.
    if example2Xml{
        text := txt.GetAsXML(TextExtractorE_words_as_elements | 
                            TextExtractorE_output_bbox | 
                            TextExtractorE_output_style_info)       
        fmt.Println("- GetAsXML  --------------------------" + text)
        fmt.Println("-----------------------------------------------------------")
    }
    // Example 3. Extract words one by one.
    if example3Wordlist{
        word := NewWord()
        line := txt.GetFirstLine()
        for line.IsValid(){
            word = line.GetFirstWord()
            for word.IsValid(){
                wordString := word.GetString()
                fmt.Println(wordString)
                word = word.GetNextWord()
			}
            line = line.GetNextLine()
		}
        fmt.Println("-----------------------------------------------------------")
	}
    // Example 4. A more advanced text extraction example. 
    // The output is XML structure containing paragraphs, lines, words, 
    // as well as style and positioning information.
    if example4Advanced{
        bbox := NewRect()
        curFlowId := -1
        curParaId := -1
        
        fmt.Println("<PDFText>")
        // For each line on the page...
        line := txt.GetFirstLine()
        for line.IsValid(){
            if line.GetNumWords() == 0{
                line = line.GetNextLine()			
                continue
			}
            word := line.GetFirstWord()
            if curFlowId != line.GetFlowID(){
                if curFlowId != -1{
                    if curParaId != -1{
                        curParaId = -1
                        fmt.Println("</Para>")
					}
                    fmt.Println("</Flow>")
				}
                curFlowId = line.GetFlowID()
                fmt.Println("<Flow id=\"" + strconv.Itoa(curFlowId) +"\">")
            }        
            if curParaId != line.GetParagraphID(){
                if curParaId != -1{
                    fmt.Println("</Para>")
				}
                curParaId= line.GetParagraphID()
                fmt.Println("<Para id=\"" +strconv.Itoa(curParaId)+ "\">")
            }    
            bbox = line.GetBBox()
            lineStyle := line.GetStyle()
            os.Stdout.Write([]byte(fmt.Sprintf("<Line box=\"%.2f, %.2f, %.2f, %.2f\"", bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2())))
            PrintStyle (lineStyle)
            os.Stdout.Write([]byte(" cur_num=\"" + strconv.Itoa(line.GetCurrentNum()) + "\"" + ">\n"))
            
            // For each word in the line...
            word = line.GetFirstWord()
            for word.IsValid(){
                // Output the bounding box for the word
                bbox = word.GetBBox()
				os.Stdout.Write([]byte(fmt.Sprintf("<Word box=\"%.2f, %.2f, %.2f, %.2f\"", bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2())))
                os.Stdout.Write([]byte(" cur_num=\"" + strconv.Itoa(word.GetCurrentNum()) + "\""));
                sz := word.GetStringLen()
                if sz == 0{
                    word = word.GetNextWord()				
                    continue
				}
                // If the word style is different from the parent style, output the new style.
                s := word.GetStyle()
                if !s.IsEqual(lineStyle){
                    PrintStyle (s)
				}
                wordString := word.GetString()
                os.Stdout.Write([]byte(">" + wordString + "</Word>\n"))
                word = word.GetNextWord()
			}
            os.Stdout.Write([]byte("</Line>\n"))               
            line = line.GetNextLine()
        }    
        if curFlowId != -1{
            if curParaId != -1{
                curParaId = -1
                os.Stdout.Write([]byte("</Para>\n"))
			}
            os.Stdout.Write([]byte("</Flow>\n"))
        }
        txt.Destroy()
        doc.Close()            
        fmt.Println("</PDFText>")
    }
    // Sample code showing how to use low-level text extraction APIs.
    if example5LowLevel{
        doc = NewPDFDoc(inputPath)
        doc.InitSecurityHandler()

        // Example 1. Extract all text content from the document
        
        reader := NewElementReader()
        itr := doc.GetPageIterator()
        for itr.HasNext(){
            reader.Begin(itr.Current())
            DumpAllText(reader)
            reader.End()
            itr.Next()
        }
		
        // Example 2. Extract text content based on the 
        // selection rectangle.
        
        fmt.Println("----------------------------------------------------")
        fmt.Println("Extract text based on the selection rectangle.")
        fmt.Println("----------------------------------------------------")
        
        itr = doc.GetPageIterator()
        firstPage := itr.Current()
        s1 := ReadTextFromRect(firstPage, NewRect(27.0, 392.0, 563.0, 534.0), reader)
        fmt.Println("Field 1: " + s1)

        s1 = ReadTextFromRect(firstPage, NewRect(28.0, 551.0, 106.0, 623.0), reader);
        fmt.Println("Field 2: " + s1)

        s1 = ReadTextFromRect(firstPage, NewRect(208.0, 550.0, 387.0, 621.0), reader);
        fmt.Println("Field 3: " + s1)
        
        doc.Close()
        PDFNetTerminate()
        fmt.Println("Done.")
	}
}
```

{% endcode %}
{% endtab %}

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

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

import java.awt.Color;
import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.*;
import java.text.DecimalFormat; 


// This sample illustrates the basic text extraction capabilities of PDFNet.
public class TextExtractTest {

    public static void main(String[] args) {
        PDFNet.initialize(PDFTronLicense.Key());

        // Relative path to the folder containing test files.
        String input_path = "../../TestFiles/";
        // string output_path = "../../TestFiles/Output/";
        boolean example1_basic = false;
        boolean example2_xml = false;
        boolean example3_wordlist = false;
        boolean example4_advanced = true;
        boolean example5_low_level = false;

        // Sample code showing how to use high-level text extraction APIs.
        try (PDFDoc doc = new PDFDoc(input_path + "newsletter.pdf")) {
            doc.initSecurityHandler();

            Page page = doc.getPage(1);
            if (page == null) {
                System.out.println("Page not found.");
            }

            TextExtractor txt = new TextExtractor();
            txt.begin(page);  // Read the page.
            // Other options you may want to consider...
            // txt.Begin(page, 0, TextExtractor.ProcessingFlags.e_no_dup_remove);
            // txt.Begin(page, 0, TextExtractor.ProcessingFlags.e_remove_hidden_text);
            // ...

            // Example 1. Get all text on the page in a single string.
            // Words will be separated with space or new line characters.
            if (example1_basic) {
                // Get the word count.
                System.out.println("Word Count: " + txt.getWordCount());

                System.out.println("\n\n- GetAsText --------------------------\n" + txt.getAsText());
                System.out.println("-----------------------------------------------------------");
            }

            // Example 2. Get XML logical structure for the page.
            if (example2_xml) {
                String text = txt.getAsXML(TextExtractor.e_words_as_elements | TextExtractor.e_output_bbox | TextExtractor.e_output_style_info);
                System.out.println("\n\n- GetAsXML  --------------------------\n" + text);
                System.out.println("-----------------------------------------------------------");
            }

            // Example 3. Extract words one by one.
            if (example3_wordlist) {
                TextExtractor.Word word;
                for (TextExtractor.Line line = txt.getFirstLine(); line.isValid(); line = line.getNextLine()) {
                    for (word = line.getFirstWord(); word.isValid(); word = word.getNextWord()) {
                        System.out.println(word.getString());
                    }
                }
                System.out.println("-----------------------------------------------------------");
            }

            // Example 4. A more advanced text extraction example.
            // The output is XML structure containing paragraphs, lines, words,
            // as well as style and positioning information.
            if (example4_advanced) {
                Rect bbox;
                int cur_flow_id = -1, cur_para_id = -1;

                TextExtractor.Line line;
                TextExtractor.Word word;
                TextExtractor.Style s, line_style;

                System.out.println("<PDFText>");
                // For each line on the page...
                for (line = txt.getFirstLine(); line.isValid(); line = line.getNextLine()) {
                    if (line.getNumWords() == 0)
                        continue;
                    if (cur_flow_id != line.getFlowID()) {
                        if (cur_flow_id != -1) {
                            if (cur_para_id != -1) {
                                cur_para_id = -1;
                                System.out.println("</Para>");
                            }
                            System.out.println("</Flow>");
                        }
                        cur_flow_id = line.getFlowID();
                        System.out.println("<Flow id=\"" + cur_flow_id + "\">");
                    }

                    if (cur_para_id != line.getParagraphID()) {
                        if (cur_para_id != -1)
                            System.out.println("</Para>");
                        cur_para_id = line.getParagraphID();
                        System.out.println("<Para id=\"" + cur_para_id + "\">");
                    }

                    bbox = line.getBBox();
                    line_style = line.getStyle();
                    System.out.print("<Line box=\"" +  String.format("%.2f, %.2f, %.2f, %.2f", bbox.getX1(), bbox.getY1(), bbox.getX2(), bbox.getY2()) + "\"");
                    printStyle(line_style);
                    System.out.println(" cur_num=\"" + line.getCurrentNum() + "\">");
                 

                    // For each word in the line...
                    for (word = line.getFirstWord(); word.isValid(); word = word.getNextWord()) {
                        // Output the bounding box for the word.
                        bbox = word.getBBox();
                        System.out.print("<Word box=\"" +  String.format("%.2f, %.2f, %.2f, %.2f", bbox.getX1(), bbox.getY1(), bbox.getX2(), bbox.getY2()) + "\"");
                        System.out.print(" cur_num=\"" + word.getCurrentNum() + "\"");
                        int sz = word.getStringLen();
                        if (sz == 0) continue;

                        // If the word style is different from the parent style, output the new style.
                        s = word.getStyle();
                        if (!s.equals(line_style)) {
                            printStyle(s);
                        }

                        System.out.print(">" + word.getString());
                        System.out.println("</Word>");
                    }
                    System.out.println("</Line>");
                }

                if (cur_flow_id != -1) {
                    if (cur_para_id != -1) {
                        cur_para_id = -1;
                        System.out.println("</Para>");
                    }
                    System.out.println("</Flow>");
                }
            }
            txt.destroy();
            System.out.println("</PDFText>");
        } catch (PDFNetException e) {
            System.out.println(e);
        }

        // Sample code showing how to use low-level text extraction APIs.
        if (example5_low_level) {
            try (PDFDoc doc = new PDFDoc((input_path + "newsletter.pdf"))) {
                doc.initSecurityHandler();

                // Example 1. Extract all text content from the document

                ElementReader reader = new ElementReader();
                //  Read every page
                for (PageIterator itr = doc.getPageIterator(); itr.hasNext(); ) {
                    reader.begin(itr.next());
                    DumpAllText(reader);
                    reader.end();
                }

                // Example 2. Extract text content based on the
                // selection rectangle.
                System.out.print("\n----------------------------------------------------");
                System.out.print("\nExtract text based on the selection rectangle.");
                System.out.println("\n----------------------------------------------------");

                Page first_page = doc.getPageIterator().next();
                String s1 = ReadTextFromRect(first_page, new Rect(27, 392, 563, 534), reader);
                System.out.print("\nField 1: " + s1);

                s1 = ReadTextFromRect(first_page, new Rect(28, 551, 106, 623), reader);
                System.out.print("\nField 2: " + s1);

                s1 = ReadTextFromRect(first_page, new Rect(208, 550, 387, 621), reader);
                System.out.print("\nField 3: " + s1);

                // ...
                System.out.println("Done.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        PDFNet.terminate();
    }


    static void printStyle(TextExtractor.Style s) {
        Color rgb = s.getColor();
        String rgb_hex =  String.format("%02X%02X%02X;", rgb.getRed(), rgb.getGreen(), rgb.getBlue() );
        DecimalFormat df = new DecimalFormat("#.#");
        System.out.print(" style=\"font-family:" + s.getFontName() + "; "
                + "font-size:" + df.format(s.getFontSize()) + ";"
                + (s.isSerif() ? " sans-serif; " : " ")
                + "color:#" + rgb_hex + "\"");
    }

    // A utility method used to dump all text content in the console window.
    static void DumpAllText(ElementReader reader) throws PDFNetException {
        Element element;
        while ((element = reader.next()) != null) {
            switch (element.getType()) {
                case Element.e_text_begin:
                    System.out.println("\n--> Text Block Begin");
                    break;
                case Element.e_text_end:
                    System.out.println("\n--> Text Block End");
                    break;
                case Element.e_text: {
                    Rect bbox = element.getBBox();
                    if (bbox == null) continue;
                    System.out.println("\n--> BBox: " + bbox.getX1() + ", "
                            + bbox.getY1() + ", "
                            + bbox.getX2() + ", "
                            + bbox.getY2());

                    String arr = element.getTextString();
                    System.out.println(arr);
                }
                break;
                case Element.e_text_new_line:
                    System.out.println("\n--> New Line");
                    break;
                case Element.e_form:                // Process form XObjects
                    reader.formBegin();
                    DumpAllText(reader);
                    reader.end();
                    break;
            }
        }
    }

    // A helper method for ReadTextFromRect
    static String RectTextSearch(ElementReader reader, Rect pos) throws PDFNetException {
        Element element;
        String srch_str = new String();
        while ((element = reader.next()) != null) {
            switch (element.getType()) {
                case Element.e_text: {
                    Rect bbox = element.getBBox();
                    if (bbox == null) continue;
                    if (bbox.intersectRect(bbox, pos)) {
                        String arr = element.getTextString();
                        srch_str += arr;
                        srch_str += "\n"; // add a new line?
                    }
                    break;
                }
                case Element.e_text_new_line: {
                    break;
                }
                case Element.e_form: // Process form XObjects
                {
                    reader.formBegin();
                    srch_str += RectTextSearch(reader, pos);
                    reader.end();
                    break;
                }
            }
        }
        return srch_str;
    }

    // A utility method used to extract all text content from
    // a given selection rectangle. The rectangle coordinates are
    // expressed in PDF user/page coordinate system.
    static String ReadTextFromRect(Page page, Rect pos, ElementReader reader) throws PDFNetException {
        reader.begin(page);
        String srch_str = RectTextSearch(reader, pos);
        reader.end();
        return srch_str;
    }
}
```

{% endcode %}
{% endtab %}

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

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


const { PDFNet } = require('@pdftron/pdfnet-node');
const PDFTronLicense = require('../LicenseKey/LicenseKey');

((exports) => {

  exports.runTextExtractTest = async () => {
    // A utility method used to dump all text content in the console window.
    const dumpAllText = async (reader) => {
      let element;
      let bbox;
      let arr;
      while ((element = await reader.next()) !== null) {
        switch (await element.getType()) {
          case PDFNet.Element.Type.e_text_begin:
            console.log('\n--> Text Block Begin');
            break;
          case PDFNet.Element.Type.e_text_end:
            console.log('\n--> Text Block End');
            break;
          case PDFNet.Element.Type.e_text:
            bbox = await element.getBBox();
            console.log('\n--> BBox: ' + bbox.x1.toFixed(2) + ', ' + bbox.y1.toFixed(2) + ', ' + bbox.x2.toFixed(2) + ', ' + bbox.y2.toFixed(2) + '\n');
            arr = await element.getTextString();
            console.log(arr);
            break;
          case PDFNet.Element.Type.e_text_new_line:
            console.log('\n--> New Line');
            break;
          case PDFNet.Element.Type.e_form:
            reader.formBegin();
            await dumpAllText(reader);
            reader.end();
            break;
        }
      }
    };

    // helper method for ReadTextFromRect
    const rectTextSearch = async (reader, pos, srchStr) => {
      let element;
      let arr;
      while ((element = await reader.next()) !== null) {
        let bbox;
        switch (await element.getType()) {
          case PDFNet.Element.Type.e_text:
            bbox = await element.getBBox();
            if (await bbox.intersectRect(bbox, pos)) {
              arr = await element.getTextString();
              srchStr += arr + '\n';
            }
            break;
          case PDFNet.Element.Type.e_text_new_line:
            break;
          case PDFNet.Element.Type.e_form:
            reader.formBegin();
            srchStr += await rectTextSearch(reader, pos, srchStr); // possibly need srchStr = ...
            reader.end();
            break;
        }
      }
      return srchStr;
    };

    const readTextFromRect = async (page, pos, reader) => {
      let srchStr = '';
      reader.beginOnPage(page); // uses default parameters.
      srchStr += await rectTextSearch(reader, pos, srchStr);
      reader.end();
      return srchStr;
    };

    const twoDigitHex = function (num) {
      const hexStr = num.toString(16).toUpperCase();
      return ('0' + hexStr).substr(-2);
    }

    const printStyle = async (s) => {
      const rgb = await s.getColor();
      const rColorVal = await rgb.get(0);
      const gColorVal = await rgb.get(1);
      const bColorVal = await rgb.get(2);
      const rgbHex = twoDigitHex(rColorVal) + twoDigitHex(gColorVal) + twoDigitHex(bColorVal)
      const fontName = await s.getFontName();
      const fontSize = await s.getFontSize();
      const serifOutput = ((await s.isSerif()) ? ' sans-serif; ' : ' ');
      const returnString = ' style="font-family:' + fontName + '; font-size:' + fontSize + ';' + serifOutput + 'color:#' + rgbHex + ';"';
      return returnString;
    };

    const main = async () => {
      // eslint-disable-next-line no-unused-vars
      let ret = 0;

      // Relative path to the folder containing test files.
      const inputPath = '../TestFiles/';
      const inputFilename = 'newsletter.pdf'; // addimage.pdf, newsletter.pdf

      const example1Basic = false;
      const example2XML = false;
      const example3Wordlist = false;
      const example4Advanced = true;
      const example5LowLevel = false;

      try {
        await PDFNet.startDeallocateStack();
        const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + inputFilename);
        doc.initSecurityHandler();

        const page = await doc.getPage(1);

        if (page.id === '0') {
          console.log('Page not found.');
          return 1;
        }

        const txt = await PDFNet.TextExtractor.create();
        txt.begin(page);

        let text;
        let line;
        let word;

        // Example 1. Get all text on the page in a single string.
        // Words will be separated with space or new line characters.
        if (example1Basic) {
          const wordCount = await txt.getWordCount();
          console.log('Word Count: ' + wordCount);
          text = await txt.getAsText();
          console.log('\n\n- GetAsText --------------------------');
          console.log(text);
          console.log('-----------------------------------------------------------');
        }

        // Example 2. Get XML logical structure for the page.
        if (example2XML) {
          text = await txt.getAsXML(PDFNet.TextExtractor.XMLOutputFlags.e_words_as_elements | PDFNet.TextExtractor.XMLOutputFlags.e_output_bbox | PDFNet.TextExtractor.XMLOutputFlags.e_output_style_info);
          console.log('\n\n- GetAsXML  --------------------------\n' + text);
          console.log('-----------------------------------------------------------');
        }

        // Example 3. Extract words one by one.
        if (example3Wordlist) {
          line = await txt.getFirstLine();
          for (; (await line.isValid()); line = (await line.getNextLine())) {
            for (word = await line.getFirstWord(); await word.isValid(); word = await word.getNextWord()) {
              text = await word.getString();
              console.log(text);
            }
          }
          console.log('-----------------------------------------------------------');
        }

        // Example 4. A more advanced text extraction example. 
        // The output is XML structure containing paragraphs, lines, words, 
        // as well as style and positioning information.
        if (example4Advanced) {
          let b;
          let q;
          let curFlowID = -1;
          let curParaID = -1;

          console.log('<PDFText>');

          // For each line on the page...
          for (line = await txt.getFirstLine(); await line.isValid(); line = await line.getNextLine()) {
            if ((await line.getNumWords()) === 0) {
              continue;
            }
            if (curFlowID !== await line.getFlowID()) {
              if (curFlowID !== -1) {
                if (curParaID !== -1) {
                  curParaID = -1;
                  console.log('</Para>');
                }
                console.log('</Flow>');
              }
              curFlowID = await line.getFlowID();
              console.log('<Flow id="' + curFlowID + '">');
            }
            if (curParaID !== await line.getParagraphID()) {
              if (curParaID !== -1) {
                console.log('</Para>');
              }
              curParaID = await line.getParagraphID();
              console.log('<Para id="' + curParaID + '">');
            }
            b = await line.getBBox();
            const lineStyle = await line.getStyle();
            let outputStringLineBox = '<Line box="' + b.x1.toFixed(2) + ', ' + b.y1.toFixed(2) + ', ' + b.x2.toFixed(2) + ', ' + b.y2.toFixed(2) + '"';
            outputStringLineBox += (await printStyle(lineStyle));
            const currentLineNum = await line.getCurrentNum();
            outputStringLineBox += ' cur_num="' + currentLineNum + '">';
            console.log(outputStringLineBox);

            // For each word in the line...
            for (word = await line.getFirstWord(); await word.isValid(); word = await word.getNextWord()) {
              // output bounding box for the word
              q = await word.getBBox();
              const currentNum = await word.getCurrentNum();
              let outputStringWord = '<Word box="' + q.x1.toFixed(2) + ', ' + q.y1.toFixed(2) + ', ' + q.x2.toFixed(2) + ', ' + q.y2.toFixed(2) + '" cur_num="' + currentNum + '"';
              const sz = await word.getStringLen();
              if (sz === 0) {
                continue;
              }
              // if the word style is different from the parent style, output the new style
              const sty = await word.getStyle();
              if (!(await sty.compare(lineStyle))) {
                outputStringWord += await printStyle(sty);
              }
              outputStringWord += '>' + (await word.getString()) + '</Word>';
              console.log(outputStringWord);
            }
            console.log('</Line>');
          }
          if (curFlowID !== -1) {
            if (curParaID !== -1) {
              curParaID = -1;
              console.log('</Para>');
            }
            console.log('</Flow>');
          }
          console.log('</PDFText>');
        }
        await PDFNet.endDeallocateStack();
      } catch (err) {
        console.log(err);
        console.log(err.stack);
        ret = 1;
      }


      if (example5LowLevel) {
        ret = 0;
        try {
          await PDFNet.startDeallocateStack();
          const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + inputFilename);
          doc.initSecurityHandler();

          // Example 1. Extract all text content from the document
          const reader = await PDFNet.ElementReader.create();
          const itr = await doc.getPageIterator(1);

          //  Read every page
          for (itr; await itr.hasNext(); itr.next()) {
            const page = await itr.current();
            reader.beginOnPage(page);
            await dumpAllText(reader);
            reader.end();
          }
          // Example 2. Extract text content based on the
          // selection rectangle.
          console.log('\n----------------------------------------------------');
          console.log('Extract text based on the selection rectangle.');
          console.log('----------------------------------------------------');


          const firstPage = await (await doc.getPageIterator()).current();
          let s1 = await readTextFromRect(firstPage, (await PDFNet.Rect.init(27, 392, 563, 534)), reader);
          console.log('\nField 1: ' + s1);

          s1 = await readTextFromRect(firstPage, (await PDFNet.Rect.init(28, 551, 106, 623)), reader);
          console.log('Field 2: ' + s1);

          s1 = await readTextFromRect(firstPage, (await PDFNet.Rect.init(208, 550, 387, 621)), reader);
          console.log('Field 3: ' + s1);

          // ...
          console.log('Done');
          await PDFNet.endDeallocateStack();
        } catch (err) {
          console.log(err.stack);
          ret = 1;
        }
      }
    };
    PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function (error) { console.log('Error: ' + JSON.stringify(error)); }).then(function () { return PDFNet.shutdown(); });
  };
  exports.runTextExtractTest();
})(exports);
// eslint-disable-next-line spaced-comment
//# sourceURL=TextExtractTest.js
```

{% endcode %}
{% endtab %}

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

```php
<?php
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2023 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");

// Relative path to the folder containing the test files.
$input_path = getcwd()."/../../TestFiles/newsletter.pdf";

//---------------------------------------------------------------------------------------
// This sample illustrates the basic text extraction capabilities of PDFNet.
//---------------------------------------------------------------------------------------

// A utility method used to dump all text content in the browser.
function DumpAllText($reader) 
{
	while (($element = $reader->Next()) != NULL)
	{
		switch ($element->GetType()) 
		{
		case Element::e_text_begin: 
			echo nl2br("\n--> Text Block Begin\n");
			break;
		case Element::e_text_end:
			echo nl2br("\n--> Text Block End\n");
			break;
		case Element::e_text:
			{
				$bbox = $element->GetBBox();
				echo nl2br("\n--> BBox: ".$bbox->x1.", "
							.$bbox->y1.", " 
							.$bbox->x2.", " 
							.$bbox->y2."\n");

				$arr = $element->GetTextString();
				echo nl2br($arr."\n");
			}
			break;
		case Element::e_text_new_line:
			echo nl2br("\n--> New Line\n");
			break;
		case Element::e_form:				// Process form XObjects
			$reader->FormBegin(); 
            		DumpAllText(reader);
			$reader->End(); 
			break; 
		}
	}
}

// A helper method for ReadTextFromRect
function RectTextSearch($reader, $pos) 
{		
	$srch_str = "";	
	while (($element = $reader->Next()) != null)
	{
		switch ($element->GetType()) 
		{
		case Element::e_text:
			{
				$bbox = $element->GetBBox();
				if($bbox->IntersectRect($bbox, $pos)) 
				{
					$arr = $element->GetTextString();
					$srch_str .= $arr;
					$srch_str .= nl2br("\n");
				}
				break;
			}
		case Element::e_text_new_line:
			{
				break;
			}
		case Element::e_form: // Process form XObjects
			{
				$reader->FormBegin(); 
				$srch_str .= RectTextSearch($reader, $pos);
				$reader->End(); 
				break; 
			}
		}
	}
	return $srch_str;
}

// A utility method used to extract all text content from
// a given selection rectangle. The rectangle coordinates are
// expressed in PDF user/page coordinate system.
function ReadTextFromRect($page, $pos, $reader)
{
	$reader->Begin($page);
	$str = RectTextSearch($reader, $pos);
	$reader->End();
	return $str;
}

function PrintStyle($style)
{
	$text_color = $style->GetColor();
	$tmp = sprintf("%02X%02X%02X;", $text_color[0], $text_color[1], $text_color[2]);
	echo " style=\"font-family:".$style->GetFontName()."; "
		."font-size:".$style->GetFontSize().";" 
		.($style->IsSerif() ? " sans-serif; " : " ")
		."color:#".$tmp."\"";
}

function IsStyleEqual($style1, $style2)
{
	if($style1->GetFontName() == $style2->GetFontName() && 
		$style1->GetFontSize() == $style1->GetFontSize() && 
		!($style1->IsSerif() xor $style1->IsSerif()) &&
		$style1->GetColor() == $style2->GetColor() ) {
		return true;
	}
	return false; 
}
//---------------------------------------------------------------------------------------

	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.

	$example1_basic     = false;
	$example2_xml       = false;
	$example3_wordlist  = false;
	$example4_advanced  = true;
	$example5_low_level = false;

	// Sample code showing how to use high-level text extraction APIs.
	
	$doc = new PDFDoc($input_path);
	$doc->InitSecurityHandler();

	$page = $doc->GetPage(1);
	if (!$page){
		echo nl2br("Page not found.\n");
		return;
	}

	$txt = new TextExtractor();
	$txt->Begin($page); // Read the page.
	// Other options you may want to consider...
	// txt.Begin(*itr, 0, TextExtractor::e_no_dup_remove);
	// txt.Begin(*itr, 0, TextExtractor::e_remove_hidden_text);

	// Example 1. Get all text on the page in a single string.
	// Words will be separated with space or new line characters.
	if ($example1_basic) 
	{
		// Get the word count.
		echo "Word Count: ".$txt->GetWordCount()."\n";

		$text = $txt->GetAsText();
		echo nl2br("\n\n- GetAsText --------------------------\n".$text."\n");
		echo nl2br("-----------------------------------------------------------\n");
	}

	// Example 2. Get XML logical structure for the page.
	if ($example2_xml) 
	{
		$text = $txt->GetAsXML(TextExtractor::e_words_as_elements | TextExtractor::e_output_bbox | TextExtractor::e_output_style_info);
		echo nl2br("\n\n- GetAsXML  --------------------------\n".$text."\n");
		echo nl2br("-----------------------------------------------------------\n");
	}

	// Example 3. Extract words one by one.
	if ($example3_wordlist) 
	{
		for ($line = $txt->GetFirstLine(); $line->IsValid(); $line=$line->GetNextLine())	{
			for ($word=$line->GetFirstWord(); $word->IsValid(); $word=$word->GetNextWord()) {
				echo nl2br($word->GetString()."\n");
			}
		}
		echo nl2br("-----------------------------------------------------------\n");
	}

	// Example 4. A more advanced text extraction example. 
	// The output is XML structure containing paragraphs, lines, words, 
	// as well as style and positioning information.
	if ($example4_advanced) 
	{
		$cur_flow_id=-1;
		$cur_para_id=-1;

		echo nl2br("<PDFText>\n");
		// For each line on the page...
		for ($line=$txt->GetFirstLine(); $line->IsValid(); $line=$line->GetNextLine())
		{
			if ($line->GetNumWords() == 0) continue;
			
			if ($cur_flow_id != $line->GetFlowID()) {
				if ($cur_flow_id != -1) {
					if ($cur_para_id != -1) {
						$cur_para_id = -1;
						echo nl2br("</Para>\n");
					}
					echo nl2br("</Flow>\n");
				}
				$cur_flow_id = $line->GetFlowID();
				echo nl2br("<Flow id=\"".$cur_flow_id."\">\n");
			}

			if ($cur_para_id != $line->GetParagraphID()) {
				if ($cur_para_id != -1)
					echo nl2br("</Para>\n");
				$cur_para_id = $line->GetParagraphID();
				echo nl2br("<Para id=\"".$cur_para_id."\">\n");
			}	

			$bbox1 = $line->GetBBox();
			$line_style = $line->GetStyle();
			printf("<Line box=\"%.2f, %.2f, %.2f, %.2f\"", $bbox1->x1, $bbox1->y1, $bbox1->x2, $bbox1->y2);
			PrintStyle($line_style);
			echo  " cur_num=\"".$line->GetCurrentNum()."\"";
			echo nl2br(">\n");

			// For each word in the line...
			for ($word=$line->GetFirstWord(); $word->IsValid(); $word=$word->GetNextWord())
			{
				// Output the bounding box for the word.
				$bbox2 = $word->GetBBox();
				printf("<Word box=\"%.2f, %.2f, %.2f, %.2f\"", $bbox2->x1, $bbox2->y1, $bbox2->x2, $bbox2->y2);
				echo " cur_num=\"" .$word->GetCurrentNum()."\"";
				$sz = $word->GetStringLen();
				if ($sz == 0) continue;

				// If the word style is different from the parent style, output the new style.
				$s = $word->GetStyle();
				if(!$s->IsEqual($line_style)){
					PrintStyle($s);
				}
				
				echo ">".$word->GetString();
				echo nl2br("</Word>\n");
			}
			echo nl2br("</Line>\n");
		}

		if ($cur_flow_id != -1) {
			if ($cur_para_id != -1) {
				$cur_para_id = -1;
				echo nl2br("</Para>\n");
			}
			echo nl2br("</Flow>\n");


		}
		echo nl2br("</PDFText>\n");

		$txt->Destroy();
		$doc->Close();

	}

	if($example5_low_level)
	{
		$doc = new PDFDoc($input_path);
		$doc->InitSecurityHandler();

		// Example 1. Extract all text content from the document

		$reader = new ElementReader();

		//  Read every page
		for ($itr=$doc->GetPageIterator(); $itr->HasNext(); $itr->Next()) 
		{
			$reader->Begin($itr->Current());
			DumpAllText($reader);
			$reader->End();
		}

		// Example 2. Extract text content based on the 
		// selection rectangle.
		echo nl2br("\n----------------------------------------------------");
		echo nl2br("\nExtract text based on the selection rectangle.");
		echo nl2br("\n----------------------------------------------------\n");

		$first_page = $doc->GetPage(1);
		$s1 = ReadTextFromRect($first_page, new Rect(27.0, 392.0, 563.0, 534.0), $reader);
		echo nl2br("\nField 1: ".$s1);

		$s1 = ReadTextFromRect($first_page, new Rect(28.0, 551.0, 106.0, 623.0), $reader);
		echo nl2br("\nField 2: ".$s1);

		$s1 = ReadTextFromRect($first_page, new Rect(208.0, 550.0, 387.0, 621.0), $reader);
		echo nl2br("\nField 3: ".$s1);

		// ... 
		$doc->Close();
		echo nl2br("Done.\n");
	}
	PDFNet::Terminate();
?>
```

{% endcode %}
{% endtab %}

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

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

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

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

 
def printStyle (style):
    sans_serif_str = ""
    if style.IsSerif():
        sans_serif_str = " sans-serif;"
    rgb = style.GetColor()
    rgb_hex = "%02X%02X%02X;" % (rgb[0], rgb[1], rgb[2])
    font_str = '%g' % style.GetFontSize()
    sys.stdout.write(" style=\"font-family:" + style.GetFontName() + "; font-size:" 
          + font_str + ";" + sans_serif_str + " color:#" + rgb_hex + "\"")

def dumpAllText (reader):
    element = reader.Next()
    while element != None:
        type = element.GetType()
        if type == Element.e_text_begin:
            print("Text Block Begin")
        elif type == Element.e_text_end:
            print("Text Block End")
        elif type == Element.e_text:
            bbox = element.GetBBox()
            print("BBox: " + str(bbox.GetX1()) + ", " + str(bbox.GetY1()) + ", " 
                  + str(bbox.GetX2()) + ", " + str(bbox.GetY2()))
            textString = element.GetTextString()
            print(textString)
        elif type == Element.e_text_new_line:
            print("New Line")
        elif type == Element.e_form:
            reader.FormBegin()
            dumpAllText(reader)
            reader.End()
        element = reader.Next()

# A utility method used to extract all text content from
# a given selection rectangle. The recnagle coordinates are
# expressed in PDF user/page coordinate system.
def ReadTextFromRect (page, pos, reader):
    reader.Begin(page)
    srch_str = RectTextSearch(reader, pos)
    reader.End()
    return srch_str

#A helper method for ReadTextFromRect
def RectTextSearch (reader, pos):
    element = reader.Next()
    srch_str2 = ""
    while element != None:
        type = element.GetType()
        if type == Element.e_text:
            bbox = element.GetBBox()
            if (bbox.IntersectRect(bbox, pos)):
                arr = element.GetTextString()
                srch_str2 += arr
                srch_str2 += "\n"
        elif type == Element.e_text_new_line:
            None
        elif type == Element.e_form:
            reader.FormBegin()
            srch_str2 += RectTextSearch(reader, pos)
            print(srch_str2)
            reader.End()
        element = reader.Next()
    return srch_str2
            

def main():
    PDFNet.Initialize(LicenseKey)
    
    # Relative path to the folder containing test files.
    input_path =  "../../TestFiles/newsletter.pdf"
    example1_basic = False
    example2_xml = False
    example3_wordlist = False
    example4_advanced = True
    example5_low_level = False
   
    # Sample code showing how to use high-level text extraction APIs.
    doc = PDFDoc(input_path)
    doc.InitSecurityHandler()
    
    page = doc.GetPage(1)
    if page == None:
        print("page no found")
        
    txt = TextExtractor()
    txt.Begin(page) # Read the page
    
    # Example 1. Get all text on the page in a single string.
    # Words will be separated witht space or new line characters.
    if example1_basic:
        print("Word count: " + str(txt.GetWordCount()))
        txtAsText = txt.GetAsText()
        print("- GetAsText --------------------------" + txtAsText)
        print("-----------------------------------------------------------")
   
    # Example 2. Get XML logical structure for the page.
    if example2_xml:
        text = txt.GetAsXML(TextExtractor.e_words_as_elements | 
                            TextExtractor.e_output_bbox | 
                            TextExtractor.e_output_style_info)       
        print("- GetAsXML  --------------------------" + text)
        print("-----------------------------------------------------------")
    
    # Example 3. Extract words one by one.
    if example3_wordlist:
        word = Word()
        line = txt.GetFirstLine()
        while line.IsValid():
            word = line.GetFirstWord()
            while word.IsValid():
                wordString = word.GetString()
                print(wordString)
                word = word.GetNextWord()
            line = line.GetNextLine()
        print("-----------------------------------------------------------")
 
    # Example 4. A more advanced text extraction example. 
    # The output is XML structure containing paragraphs, lines, words, 
    # as well as style and positioning information.
    if example4_advanced:
        bbox = Rect();
        cur_flow_id = -1
        cur_para_id = -1
        
        print("<PDFText>")
        # For each line on the page...
        line = txt.GetFirstLine()
        while line.IsValid():
            if line.GetNumWords() == 0:
                line = line.GetNextLine()			
                continue
            word = line.GetFirstWord()
            if cur_flow_id != line.GetFlowID():
                if cur_flow_id != -1:
                    if cur_para_id != -1:
                        cur_para_id = -1;
                        print("</Para>")
                    print("</Flow>")
                cur_flow_id = line.GetFlowID()
                print("<Flow id=\"" + str(cur_flow_id) +"\">")
                    
            if cur_para_id != line.GetParagraphID():
                if cur_para_id != -1:
                    print("</Para>")
                cur_para_id= line.GetParagraphID()
                print("<Para id=\"" +str(cur_para_id)+ "\">")
                
            bbox = line.GetBBox()
            line_style = line.GetStyle()
            sys.stdout.write("<Line box=\"%.2f, %.2f, %.2f, %.2f\"" % ( bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2()))
            printStyle (line_style)
            sys.stdout.write(" cur_num=\"" + str(line.GetCurrentNum()) + "\"" + ">\n")
            
            # For each word in the line...
            word = line.GetFirstWord()
            while word.IsValid():
                # Output the bounding box for the word
                bbox = word.GetBBox()
                sys.stdout.write("<Word box=\"%.2f, %.2f, %.2f, %.2f\"" % ( bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2()))
                sys.stdout.write(" cur_num=\"" + str(word.GetCurrentNum()) + "\"");
                sz = word.GetStringLen()
                if sz == 0:
                    word = word.GetNextWord()				
                    continue
                # If the word style is different from the parent style, output the new style.
                s = word.GetStyle()
                if s != line_style:
                    printStyle (s);
                wordString = word.GetString()
                sys.stdout.write(">" + wordString + "</Word>\n")
                word = word.GetNextWord()
            sys.stdout.write("</Line>\n")                
            line = line.GetNextLine()
            
        if cur_flow_id != -1:
            if cur_para_id != -1:
                cur_para_id = -1
                sys.stdout.write("</Para>\n")
            sys.stdout.write("</Flow>\n")
        
        txt.Destroy()
        doc.Close()            
        print("</PDFText>")
    
    # Sample code showing how to use low-level text extraction APIs.
    if example5_low_level:
        doc = PDFDoc(input_path)
        doc.InitSecurityHandler()

        # Example 1. Extract all text content from the document
        
        reader = ElementReader()
        itr = doc.GetPageIterator()
        while itr.HasNext():
            reader.Begin(itr.Current())
            dumpAllText(reader)
            reader.End()
            itr.Next()
            
        # Example 2. Extract text content based on the 
        # selection rectangle.
        
        print("----------------------------------------------------")
        print("Extract text based on the selection rectangle.")
        print("----------------------------------------------------")
        
        itr = doc.GetPageIterator()
        first_page = itr.Current()
        s1 = ReadTextFromRect(first_page, Rect(27, 392, 563, 534), reader)
        print("Field 1: " + s1)

        s1 = ReadTextFromRect(first_page, Rect(28, 551, 106, 623), reader);
        print("Field 2: " + s1)

        s1 = ReadTextFromRect(first_page, Rect(208, 550, 387, 621), reader);
        print("Field 3: " + s1)
        
        doc.Close()
        
        print("Done.")
    PDFNet.Terminate()
        
if __name__ == '__main__':
    main()
```

{% endcode %}
{% endtab %}

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

```ruby
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 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

def PrintStyle (style)
    sans_serif_str = ""
    if style.IsSerif()
		sans_serif_str = " sans-serif;"
	end 
    rgb = style.GetColor
    rgb_hex =  "%02X%02X%02X;" % [rgb[0], rgb[1], rgb[2]]
    font_str = '%g' % style.GetFontSize
	print " style=\"font-family:" + style.GetFontName + "; font-size:" + font_str + ";" + sans_serif_str + " color:#" + rgb_hex + "\""
end

def DumpAllText (reader)
	element = reader.Next
	while !element.nil? do
		case element.GetType
		when Element::E_text_begin
			puts "Text Block Begin"
		when Element::E_text_end
			puts "Text Block End"
		when Element::E_text
			bbox = element.GetBBox
			puts "BBox: " + bbox.GetX1.to_s + ", " + bbox.GetY1.to_s + ", " +
				bbox.GetX2.to_s + ", " + bbox.GetY2.to_s
			puts element.GetTextString
		when Element::E_text_new_line
			puts "New Line"
		when Element::E_form
			reader.FormBegin
			DumpAllText(reader)
			reader.End
		end
		element = reader.Next
	end
end

# A utility method used to extract all text content from
# a given selection rectangle. The recnagle coordinates are
# expressed in PDF user/page coordinate system.
def ReadTextFromRect (page, pos, reader)
	reader.Begin(page)
	srch_str = RectTextSearch(reader, pos)
	reader.End
	return srch_str
end

#A helper method for ReadTextFromRect
def RectTextSearch (reader, pos)
	element = reader.Next
	srch_str2 = ""
	while !element.nil? do
		case element.GetType
		when Element::E_text
			bbox = element.GetBBox
			if bbox.IntersectRect(bbox, pos)
				arr = element.GetTextString
				srch_str2 += arr
				srch_str2 += "\n"
			end
		when Element::E_text_new_line
		when Element::E_form
			reader.FormBegin
			srch_str2 += RectTextSearch(reader, pos)
			puts srch_str2
			reader.End
		end
		element = reader.Next
	end
	return srch_str2
end			
	
	PDFNet.Initialize(PDFTronLicense.Key)
	
	# Relative path to the folder containing test files.
	input_path =  "../../TestFiles/newsletter.pdf"
	example1_basic = false
	example2_xml = false
	example3_wordlist = false
	example4_advanced = true
	example5_low_level = false
   
	# Sample code showing how to use high-level text extraction APIs.
	doc = PDFDoc.new(input_path)
	doc.InitSecurityHandler
	
	page = doc.GetPage(1)
	if page.nil?
		print("page no found")
	end
		
	txt = TextExtractor.new
	txt.Begin(page) # Read the page
	
	# Example 1. Get all text on the page in a single string.
	# Words will be separated witht space or new line characters.
	if example1_basic
		puts "Word count: " + txt.GetWordCount.to_s
		puts "- GetAsText --------------------------" + txt.GetAsText
		puts "-----------------------------------------------------------"
	end
   
	# Example 2. Get XML logical structure for the page.
	if example2_xml
		text = txt.GetAsXML(TextExtractor::E_words_as_elements | 
					TextExtractor::E_output_bbox | 
					TextExtractor::E_output_style_info)	   
		puts "- GetAsXML  --------------------------" + text
		puts "-----------------------------------------------------------"
	end
		
	
	
	# Example 3. Extract words one by one.
	if example3_wordlist
		word = Word.new
		line = txt.GetFirstLine
		while line.IsValid do
			word = line.GetFirstWord
			while word.IsValid do
				puts word.GetString
				word = word.GetNextWord
			end
			line = line.GetNextLine
		end
		puts "-----------------------------------------------------------"
	end
			

	# Example 4. A more advanced text extraction example. 
	# The output is XML structure containing paragraphs, lines, words, 
	# as well as style and positioning information.
	if example4_advanced
		bbox = Rect.new
		cur_flow_id = -1
		cur_para_id = -1
		
		puts "<PDFText>"
		# For each line on the page...
		line = txt.GetFirstLine
		while line.IsValid do
			word_num = line.GetNumWords
			if word_num == 0
				line = line.GetNextLine			
				next
			end
			word = line.GetFirstWord
			if cur_flow_id != line.GetFlowID
				if cur_flow_id != -1
					if cur_para_id != -1
						cur_para_id = -1
						puts "</Para>"
					end
					puts "</Flow>"
				end
				cur_flow_id = line.GetFlowID
				puts "<Flow id=\"" + cur_flow_id.to_s + "\">"
			end
					
			if cur_para_id != line.GetParagraphID
				if cur_para_id != -1
					puts "</Para>"
				end
				cur_para_id= line.GetParagraphID
				puts "<Para id=\"" + cur_para_id.to_s + "\">"
			end
				
			bbox = line.GetBBox
			line_style = line.GetStyle
			print "<Line box=\"%.2f, %.2f, %.2f, %.2f\""% [bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2()]
			PrintStyle (line_style)
			print " cur_num=\"" + "%d" % line.GetCurrentNum + "\"" + ">\n"
			
			# For each word in the line...
			word = line.GetFirstWord
			while word.IsValid do
				# Output the bounding box for the word
				bbox = word.GetBBox
				print "<Word box=\"%.2f, %.2f, %.2f, %.2f\""% [bbox.GetX1(), bbox.GetY1(), bbox.GetX2(), bbox.GetY2()]
				print " cur_num=\"" + "%d" % word.GetCurrentNum + "\"";
				sz = word.GetStringLen
				if sz == 0
					word = word.GetNextWord				
					next
				end
				# If the word style is different from the parent style, output the new style.
				s = word.GetStyle
				if s != line_style
					PrintStyle (s)
				end
				print ">" + word.GetString + "</Word>\n"
				word = word.GetNextWord
			end
			puts "</Line>"
			line = line.GetNextLine
		end
			
		if cur_flow_id != -1
			if cur_para_id != -1
				cur_para_id = -1
				puts "</Para>"
			end
			puts "</Flow>"
		end
		
		txt.Destroy
		doc.Close			
		puts "</PDFText>"
	end

	# Sample code showing how to use low-level text extraction APIs.
	if example5_low_level
		doc = PDFDoc.new(input_path)
		doc.InitSecurityHandler

		# Example 1. Extract all text content from the document
		
		reader = ElementReader.new
		itr = doc.GetPageIterator
		while itr.HasNext do
			reader.Begin(itr.Current)
			DumpAllText(reader)
			reader.End
			itr.Next
		end
			
		# Example 2. Extract text content based on the 
		# selection rectangle.
		
		puts "----------------------------------------------------"
		puts "Extract text based on the selection rectangle."
		puts "----------------------------------------------------"
		
		itr = doc.GetPageIterator
		first_page = itr.Current
		s1 = ReadTextFromRect(first_page, Rect.new(27, 392, 563, 534), reader)
		puts "Field 1: " + s1

		s1 = ReadTextFromRect(first_page, Rect.new(28, 551, 106, 623), reader);
		puts "Field 2: " + s1

		s1 = ReadTextFromRect(first_page, Rect.new(208, 550, 387, 621), reader);
		puts "Field 3: " + s1
		
		doc.Close
		puts "Done."
	end
	PDFNet.Terminate
```

{% endcode %}
{% endtab %}

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

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

Imports System
Imports System.Drawing
Imports pdftron
Imports pdftron.Common
Imports pdftron.Filters
Imports pdftron.SDF
Imports PDFTRON.PDF

' This sample illustrates various text extraction capabilities of PDFNet.

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

	Sub Main()

		PDFNet.Initialize(PDFTronLicense.Key)

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

		Dim example1_basic As Boolean = False
		Dim example2_xml As Boolean = False
		Dim example3_wordlist As Boolean = False
		Dim example4_advanced As Boolean = True
		Dim example5_low_level As Boolean = False

		' Sample code showing how to use high-level text extraction APIs.
		Try
			Using doc As PDFDoc = New PDFDoc(input_path + "newsletter.pdf")
				doc.InitSecurityHandler()

				Dim pg As Page = doc.GetPage(1)
				If pg Is Nothing Then
					Console.WriteLine("Page not found.")
					Return
				End If

				Using txt As TextExtractor = New TextExtractor
					txt.Begin(pg)	 ' Read the page.
					' Other options you may want to consider...
					' txt.Begin(page, Nothing, TextExtractor.ProcessingFlags.e_no_dup_remove)
					' txt.Begin(page, Nothing, TextExtractor.ProcessingFlags.e_remove_hidden_text)
					' ...

					' Example 1. Get all text on the page in a single string.
					' Words will be separated with space or new line characters.
					If example1_basic Then
						' Get the word count.
						Console.WriteLine("Word Count: {0}", txt.GetWordCount())

						Console.WriteLine("")
						Console.WriteLine("- GetAsText --------------------------")
						Console.WriteLine(txt.GetAsText())
						Console.WriteLine("-----------------------------------------------------------")
					End If


					' Example 2. Get XML logical structure for the page.
					If example2_xml Then
						Console.WriteLine("")
						Console.WriteLine("- GetAsXML  --------------------------")
						Console.WriteLine(txt.GetAsXML(TextExtractor.XMLOutputFlags.e_words_as_elements Or TextExtractor.XMLOutputFlags.e_output_bbox Or TextExtractor.XMLOutputFlags.e_output_style_info))
						Console.WriteLine("-----------------------------------------------------------")
					End If


					If example3_wordlist Then
						Dim word As TextExtractor.Word
						Dim line As TextExtractor.Line = txt.GetFirstLine()
						While line.IsValid()
							word = line.GetFirstWord()
							While word.IsValid()
								Console.WriteLine(word.GetString())
								word = word.GetNextWord()
							End While
							line = line.GetNextLine()
						End While
						Console.WriteLine("-----------------------------------------------------------")
					End If


					' Example 3. A more advanced text extraction example. 
					' The output is XML structure containing paragraphs, lines, words, 
					' as well as style and positioning information.
					If example4_advanced Then
						Dim bbox As Rect
						Dim cur_flow_id As Integer = -1
						Dim cur_para_id As Integer = -1

						Dim line As TextExtractor.Line
						Dim word As TextExtractor.Word
						Dim s As TextExtractor.Style
						Dim line_style As TextExtractor.Style
						Console.WriteLine("<PDFText>")
						' For each line on the page...
						line = txt.GetFirstLine()

						While line.IsValid()
							If Not cur_flow_id = line.GetFlowID() Then
								If Not cur_flow_id = -1 Then
									If Not cur_para_id = -1 Then
										cur_para_id = -1
										Console.WriteLine("</Para>")
									End If
									Console.WriteLine("</Flow>")
								End If
								cur_flow_id = line.GetFlowID()
								Console.WriteLine("<Flow id=""{0}"">", cur_flow_id)
							End If

							If Not cur_para_id = line.GetParagraphID() Then
								If Not cur_para_id = -1 Then
									Console.WriteLine("</Para>")
								End If
								cur_para_id = line.GetParagraphID()
								Console.WriteLine("<Para id=""{0}"">", cur_para_id)
							End If

							bbox = line.GetBBox()
							line_style = line.GetStyle()
							Console.Write("<Line box=""{0}, {1}, {2}, {3}""", bbox.x1.ToString("0.00"), bbox.y1.ToString("0.00"), bbox.x2.ToString("0.00"), bbox.y2.ToString("0.00"))
							PrintStyle(line_style)
							Console.Write(" cur_num=""" & line.GetCurrentNum() & """")
							Console.WriteLine(">")

							' For each word in the line...
							word = line.GetFirstWord()
							While word.IsValid()
								' Output the bounding box for the word.
								bbox = word.GetBBox()
								Console.Write("<Word box=""{0}, {1}, {2}, {3}""", bbox.x1.ToString("0.00"), bbox.y1.ToString("0.00"), bbox.x2.ToString("0.00"), bbox.y2.ToString("0.00"))
								Console.Write(" cur_num=""" & word.GetCurrentNum() & """")
								Dim sz As Integer = word.GetStringLen()
								If (sz = 0) Then Continue While
								' If the word style is different from the parent style, output the new style.
								s = word.GetStyle()
								If Not s.Equals(line_style) Then
									PrintStyle(s)
								End If

								Console.Write(">")
								Console.Write(word.GetString())
								Console.WriteLine("</Word>")
								word = word.GetNextWord()
							End While

							Console.WriteLine("</Line>")
							line = line.GetNextLine()
						End While

						If Not cur_flow_id = -1 Then
							If Not cur_para_id = -1 Then
								cur_para_id = -1
								Console.WriteLine("</Para>")
							End If
							Console.WriteLine("</Flow>")
						End If
					End If

					Console.WriteLine("</PDFText>")
				End Using
			End Using
		Catch ex As PDFNetException
			Console.WriteLine(ex.Message)
		Catch ex As Exception
			MsgBox(ex.Message)
		End Try



		' Sample code showing how to use low-level text extraction APIs.
		If (example5_low_level) Then

			Try
				' Open the test file
				Using doc As PDFDoc = New PDFDoc(input_path + "newsletter.pdf")
					doc.InitSecurityHandler()

					Using reader As ElementReader = New ElementReader

						' Example 1. Extract all text content from the document
						Dim itr As PageIterator = doc.GetPageIterator()
						' While itr.HasNext()
						reader.Begin(itr.Current())
						DumpAllText(reader)
						reader.End()
						'   itr.Next()
						' End While

						' Example 2. Extract text based on the selection rectangle.
						Console.WriteLine("----------------------------------------------------")
						Console.WriteLine("Extract text based on the selection rectangle.")
						Console.WriteLine("----------------------------------------------------")

						Dim first_page As Page = doc.GetPage(1)
						Dim field1 As String = ReadTextFromRect(first_page, New Rect(27, 392, 563, 534), reader)
						Dim field2 As String = ReadTextFromRect(first_page, New Rect(28, 551, 106, 623), reader)
						Dim field3 As String = ReadTextFromRect(first_page, New Rect(208, 550, 387, 621), reader)

						Console.WriteLine("Field 1: {0}", field1)
						Console.WriteLine("Field 2: {0}", field2)
						Console.WriteLine("Field 3: {0}", field3)
						' ... 

						Console.WriteLine("Done.")
					End Using
				End Using

			Catch ex As PDFNetException
				Console.WriteLine(ex.Message)
			Catch ex As Exception
				MsgBox(ex.Message)
			End Try
		End If
		PDFNet.Terminate()
	End Sub


	Sub PrintStyle(ByRef s As TextExtractor.Style)
		Dim RGB As Color = s.GetColor()
		Dim rgb_hex As String = String.Format("{0:X02}{1:X02}{2:X02};", RGB.R, RGB.G, RGB.B)
		Dim sans_serif_str As String = ""
		If s.IsSerif() Then
			sans_serif_str = " sans-serif;"
		End If
		Console.Write(" style=""font-family:{0}; font-size:{1};{2} color:#{3}""", s.GetFontName(), s.GetFontSize(), sans_serif_str, rgb_hex)
	End Sub

	' LowLevelTextExtractUtils ----------------------------------------

	Sub DumpAllText(ByRef reader As ElementReader)
		Dim element As Element = reader.Next()
		While (Not IsNothing(element))		 ' Read page contents
			Dim type As Element.Type = element.GetType()

			If type = element.Type.e_text_begin Then
				Console.WriteLine()
				Console.WriteLine("--> Text Block Begin")
			ElseIf type = element.Type.e_text_end Then
				Console.WriteLine()
				Console.WriteLine("--> Text Block End")
			ElseIf type = element.Type.e_text Then
				Dim bbox As Rect = New Rect
				element.GetBBox(bbox)
				' Console.WriteLine("\n--> BBox: {0}, {1}, {2}, {3}", bbox.x1, bbox.y1, bbox.x2, bbox.y2)

				Dim txt As String = element.GetTextString()
				Console.WriteLine(txt)
			ElseIf type = element.Type.e_text_new_line Then
				' Console.WriteLine()
				' Console.WriteLine("--> New Line")
			ElseIf type = element.Type.e_form Then
				reader.FormBegin()				' Process form XObjects
				DumpAllText(reader)
				reader.End()
			End If

			element = reader.Next()
		End While
	End Sub

	Private _srch_str As String

	' A helper method for ReadTextFromRect
	Sub RectTextSearch(ByRef reader As ElementReader, ByRef pos As Rect)
		Dim element As Element = reader.Next()
		While (Not IsNothing(element))		 ' Read page contents
			Dim type As Element.Type = element.GetType()

			If type = element.Type.e_text Then
				Dim bbox As Rect = New Rect
				element.GetBBox(bbox)

				If (bbox.IntersectRect(bbox, pos)) Then
					Dim txt As String = element.GetTextString()
					_srch_str = _srch_str + txt
				End If
			ElseIf type = element.Type.e_text_new_line Then
			ElseIf type = element.Type.e_form Then
				reader.FormBegin()				   ' Process form XObjects
				RectTextSearch(reader, pos)
				reader.End()
			End If

			element = reader.Next()
		End While
	End Sub


	' A utility method used to extract all text content from
	' a given selection rectangle. The rectangle coordinates are
	' expressed in PDF user/page coordinate system.
	Function ReadTextFromRect(ByRef page As Page, ByRef pos As Rect, ByRef reader As ElementReader) As String
		_srch_str = ""
		reader.Begin(page)
		RectTextSearch(reader, pos)
		reader.End()
		Return _srch_str
	End Function

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/textextracttest.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.
