Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Office files to PDF using Microsoft Graph

I'm looking for a way to convert Office files to PDF. I found out that Microsoft Graph could be used.

I'm trying to download converted PDF using Microsoft Graph from OneDrive. I'd like to convert .docx to .pdf.

However, when I sent the following request, I did not receive a response even if I waited.

GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content?format=pdf

Also, the error code is not returned. If syntax is wrong, an error code will be returned as expected. It will not return only when it is correct.

In addition, I can download the file if I do not convert.

GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content

Is my method wrong or else I need conditions? If possible, please give me sample code that you can actually do.

 using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
            client.BaseAddress = new Uri(graphUrl);

            var result = await client.GetAsync("/v1.0/users/xxxxxxxxxxxxxxxxxxxxxxxxx/drive/root:/test.docx:/content?format=pdf");
            :
like image 232
ytaka Avatar asked Sep 01 '25 02:09

ytaka


2 Answers

I would like to elaborate a bit Marc's answer by providing a few examples for HttpClient.

Since by default for HttpClient HttpClientHandler.AllowAutoRedirect property is set to True there is no need to explicitly follow HTTP redirection headers and the content could be downloaded like this:

using (HttpClient client = new HttpClient())
{
     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
     client.BaseAddress = new Uri("https://graph.microsoft.com");

     var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");

      //save content into file 
      using (var file = System.IO.File.Create(fileName))
      { 
           var stream = await response.Content.ReadAsStreamAsync(); 
           await stream.CopyToAsync(file); 
      }
}

In case if follow HTTP redirection is disabled, to download the converted file, your app must follow the Location header in the response as demonstrated below:

var handler = new HttpClientHandler()
{
    AllowAutoRedirect = false
};

using (HttpClient client = new HttpClient(handler))
{
     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
     client.BaseAddress = new Uri("https://graph.microsoft.com");

     var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
     if(response.StatusCode == HttpStatusCode.Redirect)
     {
           response = await client.GetAsync(response.Headers.Location); //get the actual content
     }

      //save content into file 
      using (var file = System.IO.File.Create(fileName))
      { 
           var stream = await response.Content.ReadAsStreamAsync(); 
           await stream.CopyToAsync(file); 
      }
}
like image 177
Vadim Gremyachev Avatar answered Sep 03 '25 15:09

Vadim Gremyachev


The API doesn't return the converted content directly, it returns a link to the converted file. From the documentation:

Returns a 302 Found response redirecting to a pre-authenticated download URL for the converted file.

To download the converted file, your app must follow the Location header in the response.

Pre-authenticated URLs are only valid for a short period of time (a few minutes) and do not require an Authorization header to access.

You need to capture the 302 and make a 2nd call to the URI in the Location header in order to download the converted file.

like image 34
Marc LaFleur Avatar answered Sep 03 '25 14:09

Marc LaFleur