0

Is it possible to get the HTML source code of a server-side Blazor component/page? For example, to generate a PDF for any given Blazor page, I would need it's entire HTML source code rendered. Since it's SPA, each individual page does not really have any visible HTML source code ... Thanks!

2
  • What’s the reason that something like window.print() doesn’t work for your use case? Commented Feb 1, 2021 at 3:36
  • I need to generate the PDF and save it somewhere, not just for user to print it out. Commented Feb 3, 2021 at 14:31

1 Answer 1

1

It is not necessary to get all the html source code. Syncfusion Essential PDF is a .NET Core PDF library can help you create, read, and edit PDF documents in Blazor.

  1. Install the NuGet package: Syncfusion.PDF.Net.Core

  2. Create a new cs file named ExportService under Data folder and include the following namespaces in the file.

    using Syncfusion.Pdf;
    using Syncfusion.Pdf.Graphics;
    using Syncfusion.Pdf.Grid;
    using Syncfusion.Drawing;
    
  3. Add the following method in the ExportService class.

    //Export weather data to PDF document.
    public MemoryStream CreatePdf(WeatherForecast[] forecasts)
    {
      if (forecasts == null)
      {
        throw new ArgumentNullException("Forecast cannot be null");
     }
    //Create a new PDF document
    using (PdfDocument pdfDocument = new PdfDocument())
    {
    
     int paragraphAfterSpacing = 8;
     int cellMargin = 8;
    
     //Add page to the PDF document
     PdfPage page = pdfDocument.Pages.Add();
    
     //Create a new font
     PdfStandardFont font = new PdfStandardFont(PdfFontFamily.TimesRoman, 16);
    
     //Create a text element to draw a text in PDF page
     PdfTextElement title = new PdfTextElement("Weather Forecast", font, PdfBrushes.Black);
     PdfLayoutResult result = title.Draw(page, new PointF(0, 0));
    
    
     PdfStandardFont contentFont = new PdfStandardFont(PdfFontFamily.TimesRoman, 12);
     PdfTextElement content = new PdfTextElement("component generate the pdf", contentFont, PdfBrushes.Black);
     PdfLayoutFormat format = new PdfLayoutFormat();
     format.Layout = PdfLayoutType.Paginate;
    
     //Draw a text to the PDF document
     result = content.Draw(page, new RectangleF(0, result.Bounds.Bottom + paragraphAfterSpacing, page.GetClientSize().Width, page.GetClientSize().Height), format);
    
     //Create a PdfGrid
     PdfGrid pdfGrid = new PdfGrid();
     pdfGrid.Style.CellPadding.Left = cellMargin;
     pdfGrid.Style.CellPadding.Right = cellMargin;
    
     //Applying built-in style to the PDF grid
     pdfGrid.ApplyBuiltinStyle(PdfGridBuiltinStyle.GridTable4Accent1);
    
     //Assign data source
     pdfGrid.DataSource = forecasts;
    
     pdfGrid.Style.Font = contentFont;
    
     //Draw PDF grid into the PDF page
     pdfGrid.Draw(page, new Syncfusion.Drawing.PointF(0, result.Bounds.Bottom + paragraphAfterSpacing));
    
     using (MemoryStream stream = new MemoryStream())
     {
         //Saving the PDF document into the stream
         pdfDocument.Save(stream);
         //Closing the PDF document
         pdfDocument.Close(true);
         return stream;
    
      }
     }
    }
    
  4. Register your service in the ConfigureServices.

    public void ConfigureServices(IServiceCollection services)
    {
        //...
        services.AddSingleton<ExportService>();
    }
    
  5. Inject ExportService into FetchData.razor.

    @inject ExportService exportService
    @inject Microsoft.JSInterop.IJSRuntime JS
    @using System.IO
    
  6. In this component, give one button.

    <button class="btn btn-primary" @onclick="@ExportToPdf">Export to PDF</button>
    
  7. Add this method in FetchData.razor.

    @functions
    {
    
     protected async Task ExportToPdf()
     {
       using (MemoryStream excelStream = exportService.CreatePdf(forecasts))
       {
         await JS.SaveAs("Sample.pdf", excelStream.ToArray());
        }
      }
    }
    
  8. Create the static class.

    public static class FileUtil
    {
       public static ValueTask<object> SaveAs(this IJSRuntime js, string filename, byte[] data)
    => js.InvokeAsync<object>(
        "saveAsFile",
        filename,
        Convert.ToBase64String(data));
     }
    
  9. Add the following JavaScript function in the _Host.cshtml.

     <script type="text/javascript">
       function saveAsFile(filename, bytesBase64) {
         if (navigator.msSaveBlob) {
             //Download document in Edge browser
             var data = window.atob(bytesBase64);
             var bytes = new Uint8Array(data.length);
             for (var i = 0; i < data.length; i++) {
                 bytes[i] = data.charCodeAt(i);
             }
             var blob = new Blob([bytes.buffer], { type: "application/octet-stream" });
             navigator.msSaveBlob(blob, filename);
         }
         else {
             var link = document.createElement('a');
             link.download = filename;
             link.href = "data:application/octet-stream;base64," + bytesBase64;
             document.body.appendChild(link); // Needed for Firefox
             link.click();
             document.body.removeChild(link);
         }
        }
      </script>
    

Last, you can get the genereated pdf.

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

You only need to add this NuGet package: Syncfusion.PDF.Net.Core, it does not require a license.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.