Introduction
How to use C# to print Invoice? This is a trial to print Invoice with C#.
You can read another article (How to use VB.NET to print Invoice?).
My project has three forms:
frmInvoice
: to bind DataGrid
with all Orders
from Northwind
database file frmInput
: to choose one Order
which you want to print its Invoice
frmOrder
: to display Invoice
on DataGrid
, then you can Print Preview or Print the Invoice as Report
Also, we need three classes for printing:
System.Windows.Forms.PrintDialog
System.Windows.Forms.PrintPreviewDialog
System.Drawing.Printing.PrintDocument
Of course, you can use any database file instead of Northwind.mdb and change my code to connect with your database file, also you can change my SQL string to bind DataGrid
with data.
Using the Code
Bind the DataGrid
in frmInvoice
form with all Orders
:
string MyPass = "";
string MyDataFile = Application.StartupPath + @"\DataFile\Northwind.mdb";
string strCon = @"provider=microsoft.jet.oledb.4.0;data source=" +
MyDataFile + ";" + "Jet OLEDB:Database Password=" + MyPass + ";";
string strCon = @"provider=sqloledb;Data Source=PC;Initial Catalog=" +
"Northwind;Integrated Security=SSPI" + ";";
try
{
string InvSql = "SELECT Customers.CompanyName, Customers.City, " +
"Employees.FirstName + Space(1) + Employees.LastName AS Salesperson, " +
"Orders.OrderID, Orders.OrderDate, " +
"[Order Details].ProductID, Products.ProductName, [Order Details].UnitPrice, " +
"[Order Details].Quantity, [Order Details].Discount, "+
"CCur([Order Details].UnitPrice*[Quantity]*(1-[Discount])/100)*100
AS ExtendedPrice, " +
"Orders.Freight " +
"FROM Products INNER JOIN ((Employees INNER JOIN " +
"(Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID) " +
"ON Employees.EmployeeID = Orders.EmployeeID) " +
"INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID) " +
"ON Products.ProductID = [Order Details].ProductID;";
OleDbDataAdapter datAdp = new OleDbDataAdapter(InvSql, strCon);
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(datAdp);
DataTable dTable = new DataTable;
datAdp.Fill(dTable);
datGrid.DataSource = dTable;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
Bind the DataGrid
in frmOrder
form with one Order
:
int intOrder = int.Parse(clsGlobal.InvoiceOrder);
string MyDataFile = Application.StartupPath + @"\DataFile\Northwind.mdb";
string MyPass = "";
dtring strCon = "provider=microsoft.jet.oledb.4.0;data source=" +
MyDataFile + ";" + "Jet OLEDB:Database Password=" + MyPass + ";";
try
{
InvSql = "SELECT [Order Details].ProductID, " +
"Products.ProductName, [Order Details].UnitPrice, " +
"[Order Details].Quantity, [Order Details].Discount, " +
"CCur([Order Details].UnitPrice*[Quantity]*(1-[Discount])/100)*100 " +
"AS ExtendedPrice " +
"FROM Products INNER JOIN [Order Details] " +
"ON Products.ProductID=[Order Details].ProductID " +
"WHERE [Order Details].OrderID = " + intOrder;
OleDbDataAdapter datAdp = new OleDbDataAdapter(InvSql, strCon);
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(datAdp);
DataTable dTable = new DataTable;
datAdp.Fill(dTable);
ordGrid.TableStyles.Clear();
DataGridTableStyle tableStyle = new DataGridTableStyle;
foreach (DataColumn dc in dTable.Columns)
{
DataGridTextBoxColumn txtColumn = new DataGridTextBoxColumn;
txtColumn.MappingName = dc.ColumnName;
txtColumn.HeaderText = dc.Caption;
switch (dc.ColumnName.ToString())
{
case "ProductID":
txtColumn.HeaderText = "Product ID";
txtColumn.Width = 60;
break;
case "ProductName":
txtColumn.HeaderText = "Product Name";
txtColumn.Width = 110;
break;
case "UnitPrice":
txtColumn.HeaderText = "Unit Price";
txtColumn.Format = "0.00";
txtColumn.Alignment = HorizontalAlignment.Right;
txtColumn.Width = 60;
break;
case "Discount":
txtColumn.HeaderText = "Discount";
txtColumn.Format = "p";
txtColumn.Alignment = HorizontalAlignment.Right;
txtColumn.Width = 60;
break;
case "Quantity":
txtColumn.HeaderText = "Quantity";
txtColumn.Alignment = HorizontalAlignment.Right;
txtColumn.Width = 50;
break;
case "ExtendedPrice":
txtColumn.HeaderText = "Extended Price";
txtColumn.Format = "0.00";
txtColumn.Alignment = HorizontalAlignment.Right;
txtColumn.Width = 90;
break;
}
tableStyle.GridColumnStyles.Add(txtColumn);
}
tableStyle.MappingName = dTable.TableName;
ordGrid.TableStyles.Add(tableStyle);
ordGrid.DataSource = dTable.DefaultView;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
Declare and initialize three instances for printing:
private System.Windows.Forms.PrintDialog prnDialog;
private System.Windows.Forms.PrintPreviewDialog prnPreview;
private System.Drawing.Printing.PrintDocument prnDocument;
this.prnDialog = new System.Windows.Forms.PrintDialog();
this.prnPreview = new System.Windows.Forms.PrintPreviewDialog();
this.prnDocument = new System.Drawing.Printing.PrintDocument();
prnDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler
(prnDocument_PrintPage);
To draw something on the report (as line or text):
- Get Left Margin, Right Margin, Top Margin, Bottom Margin, Report Width and Report Height:
private void prnDocument_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
leftMargin = (int)e.MarginBounds.Left;
rightMargin = (int)e.MarginBounds.Right;
topMargin = (int)e.MarginBounds.Top;
bottomMargin = (int)e.MarginBounds.Bottom;
InvoiceWidth = (int)e.MarginBounds.Width;
InvoiceHeight = (int)e.MarginBounds.Height;
SetInvoiceHead(e.Graphics);
}
- Set
Font
and Color
:
Font InvTitleFont = new Font("Arial", 24, FontStyle.Regular);
SolidBrush HeadBrush = new SolidBrush(Color.Blue);
- Set
Font
Height and Font
Width and coordinate, then use DrawString
method:
private void SetInvoiceHead (Graphics g)
{
string InvTitle = "International Food Company";
Font InvTitleFont = new Font("Arial", 24, FontStyle.Regular);
SolidBrush HeadBrush = new SolidBrush(Color.Blue);
int InvTitleHeight = (int)(InvTitleFont.GetHeight(g));
int lenInvTitle = (int)g.MeasureString(InvTitle, InvTitleFont).Width;
int CurrentX = leftMargin + (InvoiceWidth -
lenInvTitle) / 2;
int CurrentY = topMargin + InvTitleHeight;
g.DrawString(InvTitle, InvTitleFont, HeadBrush, CurrentX, CurrentY);
}
The project has several pieces of code in three forms, please read the code, then run the program to see the result.
You can read about:
- How to create a report using
PrintPreviewDialog
control and PrintDocument
control? - How to draw
Invoice
head? - How to draw the table of products and its price?
- How to compute and draw
Invoice
total?
If you have any ideas or if you find any problems, please tell me.
You can read my other article to see how to print invoice using VB.NET.