From Unstructured to Structured: Adobe PDF Extract API for Data Transformation 📑
Tags: programming, learning, java, coding
Published: 2024-06-07 17:31:54


Ever felt like you're wrestling with a stubborn PDF, desperately trying to extract that crucial information? We've all been there. PDFs are fantastic for document portability, but their structure can often make it a nightmare to get the data you need.

Imagine this: you've just received a massive repository of PDF documents from a client, filled with valuable data that needs to be analysed and utilized. You're eager to dive in, but there's a catch : half of these PDFs are _scanned_, and extracting meaningful information from them seems like a Herculean task. 
Sound familiar?

Whether you're in finance, legal, healthcare, or any data-intensive field, the challenge of extracting data from PDFs is a common hurdle. Traditional methods often fall short, leaving you frustrated with manual data entry and limited extraction tools that can't handle the complexities of scanned documents.

## The Struggle with PDF Extraction
You might have perfect digital PDFs where text extraction is straightforward. But then you hit a wall with scanned PDFs, where the text is essentially locked in images. This is not just inconvenient but also incredibly time-consuming and prone to errors. The quality of data suffers, and your efficiency takes a hit.

## The Game-Changer: Adobe Extract API Service
In our quest for an efficient solution, we have explored numerous services and tools, such as [AWS Textract](https://docs.aws.amazon.com/textract/latest/dg/how-it-works.html), which automatically extracts text and data from scanned documents, and [Unstructured](https://unstructured.io/), which provides open-source solutions for processing and analysing unstructured data,each promising to simplify PDF data extraction . However, the real breakthrough came when we discovered the Adobe Extract API service. This service didn't just meet our expectations; it exceeded.

The Adobe Extract API service is designed to handle the complexities of both digital and scanned PDFs with remarkable accuracy. It seamlessly ingests PDFs and extracts text, tables, and images, turning even the most stubbornly scanned documents into actionable data. Additionally, Adobe Extract is well-suited for handling multi-column layouts, such as those found in newsletters. The Adobe Extract API service provided a reliable, efficient solution that saved us countless hours and significantly improved our data quality.

_No more delays, let's get started‼_

### What exactly is the Adobe Extract API?
Think of it as your personal PDF sherpa, guiding you through the maze of document structures. It's a cloud-based web service powered by Adobe Sensei, Adobe's industry-leading AI and Machine Learning platform.Although the Adobe PDF Extract API itself is not open source, it provides open-source SDKs for various programming languages, including Java and Python, which can be used to integrate the API into applications.

Here's the magic: [Adobe Sensei AI](https://developer.adobe.com/document-services/apis/pdf-services/adobe-pdf-extract-api/) dives deep into each page, deciphering layouts, structures, and even nuances in text and images. It doesn't just stop at simple text extraction; it's capable of tackling complex tables, figures, and more, all while maintaining accuracy and precision.

The best part? Once the Adobe Extract API works its magic, it transforms everything into a neatly organised JSON format, ready for you to dive into. It works well with both native and scanned documents.

Imagine a world where extracting customer information from invoices, product details from brochures, or financial data from reports becomes a breeze. That's the power the Adobe Extract API puts in your hands.


##### _Please refer to Adobe's official [GitHub](https://github.com/adobe/pdfservices-java-sdk-samples) repository for the full code implementation.This sample code example provides a valuable starting point:_ <br><br>



```
  ExtractPDFParams extractPDFParams = ExtractPDFParams.extractPDFParamsBuilder()
                    .addElementsToExtract(Arrays.asList(ExtractElementType.TEXT, ExtractElementType.TABLES))
                    .addElementsToExtractRenditions(Arrays.asList(ExtractRenditionsElementType.TABLES, ExtractRenditionsElementType.FIGURES))
                    .build();

```


This section of the code is where you specify which elements you want to extract from the PDF document. It's like setting up a blueprint for the extraction process. Here, you can add different types of elements, such as text, tables, or images based on your requirements. By configuring these parameters, you ensure that the Adobe Extract API focuses on extracting the specific elements you're interested in, making the extraction process more targeted and efficient.



This is the sample [PDF](https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf) link that you can use to compare the below outputs:

1. It extracts the text, tables and figures within the PDF.
2. Finally, it converts the extracted tables into a CSV format, making the data easier to work with.


<figure>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5p6stint4boahvdfgel.png)
<figcaption> <br> Fig.1 - Output structure after Adobe extraction <br><br> </figcaption>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ui5lbks0s9gltqa643c.png)
<figcaption> <br> Fig.2 -  JSON structure of extracted data <br><br></figcaption>
</figure>


### 1.Extended metadata: <br><br>

```
"extended_metadata": {
 "ID_instance": "11 B0 4E 31 FA B9 B2 11 0A 00 67 45 8B 6B C6 23 ",
 "ID_permanent": "45 46 20 44 30 20 34 42 20 33 31 20 46 41 20 42 39 20 42 32 20 31 31 20 30 41 20 30 30 20 36 37 20 34 35 20 38 42 20 36 42 20 43 36 20 32 33 20 ",
 "has_acroform": false,
 "has_embedded_files": false,
 "is_XFA": false,
 "is_certified": false,
 "is_encrypted": false,
 "is_digitally_signed": false,
 "language": "en",
 "page_count": 4,
 "pdf_version": "1.6",
 "pdfa_compliance_level": "",
 "pdfua_compliance_level": ""
}
```

