Parsing Table Data from PDFs in Power Automate with Azure AI
Leverage Azure AI Document Intelligence's pre-built Layout model to capture structured row-and-column data from PDF invoices, reports, and forms directly inside your Power Automate workflows.
Every day, organizations drown in PDFs holding critical data—but that data is stranded in rows and columns that aren't easily queried. Power Automate's standard PDF connector can extract text, but it doesn't preserve table structure. This is where Azure AI Document Intelligence's Layout model shines. It analyzes the pixel-perfect layout of a document, identifies tables, and returns their content in a structured JSON format, complete with row and column indexes.
In this guide, we'll walk through a practical example that reads a monthly sales report PDF, identifies a table containing Region, SalesRep, Quota, Actual, and Variance% columns, and outputs the data into a structure ready for databases or reporting tools.
1. Provision the Azure AI Resource
Start by creating an Azure AI Document Intelligence resource in the Azure Portal.
- Search for "Document intelligences".
- Click Create.
- Choose a resource group and name the resource something descriptive, like
pdf-table-extractor. - Select the Standard S0 pricing tier.
- Complete the wizard and deploy the resource.
After deployment, open the resource and navigate to the Keys and Endpoint section. Copy the Endpoint URL and one of the Key values—you'll need these when you configure your flow's HTTP actions.
2. Build the Power Automate Flow
Create an Instant cloud flow with a Manually trigger a flow action. Add an input parameter named Document of type File. This input will receive the PDF byte stream you want to analyze.
Step 2.1 – Submit the PDF for Analysis
Insert an HTTP action and set the following properties.
| Property | Value |
|---|---|
| Method | POST |
| URI | @{concat('https://YOUR_ENDPOINT.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-layout:analyze?api-version=2024-11-30')} |
| Headers | Ocp-Apim-Subscription-Key: YOUR_API_KEYContent-Type: application/json |
| Body | See code block below |
{
"base64Source": "@{triggerBody()?['file']?['contentBytes']}"
}If your trigger input parameter is named something other than file, adjust the triggerBody() expression accordingly.
This request is processed asynchronously. The API immediately returns a 202 Accepted status code and includes an apim-request-id header that identifies your analysis operation.
Step 2.2 – Store the Operation ID
Add an Initialize variable action to hold the operation ID returned by the POST request.
Create a variable named varOperationId of type String and set its value:
outputs('POST_to_Analyze')?['headers']?['apim-request-id']Step 2.3 – Poll for the Result
The Layout model needs a few seconds to process the document. A simple Delay action of 15 seconds is a good starting point for typical PDFs. For production flows, implement a Do Until loop that checks the status field instead of using a fixed delay.
After the delay, insert another HTTP action to retrieve the results.
| Property | Value |
|---|---|
| Method | GET |
| URI | @{concat('https://YOUR_ENDPOINT.cognitiveservices.azure.com/documentintelligence/documentModels/prebuilt-layout/analyzeResults/', variables('varOperationId'), '?api-version=2024-11-30')} |
| Headers | Ocp-Apim-Subscription-Key: YOUR_API_KEYContent-Type: application/json |
Instead of a fixed 15-second delay, wrap the GET request in a Do Until loop that runs every 5 seconds until body('GET_Results')?['status'] equals succeeded or failed. This handles large or complex documents automatically.
3. Extract and Transform the Table Data
The GET response body contains an analyzeResult object. Inside it, a tables array holds every table the model detected in the document.
Add a Compose action to inspect the raw tables output:
body('GET_Results')?['analyzeResult']?['tables']Each table object contains a cells array. Every cell has a rowIndex, columnIndex, and content property. For merged cells you'll also find rowSpan and columnSpan.
To flatten the first table's cells into a simple list suitable for further processing, add a Select action:
- From:
body('GET_Results')?['analyzeResult']?['tables'][0]?['cells'] - Map:
| Key | Value |
|---|---|
| Row | item()?['rowIndex'] |
| Column | item()?['columnIndex'] |
| Value | item()?['content'] |
This Select action produces an array of objects you can filter, sort, or write directly into a SQL table, Dataverse entity, or SharePoint list.
Common Pitfalls and Troubleshooting
1. Exposing API credentials
Hard-coding the Ocp-Apim-Subscription-Key inside an HTTP action header isn't ideal. Use an Azure Key Vault connection or a secure environment variable from your environment to manage secrets safely.
2. Wrong document format
The base64Source property expects a Base64-encoded byte stream. The standard file trigger provides contentBytes, which is already encoded. If you're passing the file directly, ensure it's a supported format: PDF, TIFF, PNG, or JPEG.
3. Missing or empty tables
If your PDF is a scanned image, make sure you're using an API version that includes OCR (all recent 2024+ versions do). Also check that the document actually contains extractable table borders—lightly drawn tables sometimes require the outputContentFormat parameter set to markdown to preserve markdown table syntax.
4. Cell alignment for merged headers
When the table has merged header cells, the rowSpan and columnSpan values are critical. Don't rely solely on rowIndex and columnIndex to rebuild the layout—include these span properties in your Select mapping if needed.
Final Recommendation
Azure AI Document Intelligence's Layout model turns PDF from a dead-end format into a structured, queryable data source. Paired with Power Automate, it closes the gap between document-based processes—purchase orders, manifests, invoices—and your digital workflows.
Start small: test with a single-page document, confirm your rowIndex and columnIndex mapping works, then scale up to multi-page, multi-table PDFs. For production implementations, always implement async polling with a Do Until loop and secure your API credentials properly.
References
Tailor AI model responses without compromising data privacy: learn how to call Azure OpenAI models from a Power Automate flow to automatically categorize and direct incoming customer inquiries.
Core principles for resilient, maintainable, and efficient cloud flows, distilled from real-world implementations.
Build flows that gracefully handle failures and automatically notify you with run details.