Skip to content

This repository contains the examples of generating dynamic PDF reports from an HTML template using the Syncfusion's .NET HTML to PDF library. Syncfusion's .NET HTML to PDF library is used to converting webpages, SVG, MHTML, and HTML files to PDF as similar like in Browser using C#.

Notifications You must be signed in to change notification settings

SyncfusionExamples/generate-pdf-from-html-csharp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Generate PDF documents from dynamic HTML using Syncfusion PDF generator API

The Syncfusion HTML-to-PDF converter library in combination with ASP.NET Core Minimal Web API offers a simple and straightforward approach for dynamically generating PDFs from HTML templates.

In this repository, we will learn how to create an ASP.NET Core Minimal Web API that dynamically generates a PDF document from an HTML template using Syncfusion HTML-to-PDF converter library.

Steps to create job offer letter from HTML template using ASP.NET Core Minimal Web API

  1. Create HTML template with CSS styling
  2. Create a minimal Web API project with ASP.NET Core (Server application)
  3. Create Blazor WASM with .NET 7 (Client application)
  4. Launching the Server and Invoking the Web API from the Client

Create HTML template with CSS styling

In HTML file, define the structure of your page, including the head and body sections, any other elements you'd like to include, such as image, header, footer, etc.

Also, it contains placeholders with {{mustache}} syntax and it is used to bind the actual data to the HTML template. For this example, we'll use the Scriban scripting language to create the placeholders. It's a lightweight scripting language and engine for .NET.

N> To learn more about the Scriban scripting language, refer to the documentation.

index.html

<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>JobOfferLetter</title>
    <link rel="stylesheet" href="style.css" media="all" />
</head>

<body>
    <div class="grid-container ">
        <img class="logo" src="logo.png" style="width:70px;height:70px;margin-left: 50px;" />
        <div style="margin-left:70px; margin-top:55px">
            <b>
                AMAZE <br />
                FOX
            </b>
        </div>
        <div style="font-size: 12px; margin-left: 300px; margin-top: 55px">
            <div><b>{{company_details.street}} </b></div>
            <div><b>{{company_details.city}} </b></div>
            <div><b>Phone: {{company_details.phone}} </b></div>
            <div><b>{{company_details.website}} </b></div>
        </div>
    </div>
    <br />
    <div class="body-content" style="margin-left: 50px;">
        <p><b>Dear {{employee_details.name}},</b></p>
        <p>We are pleased to offer you the position of Accountant at {{company_details.company_name}}. We feel confident that you will contribute your skills and experience towards the growth of our organization.</p>
        <p>As per the discussion, your starting date will be {{employee_details.joining_date}}. Please find the employee handbook enclosed herewith which contains the medical and retirement benefits offered by our organizations.</p>
        <p>Please confirm your acceptance of this offer by signing and returning a copy of this offer letter.</p>
        <p>If you have any questions regarding the same, contact the manager or me via email or phone: {{company_details.phone}}</p>
        <p>We look forward to welcoming you on board.</p>
    </div>

    <div class="body-content" style="margin-left: 50px;">
        <p><b>Sincerely,<br /> {{company_details.company_name}} <br />{{company_details.employer_name}} <br />(Managing Director)</b></p>
    </div>

    <div id="footer">
        <div class="footer-columns" style="margin-left: 50px;">
            <p>{{company_details.company_name}}</p>
            <p>{{company_details.website}}</p>
        </div>
    </div>
</body>
</html>

By default, the properties and methods of .NET objects are automatically exposed with lowercase and _ names. This means that a property like CompanyName will be exposed as company_name.name and while performing the conversion, the values can be imported from respective JSON file.

Job offer letter JSON data

CSS Styling

Create CSS file to control the appearance of your HTML template. In this CSS file, you'll define styles for your page elements, such as font sizes, colors, and images.

You can get this HTML template with CSS and fonts from this location.

style.css

@font-face {
    font-family: "OpenSans";
    src: url("OpenSans-Regular.ttf");
}

.grid-container {
    display: grid;
    grid-template-columns: 60px auto auto;
    padding: 10px;
    background-color: darkblue;
    font-size: 25px;
    text-align: left;
    font-family: OpenSans;
    color: white;
    height: 170px;
}

.body-content {
    font-size: 16px;
    font-family: OpenSans;
    padding: 20px;
    padding-right: 2.5rem;
    text-align: left;
}

.logo {
    margin-top: 50px;
}

#footer {
    font-size: 12px;
    font-family: OpenSans;
    text-align: left;
    font-weight: 500;
    color: white;
    margin-top: 0.5rem;
    bottom: 0.5rem;
    position: absolute;
    width: 100%;
    background-color: darkblue;
}

.footer-columns {
    display: flex;
    justify-content: space-between;
    padding-left: 1.5rem;
    padding-right: 2.5rem;
}

The following screenshot shows the output of the HTML template with styled CSS. Job offer letter HTML Template

Furthermore, any additional resources such as fonts, images, JSON files, etc. should be located in the same folder as the HTML file. Please refer to the screenshot below for visual reference. Job offer letter folder structure

