BoldSign Site Logo

How to Build Sample for Sending Hike Letter Documents in Bulk

Getting Started
Prerequisites & Setup
  • .NET SDK 6 / 7 / 8 This demo targets .NET 8. Download the SDK from .NET Download. Run dotnet --version to confirm.
  • Syncfusion License Required to unlock the XlsIO and DocIO libraries without a watermark. A free trial or Community License is available — details below.
  • BoldSign API Key Required to send documents for eSignature. Sign up for a free BoldSign sandbox account to get your API key — details below.
Required NuGet Packages (Ignore if already configured all the packages)
Package Used for
BoldSign.Api Sending the generated/uploaded document for signature and tracking its status.
Syncfusion.XlsIO.Net.Core Reading the employee data excel/CSV file, validating columns, and exporting the updated result sheet.
Syncfusion.DocIO.Net.Core Merging employee values into the built-in Word template and saving the personalised DOCX for each employee.
Syncfusion.Licensing Registers your Syncfusion license key at startup. Required for all Syncfusion packages.
# BoldSign API SDK
dotnet add package BoldSign.Api

# Excel read/write/export
dotnet add package Syncfusion.XlsIO.Net.Core

# Word template merge
dotnet add package Syncfusion.DocIO.Net.Core

# License registration helper
dotnet add package Syncfusion.Licensing
Tip: Keep every Syncfusion package on the same version number to avoid assembly conflicts. If you install Syncfusion.XlsIO.Net.Core v31.1.17, set Syncfusion.DocIO.Net.Core and Syncfusion.Licensing to v31.1.17 as well.
Syncfusion License (Ignore if already configured Syncfusion License)
License Type Who it's for Cost How to get it
Free 30-Day Trial Anyone evaluating Syncfusion for the first time Free Syncfusion Downloads → Download any product → a trial key is emailed automatically.
Community License Individual developers or small companies with annual revenue < USD 1 million and < 5 developers Free (perpetual) Community License → Fill in the short form and a key will be emailed.
Essential Studio (Paid) Companies that exceed the Community License thresholds Starts at ~USD 995/developer/year Syncfusion Products → Choose a plan → checkout or contact sales.
  1. Log in to your Syncfusion account at Syncfusion Downloads.
  2. Go to License & Downloads → License Keys and copy the key for your platform (ASP.NET Core).
  3. Open your project's Program.cs (or Startup.cs).
  4. Add the registration call before any other Syncfusion code runs.
// Program.cs — before builder.Build()
using Syncfusion.Licensing;

SyncfusionLicenseProvider.RegisterLicense("YOUR_LICENSE_KEY_HERE");
Never hard-code the key in source code committed to a public repository. Store it in appsettings.json or an environment variable and read it at startup:
// appsettings.json
{
  "SyncfusionLicenseKey": "YOUR_KEY"
}

// Program.cs
var licenseKey = builder.Configuration["SyncfusionLicenseKey"];
SyncfusionLicenseProvider.RegisterLicense(licenseKey);
BoldSign API Key (Ignore if already configured the BoldSign API Key)
  1. Create a free BoldSign account
    Go to BoldSign and register with the free sandbox plan.
  2. Generate an API key
    After signing in, open Settings → API → API Keys → Create New API Key. Copy the key — it is shown only once. Refer to this article for generating an API key.
  3. Add the key to your project
    Store it in appsettings.json (or an environment variable) and inject it into the API client:
// appsettings.json
{
  "BoldSignSettings": {
    "ApiKey": "YOUR_BOLDSIGN_API_KEY"
  }
}

// C#: Configure BoldSign API client
var configuration = new BoldSign.Api.Configuration();
configuration.ApiKey.Add("X-API-KEY", builder.Configuration["BoldSignSettings:ApiKey"]);
var documentClient = new DocumentClient(configuration);
Implementation Walkthrough
How It All Fits Together

How the Sample Works

This sample requires no pre-made letters — only an Excel sheet with employee values. A personalised Word document is generated on demand for every employee from one built-in template and sent directly to BoldSign for signature.

