In this post I am going to create an azure function (httpTrigger) and send html content which will be converted into PDF and save in blob container.
Steps ;
Create Blob Container
Go to azure portal ->Storage->Container (from Left Menu)->Click on + button and enter "firstcontainer" in container name. Name should be in lowercase.
From Left menu click on Access Keys and copy connection string in your local file somewhere.
Create Azure function to Convert Html To PDF
Open Visual studio and create new project for azure function -> HttpTrigger
enter project name "azfuntionhtmltopdf"
Nuget Packages : make sure you have these packages . Here I am using DinkToPdf to convert html to pdf. you can use other library also.
Add class Startup.cs in root folder. and paste below code using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using azfuntionhtmltopdf.Services;
using azfuntionhtmltopdf;
using DinkToPdf.Contracts;
using DinkToPdf;
[assembly: FunctionsStartup(typeof(Startup))]
namespace azfuntionhtmltopdf
{
public class Startup: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IDocumentConverter, DocumentConverter>();
// these are required if you are using DinkToPdf ,otherwise just remove this.
builder.Services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
var architectureFolder = (IntPtr.Size == 8) ? "64 bit" : "32 bit";
var wkHtmlToPdfPath = Path.Combine(Environment.CurrentDirectory, $"wkhtmltox\\v0.12.4\\{architectureFolder}\\libwkhtmltox");
CustomAssemblyLoadContext context = new CustomAssemblyLoadContext();
context.LoadUnmanagedLibrary(wkHtmlToPdfPath);
//dinktopdf
}
}
}
Create one folder named services and add below classes
CustomeAssemblyLoadContext -- if you are using some other library for html to pdf then this might not be required .
using System;
using System.Runtime.Loader;
namespace azfuntionhtmltopdf.Services
{
public class CustomAssemblyLoadContext : AssemblyLoadContext
{
public IntPtr LoadUnmanagedLibrary(string absolutePath)
{
return LoadUnmanagedDll(absolutePath);
}
protected override IntPtr LoadUnmanagedDll(String unmanagedDllName)
{
return LoadUnmanagedDllFromPath(unmanagedDllName);
}
}
}
DocumentConverter.cs
using Azure.Storage.Blobs;
using DinkToPdf;
using DinkToPdf.Contracts;
using System;
using System.IO;
namespace azfuntionhtmltopdf.Services
{
public class DocumentConverter: IDocumentConverter
{
private IConverter _converter;
public DocumentConverter(IConverter converter)
{
_converter = converter;
}
public void CreateAndSaveInBlob(string htmlString, string documentTitle)
{
try
{
string connString = "stroage connection string";
string blobName = "firstcontainer";
var bytePdf = PDFByte(htmlString, documentTitle);
BlobServiceClient blobServiceClient = new BlobServiceClient(connString);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(blobName);
blobContainerClient.CreateIfNotExists();
using (MemoryStream stream = new MemoryStream(bytePdf))
{
blobContainerClient.UploadBlob(documentTitle, stream);
}
}
catch (Exception ex)
{
throw ex;
}
}
private byte[] PDFByte(string htmlString,string documentTitle)
{
try
{
var globalSettings = new GlobalSettings
{
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
Margins = new MarginSettings { Top = 10 },
DocumentTitle = documentTitle,
};
var objectSettings = new ObjectSettings
{
PagesCount = true,
HtmlContent = htmlString,
// WebSettings = { DefaultEncoding = "utf-8", UserStyleSheet = Path.Combine(Environment.CurrentDirectory, "css", "site.css") }, //pass your css file link if needed
// HeaderSettings = { FontName = "Calibri", FontSize = 9, Right = $"Page [page] of [toPage] {header}", Line = true, Spacing = 1.5 }, //header setting
// FooterSettings = { FontName = "Calibri", FontSize = 9, Line = true, Center = "center content", Right = DateTime.Now.ToString("dd/MM/yyyy hh:mm a") } //footer seeting
};
return _converter.Convert(new HtmlToPdfDocument()
{
GlobalSettings = globalSettings,
Objects = { objectSettings }
});
}
catch (Exception ex)
{
throw ex;
}
}
}
}
Add interface IDocumentConverter.cs
namespace azfuntionhtmltopdf.Services
{
public interface IDocumentConverter
{
void CreateAndSaveInBlob(string htmlString, string documentTitle);
}
}
Model.cs -- to get request body data
namespace azfuntionhtmltopdf.Services
{
public class Models
{
public string HtmlString { get; set; }
public string FileName { get; set; }
}
}
Now update your default created Function1.cs class as below :
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;
using azfuntionhtmltopdf.Services;
namespace azfuntionhtmltopdf
{
public class Function1
{
private readonly IDocumentConverter _docConverter;
public Function1(IDocumentConverter docConverter)
{
_docConverter = docConverter;
}
[FunctionName("fnHtmlToPdf")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var data = JsonConvert.DeserializeObject<Models>(requestBody);
_docConverter.CreateAndSaveInBlob(data.HtmlString,data.FileName);
//you can handle error here
return new OkObjectResult("pdf created");
}
}
}
That's It . We are done with coding part. now run the project and copy the url as below
url will be someting :http://localhost:7071/api/fnHtmlToPdfopen postman to test azure function :
After executing function if all works then your pdf file would be saved in storage.
you can download all the azure samples code : https://github.com/mkumar8184/azure-sdk-services-samples