How to Create PDF Invoice using PDF and HTML Templates in C#

This article demonstrates how to create PDF invoices from HTML templates using PDF.CO Web API in the C# programming language.

The article also explains how to pass data to placeholders in HTML templates and create a PDF invoice that contains the data that you passed to placeholders.

The article has two main parts:

  1. In the first part, you will see how you can generate HTML templates that contain placeholders. You will be using the PDF.co web application to create an HTML template.
  2. The second part of this article explains how to create a PDF invoice using the template that you created in the first part, using the PDF.co Web API. In this section, you will create a C# console application that calls the PDF.CO Web API.

Create HTML Templates using PDF.co API

Creating an HTML template containing placeholders with PDF.CO app is a straightforward task. To do so, go to the following link:

https://app.pdf.co/templates/html

First, you will need to login into the PDF.CO website. After logging in to the website, you will see some default HTML templates, as shown in the following screenshot.

HTML Template

You can use the default HTML invoice templates or you can create your own custom template.

To create your own custom template, click the “click new template” button at the top-right corner of your screen. You can write your HTML code from scratch including and can also include placeholders. The PDF.CO APP uses Mustache, and Handlebars macros for creating placeholders. The other option is to copy and paste the HTML code from one of the built-in templates and edit it as per your requirements.

For example, if you open the HTML template with ID 1, you should see HTML code with some placeholder values inside the opening and closing double braces e.g. {{invoice_id}} {{client_name}} etc. These placeholder values are filled using the PDF.CO Web API while creating your PDF invoice.

You can add or remove HTML code as well as placeholders from any of the default templates to fit your needs.

In this article, we will initially be using the default HTML template with the ID 1 to create a PDF invoice. This template contains sample invoice data. After that, we will make a slight change in the template and see its effect on the generated PDF invoice.

Let’s first create a PDF invoice using the default HTML template with ID 1.

Create PDF using HTML Template with Placeholders

Create a C# console application with one class and the Main method as a starting point.

The following script imports the required libraries:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

The Microsoft .NET frame contains all the above packages by default except the “Newtonsoft” library. To install this library from Microsoft Visual Studio ID, go to “Tools-> NuGet Package Manager”. Search for “Newtonsoft” library. You will see the following packages. Select the first package and click the “Install” button.

Newtonsoft.Json Library

The next step is to define variables that store the PDF.CO Web API key, and the destination path for the PDF file that will be created using the HTML template. Here is the script for that.

const String API_KEY = "*****************************";
const string DestinationFile = @".\newDocument.pdf";

Note: You can get your API key by signing up at https://app.pdf.co/signup

The rest of the script is executed inside the Main method of your C# application.

The next step is to create a C# WebClient object that will connect with the PDF.CO Web API.

WebClient webClient = new WebClient();
webClient.Headers.Add("x-api-key", API_KEY);

After that, we will define the variable that stores the API call which creates the PDF invoice using the HTML template. The following script defines the API call.

string url = "https://api.pdf.co/v1/pdf/convert/from/html";

Finally, we will create the parameter dictionary that contains values that will be passed along with the API call.

The parameter dictionary specifies the template ID for the HTML template that will be used to create a PDF invoice. The other important parameters are “name” and “templateData”.

The “name” parameter contains the destination path for the PDF.

The “templateData” parameter contains a JSON dictionary in the form of C# string. This dictionary is used to fill data in the placeholders of the HTML template.

For instance, in the following script, the HTML template with ID 1 has placeholders {{paid}} and {{invoice_id}}. In the templateData parameter dictionary, you can see “True” and “0021” as values for the {{paid}} and {{invoice_id}} placeholders, respectively. Here backslashes \” are used to escape the double quotations in a C# string. The parameter dictionary is serialized before it can be passed via an API call.

Dictionary<string, object> parameters = new Dictionary<string, object>();
           parameters.Add("templateId", 1);
           parameters.Add("name", Path.GetFileName(DestinationFile));
           parameters.Add("margins", "40px 20px 20px 20px");
           parameters.Add("paperSize", "Letter");
           parameters.Add("orientation", "Portrait");
           parameters.Add("header", "");
           parameters.Add("printBackground", true);
           parameters.Add("footer", "");
           parameters.Add("async", false);
           parameters.Add("encrypt", false);
           parameters.Add("templateData", "{\"paid\": true,\"invoice_id\": \"0021\",\"invoice_date\": \"August 29, 2041\",\"invoice_dateDue\": \"September 29, 2041\",\"issuer_name\": \"Sarah Connor\",\"issuer_company\": \"T-800 Research Lab\",\"issuer_address\": \"435 South La Fayette Park Place, Los Angeles, CA 90057\",\"issuer_website\": \"www.example.com\",\"issuer_email\": \"info@example.com\",\"client_name\": \"Cyberdyne Systems\",\"client_company\": \"Cyberdyne Systems\",\"client_address\": \"18144 El Camino Real, Sunnyvale, California\",\"client_email\": \"sales@example.com\",\"items\": [    {    \"name\": \"T-800 Prototype Research\",    \"price\": 1000.00     },   {    \"name\": \"T-800 Cloud Sync Setup\",   \"price\": 300.00     }  ],\"discount\": 100,\"tax\": 87,\"total\": 1287,\"note\": \"Thank you for your support of advanced robotics.\"}"
);

string jsonPayload = JsonConvert.SerializeObject(parameters);

Next, inside the try/catch block, we will pass the serialized parameter dictionary to the “UploadString()” function of the WebClient object, along with the URL string containing the call API call to the PDF.CO Web API.

