0
votes

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!

1
What’s the reason that something like window.print() doesn’t work for your use case?Ben Sampica
I need to generate the PDF and save it somewhere, not just for user to print it out.Franky

1 Answers

1
votes

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