The provided JSON object contains metadata about the PDF file, including a unique instance identifier, a permanent identifier, and flags indicating various properties such as the presence of interactive forms, embedded files, XML Forms Architecture, certification, encryption, digital signatures, and compliance with PDF/A and PDF/UA standards. The metadata also specifies the language used in the PDF, the number of pages, and the version of the PDF standard employed. This detailed information helps in understanding the structure, security, and compatibility of the PDF file.


### 2.Elements <br><br>

#### _Section:Text_ <br><br>

```
{
      "Bounds": [
        57.635894775390625, 460.58860778808594, 123.0447998046875,
        480.5798645019531
      ],
      "Font": {
        "alt_family_name": "Arial",
        "embedded": true,
        "encoding": "Custom",
        "family_name": "Arial",
        "font_type": "TrueType",
        "italic": false,
        "monospaced": false,
        "name": "HOEPNL+Arial,Bold",
        "subset": true,
        "weight": 700
      },
      "HasClip": false,
      "Lang": "en",
      "ObjectID": 312,
      "Page": 0,
      "Path": "//Document/Sect[2]/H1",
      "Text": "Overview ",
      "TextSize": 14.038803100585938,
      "attributes": { "LineHeight": 16.875 }
    },
    {
      "Bounds": [
        57.635894775390625, 430.2440490722656, 522.2810974121094,
        457.99635314941406
      ],
      "Font": {
        "alt_family_name": "Arial",
        "embedded": true,
        "encoding": "Custom",
        "family_name": "Arial",
        "font_type": "TrueType",
        "italic": false,
        "monospaced": false,
        "name": "HOEPAP+Arial",
        "subset": true,
        "weight": 400
      },
      "HasClip": false,
      "Lang": "en",
      "ObjectID": 313,
      "Page": 0,
      "Path": "//Document/Sect[2]/P",
      "Text": "This sample consists of a simple form containing four distinct fields. The data file contains eight separate records. ",
      "TextSize": 11.039093017578125
    }
```

The provided JSON object includes details such as the element's spatial coordinates, font characteristics, and other attributes that help identify and style the element. The object contains the actual text value of the element, which provides a clear understanding of the content within that section.

The **_Path_** property in the provided JSON object represents an XPath expression that identifies the location of the text element within the PDF document structure. Specifically:


- **_/Sect_** matches the second **_Sect_** (section) element under the _Document_ element.
- **_/H1_** matches the **_H1_** (heading 1) element under the second section.

So this XPath expression selects the **_H1_** heading element that is the child of the second **_Sect_** element in the PDF document. This allows the text element to be precisely located and referenced within the document's hierarchy.

#### _Section:Table/Figures_ <br><br>

```
{
     "Bounds": [
       63.39500427246094, 499.7163848876953, 433.54026794433594,
       629.3433837890625
     ],
     "ObjectID": 386,
     "Page": 0,
     "Path": "//Document/Sect/Table",
     "attributes": {
       "BBox": [
         56.757699999998295, 496.57199999998556, 514.8989999999758,
         635.045999999973
       ],
       "NumCol": 2,
       "NumRow": 4,
       "Placement": "Block",
       "SpaceAfter": 18
     },
     "filePaths": ["tables/fileoutpart0.csv", "tables/fileoutpart1.png"]
   }
```

The provided JSON object includes attributes that describe the table's structure, layout and also file paths for the table, which are easy to map with corresponding section data:

- _tables/fileoutpart0.csv_
- _tables/fileoutpart1.png_

These file paths contain data or images related to tables in _.csv_ and figures in _.png_ which can be used to enhance or extend the content of elements within the document.

Thus, the API captures the natural reading order of the extracted elements and their layout on each page. This helps you understand the overall context of the extracted data.



<figure>
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g5jmg1wshed279hq45e8.png)
 <figcaption>Fig.3 - png generated for a table</figcaption>
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7riztghufk5k87b7gv2k.png)
<figcaption> <br> Fig.4 - csv generated for a table <br></figcaption>
</figure>


### 3.Pages

```
{
     "boxes": {
       "CropBox": [0.0, 0.0, 612.0, 792.0],
       "MediaBox": [0.0, 0.0, 612.0, 792.0]
     },
     "height": 792.0,
     "is_scanned": false,
     "page_number": 0,
     "rotation": 0,
     "width": 612.0
   }
```

This object indicates whether the page was scanned or not, its page number within the document, and its rotation angle. 

## PDF Processing 101: Understanding the Limits!!
Adobe's API has some limitations when it comes to processing PDF files.Here are few,

- File Size: Files up to 100 MB are supported, so you can keep your files lean and mean.
- Number of Pages: Non-scanned PDFs can handle up to 400 pages, while scanned PDFs are limited to 150 pages or less. 
- For files that are bigger than a house or have a crazy layout, it's best to break them up into smaller chunks before processing.

If your PDF is a bit on the heavy side, don't worry Adobe's got your back. They offer a way to delete pages, so you can give your file a makeover and make it fit for processing.

**Don’t forget that deleting pages also costs you time and money!!**

**Reference:**

- https://developer.adobe.com/document-services/docs/overview/pdf-extract-api/howtos/extract-api/
- https://developer.adobe.com/document-services/apis/pdf-services/adobe-pdf-extract-api/
- [Github](https://github.com/adobe/pdfservices-java-sdk-samples) - Java SDK for Adobe Extract API