Create a minimal Web API project with ASP.NET Core

Minimal APIs are architected to create HTTP APIs with minimal dependencies. They are ideal for microservices and apps that want to include only the minimum files, features, and dependencies in ASP.NET Core. Kindly refer the below link to create the project in Visual Studio 2022. Steps to create minimal API project with ASP.NET Core 7.0

Within this Web API application, the Program.cs file employs the StreamReader class to transform the HTML and JSON files, supplied by the client's request, into textual format. Subsequently, combining the HTML text with the required assets via the CopyAssets() method.

app.MapPost("/api/convertToPDF", async (HttpContext context) =>
{
    try
    {
        var html = await context.Request.ReadFormAsync();
        var value = html.AsQueryable().ToList().Where(x => x.Key == "application/json").FirstOrDefault().Value.ToString();
        var options = JsonConvert.DeserializeObject<ConversionOptions>(value);

        string htmlText = "";
        string jsonData = "";
        if (options != null)
        {
            htmlText = ReadText(html.Files[options.Index].OpenReadStream());
            jsonData = ReadText(html.Files[options.Data].OpenReadStream());
            CopyAssets(options.Assets, html.Files);
        }


        String path = Path.GetFullPath("template/");

        var conversion = new HtmlToPdfConversion();
        var pdf = conversion.ConvertToPDF(htmlText, path, jsonData, options);

        context.Response.ContentType = "application/pdf";
        await context.Response.Body.WriteAsync(pdf);
    }
    catch (Exception exception)
    {

    }
});

app.UseCors("AllowBlazorClient");
app.Run();

void CopyAssets(List<string> assets, IFormFileCollection files)
{
    if (Directory.Exists("template/"))
    {
        System.IO.DirectoryInfo di = new DirectoryInfo("template/");

        foreach (FileInfo file in di.GetFiles())
        {
            file.Delete();
        }
    }
    else
        Directory.CreateDirectory("template/");

    var formFiles = files.ToList();
    foreach (var asset in assets)
    {
        Stream stream = formFiles.FirstOrDefault(x => x.FileName == asset).OpenReadStream();
        if (stream != null)
        {
            var fileStream = new FileStream("template/" + asset, FileMode.Create);
            stream.CopyTo(fileStream);
            fileStream.Close();
            stream.Close();
        }
    }
}
string ReadText(Stream strem)
{
    StreamReader reader = new StreamReader(strem);
    string text = reader.ReadToEnd();
    reader.Close();
    strem.Dispose();

    return text;
}

Next, the HtmlToPdfConverter is utilized to turn the HTML string, accompanied by the assets, into a PDF document via the blink rendering engine within the HtmlToPdfConversion.cs file. During this conversion, we have established the size and margin of the PDF page and the viewport size using the BlinkConverterSettings class. Please refer to the accompanying code example for further information.

var expando = JsonConvert.DeserializeObject<ExpandoObject>(modelData);
var sObject = BuildScriptObject(expando);
var templateCtx = new Scriban.TemplateContext();
templateCtx.PushGlobal(sObject);
var template = Scriban.Template.Parse(pageContent);
var result = template.Render(templateCtx);

//Initialize HTML to PDF converter with Blink rendering engine
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter();
BlinkConverterSettings blinkConverterSettings = new BlinkConverterSettings();
if (options.Width != 0 && options.Height != 0)
{
    blinkConverterSettings.PdfPageSize = new Syncfusion.Drawing.SizeF(options.Width, options.Height);
}
else
{
    blinkConverterSettings.ViewPortSize= new Syncfusion.Drawing.Size(595, 842);
}
blinkConverterSettings.Margin = new PdfMargins() { All = options.Margin };
htmlConverter.ConverterSettings = blinkConverterSettings;
//Convert HTML string to PDF
PdfDocument document = htmlConverter.Convert(result, path);

//Save and close the PDF document 
MemoryStream output = new MemoryStream();
document.Save(output);
document.Close(true);

Create Blazor WASM application (client)

The client application in this implementation is a Blazor WASM application built with .NET version 7.0. To create a new ASP.NET Core Blazor WebAssembly application using Visual Studio 2022, please follow the guidance provided in this link. Within the application, we utilize the HttpClient.PostAsync method to send a POST request to the specified URI as an asynchronous operation.

//Send request to server 
var response = await client.PostAsync("https://localhost:7045/api/convertToPDF", content); 

Incorporating HTML files and additional assets

The inclusion of the HTML and CSS files in the HttpClient is necessary. Additionally, any supplementary assets such as fonts, images, and PDF size specifications should be sent along with the request using the MultipartFormDataContent.