The API response from the “UploadString()” function is parsed as a JSON object. If the response doesn’t contain any error, the link to the created PDF file is printed on the console, and the PDF file is downloaded.

In case an exception is thrown, the error message is displayed via the “catch” block.

try
           {
                string response = webClient.UploadString(url, jsonPayload);
                JObject json = JObject.Parse(response);
                if (json["error"].ToObject<bool>() == false)
                {
                string resultFileUrl = json["url"].ToString();
                Console.WriteLine(resultFileUrl);
                     webClient.DownloadFile(resultFileUrl, DestinationFile);
                Console.WriteLine("Generated PDF file saved as \"{0}\" file.", DestinationFile);
                }
                else
                {
                     Console.WriteLine(json["message"].ToString());
                }
           }
           catch (WebException e)
           {
                Console.WriteLine(e.ToString());
           }

Finally, the WebClient object is disposed of via the following script:

webClient.Dispose();

Console.WriteLine();
Console.WriteLine("Press any key...");
Console.ReadKey();

The complete code for generating the PDF invoice using the HTML template ID 1 is as follows:

Complete Code

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace ByteScoutWebApiExample
{
class Program
{

const String API_KEY = "usmanmalik57@gmail.com_8df5671cedb0fb37ec9610eada409f110c38";
const string DestinationFile = @".\newDocument.pdf";
static void Main(string[] args)
{

WebClient webClient = new WebClient();
webClient.Headers.Add("x-api-key", API_KEY);

string url = "https://api.pdf.co/v1/pdf/convert/from/html";

Dictionary<string, object> parameters = new Dictionary<string, object>();
parameters.Add("templateId", 1);
parameters.Add("name", Path.GetFileName(DestinationFile));
parameters.Add("margins", "40px 20px 20px 20px");
parameters.Add("paperSize", "Letter");
parameters.Add("orientation", "Portrait");
parameters.Add("header", "");
parameters.Add("printBackground", true);
parameters.Add("footer", "");
parameters.Add("async", false);
parameters.Add("encrypt", false);
parameters.Add("templateData", "{\"paid\": true,\"invoice_id\": \"0021\",\"invoice_date\": \"August 29, 2041\",\"invoice_dateDue\": \"September 29, 2041\",\"issuer_name\": \"Sarah Connor\",\"issuer_company\": \"T-800 Research Lab\",\"issuer_address\": \"435 South La Fayette Park Place, Los Angeles, CA 90057\",\"issuer_website\": \"www.example.com\",\"issuer_email\": \"info@example.com\",\"client_name\": \"Cyberdyne Systems\",\"client_company\": \"Cyberdyne Systems\",\"client_address\": \"18144 El Camino Real, Sunnyvale, California\",\"client_email\": \"sales@example.com\",\"items\": [    {    \"name\": \"T-800 Prototype Research\", \"price\": 1000.00    },   {     \"name\": \"T-800 Cloud Sync Setup\", \"price\": 300.00     }  ],\"discount\": 100,\"tax\": 87,\"total\": 1287,\"note\": \"Thank you for your support of advanced robotics.\"}"
);

string jsonPayload = JsonConvert.SerializeObject(parameters);
try
{

string response = webClient.UploadString(url, jsonPayload);
JObject json = JObject.Parse(response);
if (json["error"].ToObject<bool>() == false)
{
string resultFileUrl = json["url"].ToString();
Console.WriteLine(resultFileUrl);

webClient.DownloadFile(resultFileUrl, DestinationFile);
Console.WriteLine("Generated PDF file saved as \"{0}\" file.", DestinationFile);
}
else
{
Console.WriteLine(json["message"].ToString());
}
}
catch (WebException e)
{
Console.WriteLine(e.ToString());
}

webClient.Dispose();
Console.WriteLine();
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}

Output

Once you execute the above script, a PDF file named “newDocument.pdf” will be created in the same directory as your C# console application. If you open the PDF document, it should be like the one in the following screenshot:

Output PDF

On the above PDF invoice, you can see the data that you passed for the HTML template placeholders via the PDF.CO Web API call.

Let’s now make a small change in our parameter dictionary that passes values for the placeholder. In the “templateData” parameter Set the value for the “paid” attribute as “false” as shown in the following script:

   parameters.Add("templateData", "{\"paid\": false,\"invoice_id\": \"0021\",\"invoice_date\": \"August 29, 2041\",\"invoice_dateDue\": \"September 29, 2041\",\"issuer_name\": \"Sarah Connor\",\"issuer_company\": \"T-800 Research Lab\",\"issuer_address\": \"435 South La Fayette Park Place, Los Angeles, CA 90057\",\"issuer_website\": \"www.example.com\",\"issuer_email\": \"info@example.com\",\"client_name\": \"Cyberdyne Systems\",\"client_company\": \"Cyberdyne Systems\",\"client_address\": \"18144 El Camino Real, Sunnyvale, California\",\"client_email\": \"sales@example.com\",\"items\": [    {    \"name\": \"T-800 Prototype Research\",    \"price\": 1000.00     },   {    \"name\": \"T-800 Cloud Sync Setup\",   \"price\": 300.00     }  ],\"discount\": 100,\"tax\": 87,\"total\": 1287,\"note\": \"Thank you for your support of advanced robotics.\"}"
);

Here is the generated PDF. Since the value for the “paid” attribute is set to false, you can see that the “paid” stamp is not visible in the generated PDF invoice.

Output