Azure Functions allows you to run small pieces of code (called “functions”) without worrying about application infrastructure. With Azure Functions, the cloud infrastructure provides all the up-to-date servers you need to keep your application running at scale.
SelectPdf offered a .NET Core version for some time, but although it worked on some types of Azure deployments, it was not supported on Azure functions, due to some platform restrictions.
Things have changed starting with Azure Functions V3 and SelectPdf Library can run in an Azure Function. There are a few other things to take into account: similar to Azure Web Apps deployments, SelectPdf will use a restricted rendering engine to be able to run in an Azure Function. The hosting plan should be Premium or App Service Plan, starting with Standard. SelectPdf will not work with an Azure Consumption Plan nor with a Free or Shared App Service Plan.
SelectPdf and Azure Functions Sample
The following sample was created in Visual Studio 2019 and uses Azure Functions V3 with .NET Core 3.1. It shows how to read several parameters received through a GET or POST request (x-www-form-urlencoded or json encoded) and how to convert to pdf the specified url or html string.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace SelectPdf.AzureFunctions.Sample
{
public static class ConvertToPdf
{
/// <summary>
/// Use this function to convert an url or html to pdf using SelectPdf.
/// The function shows how you can send a few parameters
/// through GET or POST (x-www-form-urlencoded or json encoded).
/// Send at least the "url" or "html" parameter.
/// Other parameters are also supported (see code).
/// </summary>
/// <returns></returns>
[FunctionName("ConvertToPdf")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("Starting the conversion to pdf...");
try
{
// read parameters from query string
string url = req.Query["url"];
string html = req.Query["html"];
string base_url = req.Query["base_url"];
string page_size = req.Query["page_size"];
string page_orientation = req.Query["page_orientation"];
string web_page_width_str = req.Query["web_page_width"];
string web_page_height_str = req.Query["web_page_height"];
// read from POST if encoding is application/x-www-form-urlencoded
if (req.ContentType?.ToLower() == "application/x-www-form-urlencoded")
{
url = url ?? req.Form["url"];
html = html ?? req.Form["html"];
base_url = base_url ?? req.Form["base_url"];
page_size = page_size ?? req.Form["page_size"];
page_orientation = page_orientation ?? req.Form["page_orientation"];
web_page_width_str = web_page_width_str ?? req.Form["web_page_width"];
web_page_height_str = web_page_height_str ?? req.Form["web_page_height"];
}
// read from POST if encoding is application/json
else if (req.ContentType?.ToLower() == "application/json")
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic postData = JsonConvert.DeserializeObject(requestBody);
url = url ?? postData?.url;
html = html ?? postData?.html;
base_url = base_url ?? postData?.base_url;
page_size = page_size ?? postData?.page_size;
page_orientation = page_orientation ?? postData?.page_orientation;
web_page_width_str = web_page_width_str ?? postData?.web_page_width;
web_page_height_str = web_page_height_str ?? postData?.web_page_height;
}
// parse parameters
log.LogInformation("Parsed url: " + url?.ToString());
log.LogInformation("Parsed html: " + html?.ToString());
log.LogInformation("Parsed base_url: " + base_url?.ToString());
int web_page_width = 1024;
if (!string.IsNullOrEmpty(web_page_width_str))
{
try
{
web_page_width = Convert.ToInt32(web_page_width_str);
}
catch { }
}
log.LogInformation("Parsed web_page_width: " + web_page_width);
int web_page_height = 0;
if (!string.IsNullOrEmpty(web_page_height_str))
{
try
{
web_page_height = Convert.ToInt32(web_page_height_str);
}
catch { }
}
log.LogInformation("Parsed web_page_height: " + web_page_height);
// pdf page size
PdfPageSize pageSize = PdfPageSize.A4;
try
{
pageSize = (PdfPageSize)Enum.Parse(typeof(PdfPageSize), page_size, true);
}
catch { }
log.LogInformation("Parsed page_size: " + pageSize.ToString());
// pdf orientation
PdfPageOrientation pdfOrientation = PdfPageOrientation.Portrait;
try
{
pdfOrientation = (PdfPageOrientation)Enum.Parse(
typeof(PdfPageOrientation), page_orientation, true);
}
catch { }
log.LogInformation("Parsed page_orientation: " + pdfOrientation.ToString());
// check for mandatory parameters
if (string.IsNullOrEmpty(url) && string.IsNullOrEmpty(html))
{
string responseMessage = "Url or html string not specified.";
return new BadRequestObjectResult(responseMessage);
}
// instantiate converter object
SelectPdf.HtmlToPdf converter = new SelectPdf.HtmlToPdf();
// set converter options
converter.Options.WebPageWidth = web_page_width;
converter.Options.WebPageHeight = web_page_height;
converter.Options.PdfPageSize = pageSize;
converter.Options.PdfPageOrientation = pdfOrientation;
SelectPdf.PdfDocument doc;
// convert url or html string to pdf
if (!string.IsNullOrEmpty(url))
{
doc = converter.ConvertUrl(url);
}
else
{
doc = converter.ConvertHtmlString(html, base_url);
}
// save pdf
byte[] pdf = doc.Save();
doc.Close();
log.LogInformation("Conversion finished. Returning file...");
return new FileContentResult(pdf, "application/pdf")
{
FileDownloadName = "Document.pdf"
};
}
catch (Exception ex)
{
string responseMessage = "An error occured: " +
ex.Message + "\r\n" + ex.StackTrace;
return new BadRequestObjectResult(responseMessage);
}
}
}
}
For more details about our html to pdf converter or any other feature related to our pdf library for .NET, do not hesitate to contact us.
