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.
Mostafa Kaisoun
m_kaisoun@hotmail.com