Converting Word Documents to PDF with Azure Functions, SharePoint & Microsoft Graph

A complete walkthrough with PnP Core SDK and REST-based Graph integration

GitHub repo: https://github.com/greian/AzureFunctions.ConvertToPdf

Why I Built This

In many SharePoint solutions, users expect documents to be available as PDF — whether for archiving, sharing, or publishing to external systems. Manually exporting every document is tedious, and Power Automate’s built-in convert-to-PDF action is slow, inconsistent, and requires premium licenses.

So I built a serverless Azure Function that:

  • Reads a Word document from a SharePoint Online library
  • Converts it to PDF using Microsoft Graph’s ?format=pdf endpoint
  • Uploads the PDF to another library (or a folder structure inside it)
  • Supports overwriting existing PDFs → creates new versions automatically
  • Uses PnP Core SDK for easy authentication and site navigation
  • Uses REST-based Graph calls for conversion (more stable than the SDK)

The end result is a fast, scalable, cost-efficient pipeline with no third-party libraries.

All the code is available in this repo:

https://github.com/greian/AzureFunctions.ConvertToPdf

Architecture Overview

Here’s the end-to-end flow:

  1. Azure Function (HTTP triggered)
    Receives JSON containing:
    • Source site URL
    • Library name
    • Item ID
    • Original file name
    • Target library + optional folder path
  2. PnP Core SDK
    • Handles Azure AD authentication
    • Finds the SharePoint list & list item
    • Resolves the list GUID for Graph
  3. Microsoft Graph REST API
    • GET /lists/{id}/items/{itemId}/driveItem → get driveItem
    • GET /drives/{driveId}/items/{itemId}/content?format=pdf → convert Word → PDF
    • PUT /drives/{driveId}/root:/path/file.pdf:/content → upload PDF
  4. SharePoint Online
    • Stores the PDF in the target library
    • Creates a new file version if a PDF with the same name already exists

Why Not Use Microsoft.Graph NuGet Instead?

The new Graph SDK (v5+) is great, but:

  • It adds model abstractions we don’t need
  • It’s extremely heavy in function apps
  • You get full control & fewer dependencies using REST directly
  • PnP Core already provides the authenticated token for us

This combination turned out to be the most robust solution:

✔ PnP Core for auth
✔ Graph REST for conversion + upload
✔ No unnecessary Graph SDK dependencies

Code Walkthrough

The full code is in the repo, but here’s the core function as implemented:
(Automatically referenced from your uploaded file.)
ConvertToPdf

The important parts:

1. Authenticating to Graph using PnP Core

var client = httpClientFactory.CreateClient();
client.BaseAddress = new Uri("https://graph.microsoft.com/v1.0/");

var dummyRequest = new HttpRequestMessage(HttpMethod.Get, "$metadata");
await context.AuthenticationProvider.AuthenticateRequestAsync(dummyRequest.RequestUri, dummyRequest);

client.DefaultRequestHeaders.Authorization = dummyRequest.Headers.Authorization;

2. Getting the driveItem for the Word document

var driveItemResponse = await graphClient.GetAsync(
    $"sites/{siteId}/lists/{listId}/items/{itemId}/driveItem?$select=id,parentReference");

var driveItem = await driveItemResponse.Content.ReadFromJsonAsync<GraphDriveItemInfo>();
var driveId = driveItem.ParentReference.DriveId;
var driveItemId = driveItem.Id;

3. Converting Word → PDF using Graph

var pdfResponse = await graphClient.GetAsync(
    $"drives/{driveId}/items/{driveItemId}/content?format=pdf");

var pdfBytes = await pdfResponse.Content.ReadAsByteArrayAsync();

4. Uploading the PDF to the target library

var uploadUrl = $"drives/{driveId}/root:/{escapedPath}:/content";

var uploadResponse = await graphClient.PutAsync(uploadUrl, new ByteArrayContent(pdfBytes));
uploadResponse.EnsureSuccessStatusCode();

Versioning? Yes, automatically!

If you upload to the same path, SharePoint will:

  • Replace the file content
  • Create a new version

No extra code needed.

Example Request Payload

POST to your function:

{
  "SourceSiteUrl": "https://tenant.sharepoint.com/sites/MySite",
  "SourceLibraryTitle": "Documents",
  "ItemId": 123,
  "FileName": "QuarterlyReport.docx",
  "TargetLibraryTitle": "PublishedPDF",
  "TargetFolderPathInLibrary": "2025/Q1"
}

The function responds with:

{
  "success": true,
  "pdfItemWebUrl": "https://tenant.sharepoint.com/.../QuarterlyReport.pdf",
  "message": "Conversion completed successfully."
}

Notes & Pitfalls

1. Large Files

Graph supports very large files, but Azure Functions may timeout.
Premium or Dedicated plans recommended for >100MB documents.

2. File Versions

Overwriting an existing PDF = new version.
Disable versioning if you want overwrites without history.

3. Permissions

Your Azure AD app must have:

  • Sites.ReadWrite.All or
  • Sites.Selected with explicit site permissions

4. File Name Detection

We resolve the filename from Graph driveItem instead of relying on SharePoint fields like FileLeafRef (which are not always loaded or available).

GitHub Repository

Source code and a ready-to-deploy Function App can be found in this github repo:

https://github.com/greian/AzureFunctions.ConvertToPdf

Feel free to fork, star, or open issues.

Summary

This approach gives you a fast, reliable, and license-free way to convert Word documents to PDF in SharePoint – without relying on Power Automate Premium or third-party libraries like Aspose or Syncfusion. It is lightweight, cloud-native, cost-effective, and scales well.

Leave a comment