> 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/basic-operations/page-content.md).

# Access PDF content to read, write & edit on Server/Desktop

Learn how to access PDF page content with the ElementReader API. Explore code samples and powerful features of Apryse SDK for efficient content extraction and dynamic PDF generation. The Apryse Server

To access PDF page content.

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

```csharp
PDFDoc doc = new PDFDoc(filename);
Page page = doc.GetPage(page_num);
ElementReader reader = new ElementReader();

// Use reader to being reading the page
reader.Begin(page);

// Iterate over the page elements
while ((element = reader.Next()) != null)
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```cpp
PDFDoc doc(filename);
Page page = doc.GetPage(page_num);
ElementReader reader;

// Use reader to being reading the page
reader.Begin(page);

// Iterate over the page elements
for (Element element=reader.Next(); element; element = reader.Next())
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```go
doc := NewPDFDoc(filename)
page := doc.GetPage(page_num)
pageReader := NewElementReader()

// Use reader to being reading the page
pageReader.Begin(page)

element := reader.Next()
for element.GetMp_elem().Swigcptr() != 0 {       
    
  // ... perform some document processing

  element = reader.Next()
}
```

{% endcode %}
{% endtab %}

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

```java
PDFDoc doc = new PDFDoc(filename);
Page page = doc.getPage(page_num);
ElementReader reader = new ElementReader();

// Use reader to being reading the page
reader.Begin(page);

for (Element element = reader.next(); element != null; element = reader.next())
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```js
async function main() {
  const doc = await PDFNet.PDFDoc.createFromURL(filename);
  const page = await doc.getPage(page_num);
  const reader = await PDFNet.ElementReader.create();

  // Use reader to being reading the page
  reader.beginOnPage(page);

  for (let element = await reader.next(); element !== null; element = await reader.next())
  {
    // ... perform some document processing
  }
}
PDFNet.runWithCleanup(main);
```

{% endcode %}
{% endtab %}

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

```kotlin
val doc = PDFDoc(filename)
val page = doc.getPage(page_num)
val reader = ElementReader()

// Use reader to being reading the page
reader.begin(page);

val element: reader.next()
while (element != null) 
{
  // ... perform some document processing
  element = reader.next()
}
```

{% endcode %}
{% endtab %}

{% tab title="Obj-C" %}
{% code lineNumbers="true" %}

```objc
PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: filename];
PTPage *page = [doc GetPage: page_num];
PTElementReader *reader = [[PTElementReader alloc] init];

// Use reader to being reading the page
[reader Begin: page];

for (PTElement *element=[reader Next]; element != NULL; element = [reader Next])
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```swift
let doc: PTPDFDoc = PTPDFDoc(filepath: filename)
let page: PTPage = doc.getPage(page_num)
let reader: PTElementReader = PTElementReader()

// Use reader to being reading the page
reader.begin(page)

while let element = reader.next()
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```php
$doc = new PDFDoc($filename);
$page = $doc->GetPage($page_num);
$reader = new ElementReader();

// Use reader to being reading the page
$reader->Begin($page);
for ($element=$reader->Next(); $element != null; $element = $reader->Next())
{
  // ... perform some document processing
}
```

{% endcode %}
{% endtab %}

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

```python
doc = PDFDoc(filename)
page = doc.GetPage(page_num)
reader = ElementReader()

# Use reader to being reading the page
reader.Begin(page)

element = reader.Next()
while element != None:
  # ... perform some document processing
  element = reader.Next()
```

{% endcode %}
{% endtab %}

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

```ruby
doc = PDFDoc.new(filename)
page = doc.GetPage(page_num)
reader = ElementReader.new()

# Use reader to being reading the page
reader.Begin(page)

element = reader.Next()
while !element.nil? do
  # ... perform some document processing
  element = reader.Next()
end
```

{% endcode %}
{% endtab %}

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

```vb
Dim doc As PDFDoc = New PDFDoc(filename)
Dim page As Page = doc.GetPage(page_num)
Dim reader As ElementReader = New ElementReader()

' Use reader to being reading the page
reader.Begin(page)

Dim element As Element = reader.Next()
While element IsNot Nothing
  ' ... perform some document processing
  element = reader.Next()