private async Task ConvertToPDF()
{
    //Create http client to send both files and json data
    using (var client = new HttpClient())
    {
            //Create multipart form data content
            using (var content = new MultipartFormDataContent())
            {
                var html = await Http.GetByteArrayAsync("JobOfferLetter/index.html");
                var css = await Http.GetByteArrayAsync("JobOfferLetter/style.css");
                var data = await Http.GetByteArrayAsync("JobOfferLetter/Data.json");
                var logo = await Http.GetByteArrayAsync("JobOfferLetter/logo.png");
                var font = await Http.GetByteArrayAsync("JobOfferLetter/OpenSans-Regular.ttf");

                //Add file to content
                content.Add(CreateContent("index.html", "index.html", html));
                content.Add(CreateContent("style.css", "style.css", css));
                content.Add(CreateContent("Data.json", "Data.json", data));
                content.Add(CreateContent("logo.png", "logo.png", logo));
                content.Add(CreateContent("OpenSans-Regular.ttf", "OpenSans-Regular.ttf", font));
                var json = new JsonObject
                {
                        ["index"] = "index.html",
                        ["data"] = "Data.json",
                        ["width"] = 0,
                        ["height"] = 0,
                        ["margin"] = 40,
                        ["assets"] = new JsonArray
                        {
                          "style.css",
                          "logo.png",
                          "OpenSans-Regular.ttf"
                        }
                };
                //Add json data to content
                content.Add(new StringContent(json.ToString()), "application/json");
                //Send request to server
                var response = await client.PostAsync("https://localhost:7045/api/convertToPDF", content);
                if (response.StatusCode == HttpStatusCode.OK)
               {
                var responseContent = await response.Content.ReadAsStreamAsync();
                using var Content = new DotNetStreamReference(stream: responseContent);
                await JS.InvokeVoidAsync("SubmitHTML", "HTMLToPDF.pdf", Content);
               }
        }
    }
}

Once the requested response status code is OK, then invoke the JavaScript (JS) function in index.html file to save the PDF document.

<script>
    window.SubmitHTML = async (fileName, contentStreamReference) => {
        const arrayBuffer = await contentStreamReference.arrayBuffer();
        const blob = new Blob([arrayBuffer]);
        const url = URL.createObjectURL(blob);
        const anchorElement = document.createElement('a');
        anchorElement.href = url;
        anchorElement.download = fileName ?? '';
        anchorElement.click();
        anchorElement.remove();
        URL.revokeObjectURL(url);
    }
</script>

While building and running the application, the website will open in your default browser. Blazor UI

Launching the Server and Invoking the PDF Generation API from the Client

Here are the steps to launching the server and invoking the PDF generation API from the client application.

Step 1: Run the Web API application, which will launch the published web API in the browser.

Step 2: To generate a PDF document using the client application, send an asynchronous POST request to the specified URI (e.g., https://localhost:7094/api/convertToPDF) on the localhost. This will send the request to the server application, which will convert the HTML to PDF and send the response back to the client. After running the client application, click the "Convert to PDF" button, which will initiate the HTML to PDF conversion process and generate a PDF document named "HTMLToPDF.pdf" in the designated folder.
Blazor UI

Upon successful conversion, you will receive a PDF document as illustrated in the following screenshot.
Job offer letter output

Sample Templates

Template Name HTML Template Description
Invoice Invoice HTML Template An invoice is a commercial document issued by a seller to a buyer relating to a sale transaction and indicating the products, quantities, and agreed-upon prices for products or services the seller had provided the buyer.
BoardingPass BoardingPass HTML Template A boarding pass is a document provided by an airline during check-in, giving a passenger permission to board the airplane for a particular flight.
Lease Agreement LeaseAgreement HTML Template A rental agreement is a contract of rental, usually written, between the owner of a property and a renter who desires to have temporary possession of the property.
EmployeeCertificate Certificate of appreciation HTML Template This certificate is one of the way to say thank you to the employees who work in their organization.
HospitalDischarge Certificate of appreciation HTML Template This hospital discharge template captures the medical information related to patient during the stay in the hospital.
JobOfferLetter JobOfferLetter HTML Template Job offer letter refers to an official document employer gives to an employee in order to provide them with an offer of employment.
PatientMedicalRecord JobOfferLetter HTML Template The patient medical records are used to describe the systematic documentation of a single patient's medical history.

Resources

Support and feedback

License

This is a commercial product and requires a paid license for possession or use. Syncfusion’s licensed software, including this component, is subject to the terms and conditions of Syncfusion's EULA. You can purchase a licnense here or start a free 30-day trial here.

About Syncfusion

Founded in 2001 and headquartered in Research Triangle Park, N.C., Syncfusion has more than 26,000+ customers and more than 1 million users, including large financial institutions, Fortune 500 companies, and global IT consultancies.

Today, we provide 1600+ components and frameworks for web (Blazor, ASP.NET Core, ASP.NET MVC, ASP.NET WebForms, JavaScript, Angular, React, Vue, and Flutter), mobile (Xamarin, Flutter, UWP, and JavaScript), and desktop development (WinForms, WPF, WinUI(Preview), Flutter and UWP). We provide ready-to-deploy enterprise software for dashboards, reports, data integration, and big data processing. Many customers have saved millions in licensing fees by deploying our software.

About

This repository contains the examples of generating dynamic PDF reports from an HTML template using the Syncfusion's .NET HTML to PDF library. Syncfusion's .NET HTML to PDF library is used to converting webpages, SVG, MHTML, and HTML files to PDF as similar like in Browser using C#.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages