2

I am trying to generate a PDF via Azure function using DinkToPdf. This what I have done so far.

[FunctionName("GeneratePdf")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log,
    ExecutionContext executionContext)
{
    string name = await GetName(req);
    return CreatePdf(name, executionContext);
}

private static ActionResult CreatePdf(string name, ExecutionContext executionContext)
{
    var globalSettings = new GlobalSettings
    {
        ColorMode = ColorMode.Color,
        Orientation = Orientation.Portrait,
        PaperSize = PaperKind.A4,
        Margins = new MarginSettings { Top = 10 },
    };
    var objectSettings = new ObjectSettings
    {
        PagesCount = true,
        WebSettings = { DefaultEncoding = "utf-8" },
        HtmlContent = $@"
               <!DOCTYPE html>
               <html>
               <head>
                   <meta charset="utf-8" />
                   <title></title>
                   <meta name="viewport" content="width=device-width, initial-scale=1">
               </head>
               <body>
                  Hello, ${name}
               </body>
               </html>",
     };

     var pdf = new HtmlToPdfDocument()
     {
        GlobalSettings = globalSettings,
        Objects = { objectSettings }
     };

     byte[] pdfBytes = IocContainer.Resolve<IConverter>().Convert(pdf);
     return new FileContentResult(pdfBytes, "application/pdf");
}

This is working pretty good, when I am testing the function on local. However, it is not working as expected when deployed to Azure.

The primary problem is that in the places of the texts in the pdf, boxes are appearing (see below for example). enter image description here

Moreover the response is also excruciatingly slow. Is there a way to improve/correct this?

Additional Info:

  1. I am also using unity IOC to resolve IConverter. The type registration looks something like below:

    var container = new UnityContainer();
    container.RegisterType<IConverter>(
        new ContainerControlledLifetimeManager(),
        new InjectionFactory(c => new SynchronizedConverter(new PdfTools()))
    );
    
  2. I have tried couple of other NuGet packages such as PdfSharp, MigraDoc, Select.HtmlToPdf.NetCore, etc. But alll of those have dependency on System.Drawing.Common, which is not usable in Azure function.

Sayan Pal
  • 4,768
  • 5
  • 43
  • 82
  • 2
    First thing that comes to mind when I see the render is you're either missing a font in the Azure environment, or the encoding doesn't play nice. – rickvdbosch Nov 07 '18 at 11:33
  • @rickvdbosch That's what I thought as well, and then added the `WebSettings = { DefaultEncoding = "utf-8" }` part, but it too didn't help :( – Sayan Pal Nov 07 '18 at 11:36
  • @rickvdbosch Additionally, I am not using any custom fonts. In that case, I assume that the default fonts and encoding (`utf-8`, as specified) should be used as fallback. Or, is that not the case? – Sayan Pal Nov 07 '18 at 11:46
  • I am also thinking about the font problem. Here is an open feature request that seems quite related to your problem : https://feedback.azure.com/forums/169385-web-apps/suggestions/32622797-support-custom-web-fonts-in-azure-app-services . Maybe you can try to force a font (that is not "webfont" somehow, let's start with a "Times New Roman" for instance) – Pac0 Nov 07 '18 at 11:47
  • maybe useful : https://stackoverflow.com/questions/10611828/use-custom-fonts-with-wkhtmltopdf – Pac0 Nov 07 '18 at 11:51
  • 1
    @Pac0 Thanlk you for comment. Following your suggestion, I tried both setting a font-family explicitly (`font-family: 'Times New Roman', Times, serif;`), as well as including an external font like ``. But none of those worked. – Sayan Pal Nov 07 '18 at 13:05

1 Answers1

4

The issue appears to be related to the restrictions of the Azure Function in "Consumption" mode. If you use "App Mode", it should work. See the discussion below this Gist for some users who had success converting their Azure Function to "App Mode".

lafe
  • 111
  • 1
  • 2