Signature Tags Pre-configured: The built-in hike letter template (Hike_Letter_Template.docx) already contains the BoldSign text tag {{sign|1|*}} placed at the signature location. The tag is set in white text so it remains invisible in the rendered document while BoldSign still detects and renders the signature field correctly.

Step 1 Upload the Employee Data Sheet

The uploaded Excel sheet must contain exactly these six columns: Employee_Id, Employee_Name, Designation, Effective_Date, Raise_Percentage, and Rounded_Salary. Each row is parsed and validated using Syncfusion XlsIO into a strongly-typed HikeLetterTemplateRow object.

using Syncfusion.XlsIO;

using var excelEngine = new ExcelEngine();
var workbook = excelEngine.Excel.Workbooks.Open(fileStream);
var sheet = workbook.Worksheets[0];
var usedRange = sheet.UsedRange;

for (var r = 2; r <= usedRange.LastRow; r++)
{
    var row = new HikeLetterTemplateRow
    {
        Employee_Id      = sheet.Range[r, 1].DisplayText?.Trim(),
        Employee_Name    = sheet.Range[r, 2].DisplayText?.Trim(),
        Designation      = sheet.Range[r, 3].DisplayText?.Trim(),
        Effective_Date   = sheet.Range[r, 4].DisplayText?.Trim(),
        Raise_Percentage = sheet.Range[r, 5].DisplayText?.Trim(),
        Rounded_Salary   = sheet.Range[r, 6].DisplayText?.Trim(),
    };
}

Step 2 Merge Values into the Word Template

The built-in template (Hike_Letter_Template.docx) contains plain-text placeholders such as «Employee_Name». For every employee row, we open a fresh copy of the template with Syncfusion DocIO and replace each placeholder with the row's actual value:

using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;

using var document = new WordDocument(templateStream, FormatType.Docx);
document.Replace("«Employee_Id»",      row.Employee_Id,      false, true);
document.Replace("«Employee_Name»",    row.Employee_Name,    false, true);
document.Replace("«Designation»",      row.Designation,      false, true);
document.Replace("«Effective_Date»",   row.Effective_Date,   false, true);
document.Replace("«Raise_Percentage»", row.Raise_Percentage, false, true);
document.Replace("«Rounded_Salary»",   row.Rounded_Salary,   false, true);

Step 3 Send the Merged Document for Signature

Because BoldSign accepts DOCX files natively, the merged in-memory Word document is saved to a byte array and sent directly. The employee is the sole signer — BoldSign automatically converts the {{sign|1|*}} text tag in the document into a real signature form field.

using var docxStream = new MemoryStream();
document.Save(docxStream, FormatType.Docx);
var docxBytes = docxStream.ToArray();

var request = new SendForSign
{
    Title = $"Hike Letter - {row.Employee_Name}",
    UseTextTags = true,
    Files = new List<IDocumentFile>
    {
        new DocumentFileBytes
        {
            FileData = docxBytes,
            FileName = $"HikeLetter_{row.Employee_Id}.docx",
            ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        }
    },
    Signers = new List<DocumentSigner>
    {
        new DocumentSigner(
            name: row.Employee_Name,
            emailAddress: row.EmployeeEmail,
            signerType: SignerType.Signer)
    }
};

var result = await documentClient.SendDocumentAsync(request);
row.DocumentId = result.DocumentId;
row.Status = "Sent";

Background Processing & Live Progress

The row list is handed off to HikeLetterJobManager, which processes each employee one-by-one on a background task so the UI can poll for live progress every second:

public string StartTemplateJob(List<HikeLetterTemplateRow> rows)
{
    var job = new HikeLetterJobState("template", rows.Count);
    this.jobs[job.JobId] = job;
    _ = Task.Run(() => this.ProcessTemplateJobAsync(job, rows));
    return job.JobId;
}

As each row finishes, its Status and DocumentId are updated in place on the same object referenced by the session, and an activity log entry is appended. The browser polls ?handler=JobStatus to update the live progress bar, success/failed/skipped counters, and activity table in real time.

Final Step Export the Updated Excel

Once the batch finishes, clicking Download Updated Excel regenerates the original sheet with two new columns populated — Status and Document_Id — using XlsIO, so the results can be tracked and audited outside the app.