End While
```

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

[Read Elements Across All PDF Pages](/core/get-started/samples/elementreadertest.md) Full code sample which illustrates how to traverse page display list using ElementReader.

## About working with page content

Apryse SDK provides a powerful, easy-to-use API that can be used to read, write and edit text, images, and other graphical entities, called the *Element* API. A good match for interactive applications (such as PDF viewers and editors), for content extraction applications (such as PDF conversion and validation), and for dynamic PDF generation because the Element API is very efficient.

Page content, a major component of a PDF document, is made up of the visible marks on a page drawn by PDF marking operators. For details on PDF content streams and thorough operator descriptions please refer to Section 3.7.1, “Content Streams,” in the PDF Reference Manual.

Although the Apryse SDK SDF and Filter APIs provide everything required to decode and parse low-level content streams, using the Element API is easier and more intuitive. The reason why is that the Element API allows you to treat a page's contents as a *list of objects* (i.e. a display list or a sequence of Elements) rather than as sets of cryptic marking operators.

## What is an element?

An Element (such as text, a path, or an image) is constructed from a set of marking operators from the page content stream. A set of Elements represents a display list.

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-afafb1dd1f208fa387d7e910fc852bdec63134bd%2F1bbeacf628e7120439d1692a36a1bd0aaa6e5167-469x244.gif?alt=media)

A sequence of page marking operators represents an Element.

Therefore, the Apryse SDK Element interface allows you to treat page contents as a list of objects whose values and attributes can be modified.

Using the Element interface, applications can read, write, edit, and create page contents and resources. These contents and resource may in turn contain fonts, images, shadings, patterns, extended graphics states, and so on.

An application may use Element methods to modify the appearance of a page, or it can create page content from scratch.

Each Element is independent of other Elements. Therefore, every Element encapsulates all the relevant information about itself. A text object, for example, contains all font attributes.

*Element* is the concrete base class for all Elements. Apryse SDK supports all content elements allowed by the PDF format, namely: `path`, `text_begin`, `text`, `text_new_line`, `text_end`, `image`, `inline_image`, `shading`, `form`, `group_begin`, `group_end`, `marked_content_begin`, and `marked_content_end`.

Note that some Elements — such as `path`, `text`, `image`, `inline-image`, and `shading` — represent concrete graphical elements. However, other Elements — such as `text_begin/end`, `text_new_line`, `group_begin/end`, and `marked_content_begin/end` — don't have graphical representation but are used for logical grouping of Element sequences or to provide meta-data associated with Element groups.

The Element class hierarchy implements a composite pattern — that is, the Element class provides the methods of all derived classes.

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-24611cee0bf5d34d272aeec25ffcaaa18770db2e%2Fa9e064a8e563c4d0c5c915b3329aaf1b136ca05c-352x1316.gif?alt=media)

Element hierarchy. Only methods listed in the Element group or base class can be invoked for the given type.

To find the type of an Element object, use the `element.GetType()` method. **Be forewarned:** it is not allowed to call methods on an object that are not related to that object's Element type. The behavior when doing so is undefined. For example, it is illegal to call `element.GetImageData()` on an e\_path element.

Note that, in above, `e_group_begin/end` and `e_text_begin/end` don't add any functionality to the common Element interface (i.e. `GetType()/GetGState()/GetCTM()`). The main purpose of these Elements is to mark sequences of Elements into logical groups. The Element `e_group_begin` corresponds to the PDF 'q' operator (saveState), `e_group_end` corresponds to the 'Q' operator, `e_text_begin` corresponds to the 'BT' (begin text) operator, and e\_text\_end corresponds to the 'ET' operator.

`e_text_begin` initializes a text object, initializing the text matrix and the text line matrix to the identity matrix. Because PDF text objects can't be nested, a second `e_text_begin` element cannot appear before `e_text_end`. A text object contains one or more text runs (that is, e\_text elements) and new line markers (that is, e\_text\_new\_line elements). `e_text` and `e_text_new_line` are not allowed outside of the text group (that is, outside element sequence surrounded by `e_text_begin/end`).

## Graphics state

Every element has an associated CTM (current transformation matrix) and graphics state. `Element.GetCTM()` returns the transformation matrix used while processing the current Element. `Element.GetGState()` returns the element's associated graphics state. GState keeps track of a number of style attributes used to visually define graphical Elements.

The methods available through the GState class are listed below:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-0dedc7fa7f12f11169da67671472285d1a7edff6%2Ffdd3f933e2db8d513b3934a8f38500da7abf7066-178x830.gif?alt=media)

Graphics State.

For a detailed description of graphics state attributes refer to section 4.3 "Graphics State" in the PDF Reference Manual.


---

# 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/basic-operations/page-content.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.
