Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Razor view Engine in Blazor (Convert blazor component to html string at run-time)

I'm trying to get the generate the pdf in server-side Blazor. I use DinkToPdf as an external library to convert HTML string to pdf. But I'm having trouble of converting the blazor component to HTML string.

There is a way to render Razor templates to a string by using the Razor ViewEngine. From this web http://fizzylogic.nl/2017/08/03/how-to-generate-pdf-documents-in-asp-net-core/

[HttpGet]
public async Task<IActionResult> CreatePDF()
{
    var globalSettings = new GlobalSettings
    {
        ColorMode = ColorMode.Color,
        Orientation = Orientation.Portrait,
        PaperSize = PaperKind.A4,
        Margins = new MarginSettings { Top = 10 },
        DocumentTitle = "PDF Report",
    };

    var objectSettings = new ObjectSettings
    {
        PagesCount = true,
        HtmlContent = "<h>Hello World</h>",
        WebSettings = { DefaultEncoding = "utf-8"},
        HeaderSettings = { FontName = "Arial", FontSize = 9, Right = "Page [page] of [toPage]", Line = true },
        FooterSettings = { FontName = "Arial", FontSize = 9, Line = true, Center = "Report Footer" }
    };

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

    var file = _converter.Convert(pdf);
    return File(file,"application/pdf");
}

I need to modify the ObjectSettings.HtmlContent to be my blazor component html string.

like image 258
user489566 Avatar asked Feb 08 '19 14:02

user489566


1 Answers

Are you trying to convert content the user can see? If so, you could add @ref='ContentToRender' to the component you want to render, Blazor will then assign that reference after the component is rendered:

@inject IJSRuntime JSRuntime

<div @ref=ContentToRender>
  ... Your content here...
</div>

@code {
  ElementReference ContentToRender;

  protected async override Task OnAfterRenderAsync(bool firstRender) 
  {
    if (firstRender) 
    {
      string html = await JSRuntime.InvokeAsync<string>("BlazorUniversity.getInnerHTML", ContentToRender);
    }
  };
}

Where the JS would look something like this

var BlazorUniversity = BlazorUniversity || {};
BlazorUniversity.getInnerHTML = function(element) {
  return element.innerHTML;
};

Don't forget to include the JS in your main index.html or _Host.cshtml page.

For more info see Passing HTML Element References on Blazor University.

Note that you will not be able to access the content until at least after the first render event (firstRender == true).

like image 187
Peter Morris Avatar answered Oct 19 '22 22:10

Peter Morris