Generat Invoice and printing is a common requirement in retail, e-commerce, and enterprise systems. Invoice printing in C#, on on A4 Printer Paper involves a combination of layout design, graphics rendering, and printer control. This post walks you through building a simple invoice printing system using C# and the .NET Framework
Invoice Printing in C# on A4 Printer Paper
Getting Started
In many business or industrial applications, printing documents without user interaction is essential. Whether you're printing invoices, labels, or reports, bypassing the print dialog helps automate processes and reduce user friction.
To print an invoice in C# on A4 paper size, you’ll typically use the PrintDocument
class from the System.Drawing.Printing
namespace which is availabl in System.Drawing.Common.Printing
library. This library can be used in both .NetFramework and .NET Core/6/7+. Here we will generate invoice and print in C# and .Net 8.0
A4 Printer Paper
Before continuing let's know about the A4 Printer Paper, An A4 paper size is part of the ISO 216 standard for paper sizes, commonly used internationally (especially outside the U.S. and Canada).
A4 paper size
An A4 printer paper has following dimention:- A4 size in cm:is 21.0 cm × 29.7 cm
- A4 size in inches:is 8.27 in × 11.69
- A4 size in pixel: (8.27*dpi × 11.69*dpi
DPI stands for Dots Per Inch, and it's a measure of a printer's resolution—specifically, how many tiny ink dots it can print in a single inch. 300 DPI is usually considered the minimum for professional-looking print.
Invoice Printing in C#
Let's say you are working on a bill invoice generator tool project for a service center where services are provided to two-wheeler vehicles. The goal is to generate an invoice and print it on A4 printer paper at the end of the service for payment. The code examples below are built with this scenario in mind.
This invoice printing has two parts that means the PrintDocument
class has two parts to accomplish the invoice printing on A4 Printer paper. The first part is setting the printer and setting up the A4 paper size. The second part is printing invoice elements border, header and footer etc. on A4 paper size using PrintPageEventHandler
. Check the below codes...
Setting up Printer & A4 Printer Paper
int pageWidth = Convert.ToInt32(8.27 * 96);
int pageHeight = Convert.ToInt32((11.69 * 96));
int margin = 40;
PrintDocument printDocument = new PrintDocument();
printDocument.DefaultPageSettings.PaperSize = new PaperSize("A4", pageWidth, pageHeight);
printDocument.DefaultPageSettings.Margins = new Margins(margin, margin, margin, margin);
//printDocument.DefaultPageSettings.Landscape = false;
printDocument.DefaultPageSettings.PrinterSettings.Copies = 1;
printDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF";
Printing Invoice Elements
An invoice mainly consists of three sections: Header, Detail, and Footer, along with other elements such as borders and lines. We will discuss each element here, one by one.
Print Invoice Border
The invoice border typically refers to the visual boundary or frame that surrounds the content of an invoice, especially when it's printed or displayed as a PDF or hard copy. It helps to makes the invoice look professional and organized.
C# Code Example Graphics g = e.Graphics;
// Get margin bounds
Rectangle marginBounds = e.MarginBounds;
int positionX = marginBounds.Left + 10;
int positionY = marginBounds.Top + 10;
// Draw border rectangle
g.DrawRectangle(new Pen(Color.Black, 1), marginBounds);
Print Invoice Header
An Invoice Header is the top section of an invoice document. It provides essential information that identifies the invoice and sets the context for the transaction. It contains key identifying information such as company name, company logo, address, contact details and invoice title etc.Here the codes that prints the header information.
C# Code Example #region Invoice_Header
int positionX = marginBounds.Left + 10;
int positionY = marginBounds.Top + 10;
Font orgFont = new Font("Engravers MT", 18, FontStyle.Bold);
Brush orgBrush = Brushes.Gray;
// Example: Draw text at the top-left margin
SizeF textSize = g.MeasureString("Nidhi Service Center", orgFont);
g.DrawString("Nidhi Service Center", orgFont, orgBrush, positionX, positionY);
positionY += Convert.ToInt32(textSize.Height)+1;
Font addFont = new Font("Arial", 10, FontStyle.Bold);
Brush addBrush = Brushes.Gray;
g.DrawString("Building #-8,Room #603,Road-8,Sahid Nagar,Old Town, Mumbai-70002", addFont, addBrush, positionX, positionY);
textSize = g.MeasureString("Building #-8,Room #603,Road-8,Sahid Nagar,Old Town, Mumbai-70002\"", addFont);
positionY += Convert.ToInt32(textSize.Height) + 1;
Font ctntFont = new Font("Arial", 10, FontStyle.Bold);
Brush ctntBrush = Brushes.Gray;
g.DrawString("Contact No.:", ctntFont, ctntBrush, positionX, positionY);
textSize = g.MeasureString("Contact No.:", ctntFont);
positionX += Convert.ToInt32(textSize.Width) + 5;
Font ctnFont = new Font("Arial", 10, FontStyle.Bold);
Brush ctnBrush = Brushes.Gray;
//g.DrawString(contactno, ctnFont, ctnBrush, 130, positionY);
g.DrawString(contactno, ctnFont, ctnBrush, positionX, positionY);
positionY = marginBounds.Top + 30;
Font invFont = new Font("Arial", 20, FontStyle.Bold);
Brush invBrush = Brushes.LightGray;
textSize = g.MeasureString("INVOICE", invFont);
positionX = marginBounds.Right - (Convert.ToInt32(textSize.Width) + 10);
g.DrawString("INVOICE", invFont, invBrush, positionX, positionY);
int linePositionY = 130;
g.DrawLine(Pens.Black, marginBounds.Left, linePositionY, marginBounds.Right, linePositionY);
#endregion
At the end of the header details, this code draws a line to separate header information.
Print Invoice Sub-Header
A sub-header on an invoice is the section just below the main "header" title that provides a quick summary of the key details about the invoice. It helps the client or recipient immediately see important information without needing to dig through the full document.
C# Code Example #region Sub_Header
positionX = marginBounds.Left + 10;
positionY = linePositionY+10;
Font headerFont = new Font("Arial", 10);
Brush headerBrush = Brushes.Black;
Font valueFont = new Font("Arial", 10);
Brush valueBrush = Brushes.Gray;
textSize = g.MeasureString("Service #.:", headerFont);
g.DrawString("Service #.:", headerFont, headerBrush, positionX, positionY);
g.DrawString("200729", valueFont, valueBrush, positionX+80, positionY);
g.DrawString("Customer :", headerFont, headerBrush, positionX, positionY+20);
g.DrawString("Kailash Behera", valueFont, valueBrush, positionX + 80, positionY + 20);
g.DrawString("Vehicle #:", headerFont, headerBrush, positionX, positionY + 40);
g.DrawString("MH03CF0000", valueFont, valueBrush, positionX + 80, positionY + 40);
g.DrawString("Model :", headerFont, headerBrush, positionX, positionY + 60);
g.DrawString("BAJAJ PULSAR 150", valueFont, valueBrush, positionX + 80, positionY + 60);
textSize = g.MeasureString("29-07-2025", headerFont);
positionX = marginBounds.Right - (Convert.ToInt32(textSize.Width) + 10);
g.DrawString("29-07-2025", valueFont, valueBrush, positionX, positionY);
g.DrawString("Date.:", headerFont, headerBrush, positionX-50, positionY);
linePositionY = 240;
g.DrawLine(Pens.Black, marginBounds.Left, linePositionY, marginBounds.Right, linePositionY);
#endregion
Print Invoice Details
An Invoice Details is a structured table that contains detailed, line-by-line information about the items or services listed on an invoice.
C# Code Example #region Invoice_Details
int row = 250;
g.DrawString("Sno.", headerFont, headerBrush, marginBounds.Left + 10, row);
g.DrawString("Particulars", headerFont, headerBrush, 100, row);
g.DrawString("Unit.", headerFont, headerBrush, marginBounds.Right - 250, row);
g.DrawString("Qty.", headerFont, headerBrush, marginBounds.Right - 200, row);
g.DrawString("Price", headerFont, headerBrush, marginBounds.Right - 150, row);
g.DrawString("Amount", headerFont, headerBrush, marginBounds.Right - 60, row);
linePositionY = 280;
g.DrawLine(Pens.Black, marginBounds.Left, linePositionY, marginBounds.Right, linePositionY);
row = 300;
int column = 0;
for (int i = 1; i <= 20; i++)
{
column = (i < 10 ? 55 : 50);
g.DrawString(i.ToString(), headerFont, headerBrush, column, row);
g.DrawString("item "+i.ToString(), headerFont, headerBrush, 100, row);
g.DrawString("No", headerFont, headerBrush, marginBounds.Right - 250, row);
column = Convert.ToInt32(g.MeasureString((i * 10).ToString(), headerFont).Width);
column = 580 - column;
g.DrawString((i * 10).ToString(), headerFont, headerBrush, column, row);
column = Convert.ToInt32(g.MeasureString((i * 10).ToString(), headerFont).Width);
column = 634- column;
g.DrawString((i * 10).ToString(), headerFont, headerBrush, column, row);
double amount = (i * 100);
column = marginBounds.Right - 10;
column = column-Convert.ToInt32(g.MeasureString(amount.ToString(), headerFont).Width);
g.DrawString((i * 100).ToString(), headerFont, headerBrush, column, row);
row += 30;
}
linePositionY = row;
g.DrawLine(Pens.Black, marginBounds.Left, linePositionY, marginBounds.Right, linePositionY);
#endregion
Print Invoice Footer
An invoice footer is the section at the bottom of an invoice that provides summary details like total amount, tax applied etc.
C# Code Example #region Invoice_Footer
row +=10;
g.DrawString("Billing Date.:", headerFont, headerBrush, 50, row);
g.DrawString("29-07-2025", valueFont, valueBrush, 130, row);
g.DrawString("Service Amount.:", headerFont, headerBrush, marginBounds.Right - 250, row);
g.DrawString("S1000.00", valueFont, valueBrush, marginBounds.Right - 80, row);
row += 20;
g.DrawString("Tax (18%).:", headerFont, headerBrush, marginBounds.Right - 250, row);
g.DrawString("S100.00", valueFont, valueBrush, marginBounds.Right - 80, row);
row += 20;
g.DrawString("Billing Amount.:", headerFont, headerBrush, marginBounds.Right - 250, row);
g.DrawString("S1100.00", valueFont, valueBrush, marginBounds.Right - 80, row);
//row += 20;
//g.DrawString("Received Amount.:", headerFont, headerBrush, marginBounds.Right - 250, row);
//g.DrawString("S1100.00", valueFont, valueBrush, marginBounds.Right - 80, row);
//row += 20;
//g.DrawString("Balance.:", headerFont, headerBrush, marginBounds.Right - 250, row);
//g.DrawString("S0.00", valueFont, valueBrush, marginBounds.Right - 80, row);
linePositionY = row +20;
g.DrawLine(Pens.Black, marginBounds.Left, linePositionY, marginBounds.Right, linePositionY);
#endregion
#region PageFooter
g.DrawString("Print Date.:", headerFont, headerBrush, 50, marginBounds.Bottom - 20);
g.DrawString(DateTime.Now.ToShortDateString(), valueFont, valueBrush, 120, marginBounds.Bottom - 20);
g.DrawString("Azutherise Signature", headerFont, headerBrush, marginBounds.Right - 140, marginBounds.Bottom - 60);
Font logoFont = new Font("Bodoni MT", 12, FontStyle.Bold);
Brush logoBrush = Brushes.LightGray;
g.DrawString("MSC", logoFont, logoBrush, marginBounds.Right - 50, marginBounds.Bottom - 20);
//StringFormat stringFormat = new StringFormat();
//stringFormat. = StringAlignment.Center;
#endregion
Full code of Invoice Printing
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace printingincsharp
{
internal class Program
{
static string contactno = "0987654321,1234567890";
static void Main(string[] args)
{
PrintDocument printDocument;
printDocument = new PrintDocument();
printDocument.DefaultPageSettings.PaperSize = new PaperSize("A4", 827, 1169); // 827x1169 hundredths of an inch (8.27in x 11.69in)
printDocument.PrintPage += new PrintPageEventHandler(PrintPageHandler);
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
if (printDialog.ShowDialog() == DialogResult.OK)
{
printDocument.Print();
}
}
private static void PrintPageHandler(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
// Get margin bounds
Rectangle marginBounds = e.MarginBounds;
marginBounds.X = 20;
marginBounds.Y = 20;
marginBounds.Width = Convert.ToInt32((8.27 * 96 - 10));
marginBounds.Height = Convert.ToInt32((11.69 * 96));
// Set border pen
Pen borderPen = new Pen(Color.Black, 1); // 2-pixel thick black border
// Draw border rectangle
g.DrawRectangle(borderPen, marginBounds);
Font orgFont = new Font("Engravers MT", 16, FontStyle.Bold);
Brush orgBrush = Brushes.Gray;
// Example: Draw text at the top-left margin
g.DrawString("Nidhi Service Center", orgFont, orgBrush, 30, 30);
Font addFont = new Font("Arial", 10, FontStyle.Bold);
Brush addBrush = Brushes.Gray;
g.DrawString("Building #-8,Room #603,Road-8,Sahid Nagar,Old Town, Mumbai-70002", addFont, addBrush, 30, 60);
Font ctntFont = new Font("Arial", 10, FontStyle.Bold);
Brush ctntBrush = Brushes.Gray;
g.DrawString("Contact No.:", ctntFont, ctntBrush, 30, 80);
Font ctnFont = new Font("Arial", 10, FontStyle.Bold);
Brush ctnBrush = Brushes.Gray;
g.DrawString(contactno, ctnFont, ctnBrush, 120, 80);
Font invFont = new Font("Arial", 20, FontStyle.Bold);
Brush invBrush = Brushes.LightGray;
g.DrawString("INVOICE", invFont, invBrush, marginBounds.Right - 120, 50);
// Example: Draw horizontal line across the page (centered vertically)
//int positionY = marginBounds.Top + marginBounds.Height / 2;
int positionY = 120;
g.DrawLine(Pens.Black, marginBounds.Left, positionY, marginBounds.Right, positionY);
Font headerFont = new Font("Arial", 10);
Brush headerBrush = Brushes.Black;
Font valueFont = new Font("Arial", 10);
Brush valueBrush = Brushes.Gray;
g.DrawString("Service #.:", headerFont, headerBrush, 30, 140);
g.DrawString("200729", valueFont, valueBrush, 110, 140);
g.DrawString("Date.:", headerFont, headerBrush, marginBounds.Right - 150, 140);
g.DrawString("29-07-2025", valueFont, valueBrush, marginBounds.Right - 100, 140);
g.DrawString("Customer :", headerFont, headerBrush, 30, 165);
g.DrawString("Kailash Behera", valueFont, valueBrush, 110, 165);
g.DrawString("Vehicle #:", headerFont, headerBrush, 30, 185);
g.DrawString("MH02KC0000", valueFont, valueBrush, 110, 185);
g.DrawString("Model :", headerFont, headerBrush, 30, 205);
g.DrawString("BAJAJ PULSAR 150", valueFont, valueBrush, 110, 205);
positionY = 240;
g.DrawLine(Pens.Black, marginBounds.Left, positionY, marginBounds.Right, positionY);
g.DrawString("Sno.", headerFont, headerBrush, 30, 250);
g.DrawString("Particulars", headerFont, headerBrush, 80, 250);
g.DrawString("Unit.", headerFont, headerBrush, marginBounds.Right - 250, 250);
g.DrawString("Qty.", headerFont, headerBrush, marginBounds.Right - 200, 250);
g.DrawString("Price", headerFont, headerBrush, marginBounds.Right - 150, 250);
g.DrawString("Amount", headerFont, headerBrush, marginBounds.Right - 80, 250);
positionY = 280;
g.DrawLine(Pens.Black, marginBounds.Left, positionY, marginBounds.Right, positionY);
int row = 300;
for (int i = 1; i <= 20; i++)
{
g.DrawString(i.ToString(), headerFont, headerBrush, 30, row);
g.DrawString("Item "+i.ToString(), headerFont, headerBrush, 80, row);
g.DrawString("No", headerFont, headerBrush, marginBounds.Right - 250, row);
g.DrawString((i * 10).ToString(), headerFont, headerBrush, marginBounds.Right - 200, row);
g.DrawString((i * 10).ToString(), headerFont, headerBrush, marginBounds.Right - 150, row);
g.DrawString((i * 100).ToString(), headerFont, headerBrush, marginBounds.Right - 80, row);
row += 30;
}
positionY = 900;
g.DrawLine(Pens.Black, marginBounds.Left, positionY, marginBounds.Right, positionY);
g.DrawString("Billing Date.:", headerFont, headerBrush, 30, 920);
g.DrawString("29-07-2025", valueFont, valueBrush, 120, 920);
g.DrawString("Service Amount.:", headerFont, headerBrush, marginBounds.Right - 230, 920);
g.DrawString("S1000.00", valueFont, valueBrush, marginBounds.Right - 80, 920);
g.DrawString("Tax (18%).:", headerFont, headerBrush, marginBounds.Right - 230, 940);
g.DrawString("S100.00", valueFont, valueBrush, marginBounds.Right - 80, 940);
g.DrawString("Billing Amount.:", headerFont, headerBrush, marginBounds.Right - 230, 960);
g.DrawString("S1100.00", valueFont, valueBrush, marginBounds.Right - 80, 960);
g.DrawString("Received Amount.:", headerFont, headerBrush, marginBounds.Right - 230, 980);
g.DrawString("S1100.00", valueFont, valueBrush, marginBounds.Right - 80, 980);
g.DrawString("Balance.:", headerFont, headerBrush, marginBounds.Right - 230, 1000);
g.DrawString("S0.00", valueFont, valueBrush, marginBounds.Right - 80, 1000);
positionY = 1020;
g.DrawLine(Pens.Black, marginBounds.Left, positionY, marginBounds.Right, positionY);
g.DrawString("Print Date.:", headerFont, headerBrush, 30, marginBounds.Bottom - 20);
g.DrawString(DateTime.Now.ToShortDateString(), valueFont, valueBrush, 120, marginBounds.Bottom - 20);
g.DrawString("Azutherise Signature", headerFont, headerBrush, marginBounds.Right - 140, marginBounds.Bottom - 60);
Font logoFont = new Font("Bodoni MT", 12, FontStyle.Bold);
Brush logoBrush = Brushes.LightGray;
g.DrawString("M.S.C", logoFont, logoBrush, marginBounds.Right - 50, marginBounds.Bottom - 20);
//StringFormat stringFormat = new StringFormat();
//stringFormat. = StringAlignment.Center;
}
}
}
Note:-These codes dynamically create an invoice template while printing
Summary
This approach offers a flexible way to print invoices on A4 printer paper using native .NET tools (such as the PrintDocument
class by setting the PaperSize
), making it a straightforward solution, especially useful in enterprise applications that require unattended document generation and output. I hope this code example was helpful to you.
Thanks