Create or Generate PDF / Word and export in ASP.NET
GemBox.Document is a standalone .NET component with 100% managed code. It doesn't use Microsoft Office Interop nor any other dependency.
Its fast performance and thread safety when working with multiple DocumentModel
objects makes it ideal for web applications (like ASP.NET Web Forms, ASP.NET MVC, and ASP.NET Core).
The following example shows how you can create an ASP.NET Web Forms application that executes a mail merge process on a template Word document, with data provided by web form, to generate a PDF file that's exported or downloaded to a client's browser.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MediumTrust.Default" %>
<!DOCTYPE html>
<html lang="en-US">
<head runat="server">
<title>Create PDF documents or Word files (DOCX, RTF, XML, HTML) from ASP.NET Web Forms</title>
<style>
* {
font-family: Calibri;
color: #514E52;
padding: 6px;
box-sizing: border-box;
}
header {
height: 80px;
background: #F26522 url("./images/logo.svg") no-repeat left;
}
header a {
height: 68px;
display: block;
}
label, input, select, th, td { width: 150px; }
label {
display: inline-block;
text-align: right;
}
label::after { content: ":"; }
.aspNetHidden { padding: 0; }
</style>
</head>
<body>
<header><a href="https://www.gemboxsoftware.com/"></a></header>
<form id="formInvoice" runat="server">
<h1>Invoice</h1>
<div>
<asp:Label ID="lblNumber" runat="server" AssociatedControlId="txtNumber" Text="Number" />
<asp:TextBox ID="txtNumber" runat="server" TextMode="Number" />
</div>
<div>
<asp:Label ID="lblDate" runat="server" AssociatedControlId="txtDate" Text="Date" />
<asp:TextBox ID="txtDate" runat="server" TextMode="Date" />
</div>
<div>
<asp:Label ID="lblCompany" runat="server" AssociatedControlId="txtCompany" Text="Company" />
<asp:TextBox ID="txtCompany" runat="server" TextMode="SingleLine" />
</div>
<asp:GridView ID="gridItems" runat="server" BorderColor="#BFBFBF" ShowHeaderWhenEmpty="true"
AutoGenerateColumns="false" AutoGenerateDeleteButton="true" AutoGenerateEditButton="true"
OnRowUpdating="gridItems_RowUpdating"
OnRowEditing="gridItems_RowEditing"
OnRowCancelingEdit="gridItems_RowCancelingEdit"
OnRowDeleting="gridItems_RowDeleting">
<HeaderStyle Font-Bold="true" Font-Size="Larger" />
<Columns>
<asp:BoundField DataField="Date" HeaderText="Date" DataFormatString="{0:d MMM yyyy}" />
<asp:BoundField DataField="Hours" HeaderText="Hours" DataFormatString="{0:d}" />
<asp:BoundField DataField="Unit" HeaderText="Unit (€/hour)" DataFormatString="{0:0.00}" />
<asp:BoundField DataField="Price" HeaderText="Price" DataFormatString="{0:0.00}" ReadOnly="true" />
</Columns>
</asp:GridView>
<div>
<asp:Button ID="btnAddRow" runat="server" Text="Add Item" OnClick="btnAddRow_Click"/>
</div>
<div>
<asp:Label ID="lblTotal" runat="server" AssociatedControlId="txtDate" Text="Total" Font-Bold="true" ForeColor="#F26522" Font-Size="Larger" />
<asp:TextBox ID="txtTotal" runat="server" ReadOnly="true" Font-Bold="true" ForeColor="#F26522" Font-Size="Larger" />
</div>
<div>
<asp:Label ID="lblFileFormat" runat="server" AssociatedControlId="ddlFileFormat" Text="File format" />
<asp:DropDownList ID="ddlFileFormat" runat="server">
<asp:ListItem Value=".pdf" Selected="true">PDF</asp:ListItem>
<asp:ListItem Value=".docx">DOCX</asp:ListItem>
<asp:ListItem Value=".odt">ODT</asp:ListItem>
<asp:ListItem Value=".html">HTML</asp:ListItem>
<asp:ListItem Value=".mhtml">MHTML</asp:ListItem>
<asp:ListItem Value=".rtf">RTF</asp:ListItem>
<asp:ListItem Value=".xml">XML</asp:ListItem>
<asp:ListItem Value=".txt">TXT</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<asp:Button ID="btnCreateFile" runat="server" Text="Create Invoice" OnClick="btnCreateFile_Click" />
</div>
</form>
</body>
</html>
using GemBox.Document;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MediumTrust
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
// If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// In order to create a PDF file in Medium Trust environment you'll need to specify
// font files location that is under your ASP.NET application's control.
// This is required because in partial-trust domain it's prohibited to access system's installed fonts.
FontSettings.FontsBaseDirectory = Server.MapPath("Fonts/");
// Set web form default values.
if (!this.Page.IsPostBack)
{
this.txtNumber.Text = "10203";
this.txtDate.Text = DateTime.Today.ToString("yyyy-MM-dd");
this.txtCompany.Text = "ACME Corp";
var items = new DataTable("Items");
items.Columns.Add("Date", typeof(DateTime));
items.Columns.Add("Hours", typeof(int));
items.Columns.Add("Unit", typeof(double));
items.Columns.Add("Price", typeof(double));
items.Rows.Add(DateTime.Today.AddDays(-3), 6, 35);
items.Rows.Add(DateTime.Today.AddDays(-2), 7, 35);
items.Rows.Add(DateTime.Today.AddDays(-1), 8, 35);
this.Session["ItemsTable"] = items;
this.RefreshGridData();
}
}
private DataTable GetGridData() => (DataTable)this.Session["ItemsTable"];
private void RefreshGridData()
{
var items = this.GetGridData();
double total = 0;
foreach (DataRow row in items.Rows)
{
double price = (int)row["Hours"] * (double)row["Unit"];
row["Price"] = price;
total += price;
}
this.gridItems.DataSource = items;
this.gridItems.DataBind();
this.txtTotal.Text = total.ToString("0.00");
}
protected void btnCreateFile_Click(object sender, EventArgs e)
{
// Load template document.
DocumentModel document = DocumentModel.Load(
Path.Combine(this.Request.PhysicalApplicationPath, "%#InvoiceTemplate.docx%"));
if (!int.TryParse(this.txtNumber.Text, out int number))
this.txtNumber.Text = number.ToString();
if (!DateTime.TryParse(this.txtDate.Text, out DateTime date))
this.txtDate.Text = date.ToString();
// Execute mail merge operations with data from web form.
document.MailMerge.Execute(
new Dictionary<string, object>()
{
["Number"] = number,
["Date"] = date,
["Company"] = this.txtCompany.Text,
["TotalPrice"] = double.Parse(this.txtTotal.Text)
});
document.MailMerge.Execute(
this.GetGridData());
// Create document in specified format (PDF, DOCX, etc.) and
// stream (download) it to client's browser.
document.Save(this.Response, $"Invoice{this.ddlFileFormat.SelectedValue}");
}
protected void btnAddRow_Click(object sender, EventArgs e)
{
var items = this.GetGridData();
items.Rows.Add(DateTime.Today, 8, 35);
this.RefreshGridData();
}
protected void gridItems_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
var items = this.GetGridData();
int rowIndex = e.RowIndex;
for (int columnIndex = 1; columnIndex < items.Columns.Count; columnIndex++)
{
var cell = this.gridItems.Rows[rowIndex].Cells[columnIndex];
if (cell.Controls[0] is System.Web.UI.WebControls.TextBox textBox)
{
try { items.Rows[rowIndex][columnIndex - 1] = textBox.Text; }
catch (ArgumentException) { }
}
}
this.gridItems.EditIndex = -1;
this.RefreshGridData();
}
protected void gridItems_RowEditing(object sender, GridViewEditEventArgs e)
{
this.gridItems.EditIndex = e.NewEditIndex;
this.RefreshGridData();
}
protected void gridItems_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
this.gridItems.EditIndex = -1;
this.RefreshGridData();
}
protected void gridItems_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
var items = this.GetGridData();
items.Rows[e.RowIndex].Delete();
this.RefreshGridData();
}
}
}
Imports GemBox.Document
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.IO
Imports System.Web.UI
Imports System.Web.UI.WebControls
Namespace MediumTrust
Partial Public Class [Default]
Inherits Page
Protected Sub Page_Load(sender As Object, e As EventArgs)
' If using the Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' In order to create a PDF file in Medium Trust environment you'll need to specify
' font files location that is under your ASP.NET application's control.
' This is required because in partial-trust domain it's prohibited to access system's installed fonts.
FontSettings.FontsBaseDirectory = Server.MapPath("Fonts/")
' Set web form default values.
If Not Page.IsPostBack Then
Me.txtNumber.Text = "10203"
Me.txtDate.Text = DateTime.Today.ToString("yyyy-MM-dd")
Me.txtCompany.Text = "ACME Corp"
Dim items As New DataTable("Items")
items.Columns.Add("Date", GetType(DateTime))
items.Columns.Add("Hours", GetType(Integer))
items.Columns.Add("Unit", GetType(Double))
items.Columns.Add("Price", GetType(Double))
items.Rows.Add(DateTime.Today.AddDays(-3), 6, 35)
items.Rows.Add(DateTime.Today.AddDays(-2), 7, 35)
items.Rows.Add(DateTime.Today.AddDays(-1), 8, 35)
Me.Session("ItemsTable") = items
Me.RefreshGridData()
End If
End Sub
Private Function GetGridData() As DataTable
Return DirectCast(Me.Session("ItemsTable"), DataTable)
End Function
Private Sub RefreshGridData()
Dim items = Me.GetGridData()
Dim total As Double = 0
For Each row As DataRow In items.Rows
Dim price As Double = CInt(row("Hours")) * CDbl(row("Unit"))
row("Price") = price
total += price
Next
Me.gridItems.DataSource = items
Me.gridItems.DataBind()
Me.txtTotal.Text = total.ToString("0.00")
End Sub
' On button click generate the document and stream it to the browser.
Protected Sub btnCreateFile_Click(sender As Object, e As EventArgs)
' Load template document.
Dim document As DocumentModel = DocumentModel.Load(
Path.Combine(Me.Request.PhysicalApplicationPath, "%#InvoiceTemplate.docx%"))
Dim number As Integer
If Not Integer.TryParse(Me.txtNumber.Text, number) Then
Me.txtNumber.Text = number.ToString()
End If
Dim [date] As DateTime
If Not DateTime.TryParse(Me.txtDate.Text, [date]) Then
Me.txtDate.Text = [date].ToString()
End If
' Execute mail merge operations with data from web form.
document.MailMerge.Execute(
New Dictionary(Of String, Object) From
{
{"Number", number},
{"Date", [date]},
{"Company", Me.txtCompany.Text},
{"TotalPrice", Double.Parse(Me.txtTotal.Text)}
})
document.MailMerge.Execute(
Me.GetGridData())
' Create document in specified format (PDF, DOCX, etc.) and
' stream (download) it to client's browser.
document.Save(Me.Response, $"Invoice{Me.ddlFileFormat.SelectedValue}")
End Sub
Protected Sub btnAddRow_Click(sender As Object, e As EventArgs)
Dim items = Me.GetGridData()
items.Rows.Add(DateTime.Today, 8, 35)
Me.RefreshGridData()
End Sub
Protected Sub gridItems_RowUpdating(sender As Object, e As GridViewUpdateEventArgs)
Dim items = Me.GetGridData()
Dim rowIndex As Integer = e.RowIndex
For columnIndex = 1 To items.Columns.Count - 1
Dim cell = Me.gridItems.Rows(rowIndex).Cells(columnIndex)
Dim textBox = TryCast(cell.Controls(0), System.Web.UI.WebControls.TextBox)
If textBox IsNot Nothing Then
Try
items.Rows(rowIndex)(columnIndex - 1) = textBox.Text
Catch ex As ArgumentException
End Try
End If
Next
Me.gridItems.EditIndex = -1
Me.RefreshGridData()
End Sub
Protected Sub gridItems_RowEditing(sender As Object, e As GridViewEditEventArgs)
Me.gridItems.EditIndex = e.NewEditIndex
Me.RefreshGridData()
End Sub
Protected Sub gridItems_RowCancelingEdit(sender As Object, e As GridViewCancelEditEventArgs)
Me.gridItems.EditIndex = -1
Me.RefreshGridData()
End Sub
Protected Sub gridItems_RowDeleting(sender As Object, e As GridViewDeleteEventArgs)
Dim items = Me.GetGridData()
items.Rows(e.RowIndex).Delete()
Me.RefreshGridData()
End Sub
End Class
End Namespace
GemBox.Document provides support for both full trust and medium trust environment. This example's demo is an ASP.NET Medium Trust application that is running in a partial-trust application domain.
Such applications have homogeneous domains that have a constrained set of possible permissions. For more information, visit our Support for Partially Trusted applications help page or Microsoft's ASP.NET Code Access Security documentation. GemBox.Document follows a licensing model per individual developer, which includes royalty-free deployment. You are allowed to build an unlimited number of applications and deploy or distribute them across numerous services, servers, or end-user machines without any additional cost. For more information, read our End User License Agreement (EULA).Host and deploy ASP.NET Web Forms