Thursday, September 1, 2022

Convert Html to Pdf in azure function and save in blob container

 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/fnHtmlToPdf

open 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

No comments:

Post a Comment

Thanks for your valuable comments

Convert Html to Pdf in azure function and save in blob container

 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 bl...