Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Print Invoice using C#?

0.00/5 (No votes)
15 May 2011 7  
This is a trial to print Invoice with C#

PrintInvoice_CS/Img027.JPG

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:

// following lines to connect with access database file 'Northwind.mdb'
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 + ";";

// If you are using SQL Server, please replace previous lines with following:
 string strCon = @"provider=sqloledb;Data Source=PC;Initial Catalog=" +
   "Northwind;Integrated Security=SSPI" + ";";
// and replace 'Data Source=PC' with the name of your system 

try
{
   // Get data from tables: Orders, Customers, Employees, Products, Order Details:
   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;";

   // create an OleDbDataAdapter
   OleDbDataAdapter datAdp = new OleDbDataAdapter(InvSql, strCon);

   // create a command builder
   OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(datAdp);

   // create a DataTable to hold the query results
   DataTable dTable = new DataTable;

   // fill the DataTable
   datAdp.Fill(dTable);

   // set DataSource of DataGrid 
   datGrid.DataSource = dTable;
}
catch (Exception e)
{
   MessageBox.Show(e.ToString());
}

Bind the DataGrid in frmOrder form with one Order:

// Declare 'InvoiceOrder' in 'clsGlobal' class, 
//'InvoiceOrder' is the number of Order which you select:
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
{
   // Get Invoice Data:
   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;

   // create an OleDbDataAdapter
   OleDbDataAdapter datAdp = new OleDbDataAdapter(InvSql, strCon);

   // create a command builder
   OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(datAdp);

   // create a DataTable to hold the query results
   DataTable dTable = new DataTable;

   // fill the DataTable
   datAdp.Fill(dTable);

   // Create a TableStyle to format Datagrid columns.
   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": // Product ID 
            txtColumn.HeaderText = "Product ID";
            txtColumn.Width = 60;
         break;
         case "ProductName": // Product Name 
            txtColumn.HeaderText = "Product Name";
            txtColumn.Width = 110;
         break;
         case "UnitPrice": // Unit Price 
            txtColumn.HeaderText = "Unit Price";
            txtColumn.Format = "0.00";
            txtColumn.Alignment = HorizontalAlignment.Right;
            txtColumn.Width = 60;
         break;
         case "Discount": // Discount 
            txtColumn.HeaderText = "Discount";
            txtColumn.Format = "p"; // percent
            txtColumn.Alignment = HorizontalAlignment.Right;
            txtColumn.Width = 60;
         break;
         case "Quantity": // Quantity 
            txtColumn.HeaderText = "Quantity";
            txtColumn.Alignment = HorizontalAlignment.Right;
             txtColumn.Width = 50;
         break;
         case "ExtendedPrice": // Extended Price 
            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);
   // set DataSource of DataGrid 
   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();
// the Event of 'PrintPage'
prnDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler
			(prnDocument_PrintPage);

To draw something on the report (as line or text):

  1. Get Left Margin, Right Margin, Top Margin, Bottom Margin, Report Width and Report Height:
    // Result of the Event 'PrintPage'
    private void prnDocument_PrintPage(object sender, 
    System.Drawing.Printing.PrintPageEventArgs e)
    {
        leftMargin = (int)e.MarginBounds.Left;  	// leftMargin, rightMargin, 
    					// ... Declared before
        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;
        // Draw Invoice Head
        SetInvoiceHead(e.Graphics); 
    }
  2. Set Font and Color:
    Font InvTitleFont = new Font("Arial", 24, FontStyle.Regular);
    SolidBrush HeadBrush = new SolidBrush(Color.Blue);
  3. Set Font Height and Font Width and coordinate, then use DrawString method:
    private void SetInvoiceHead (Graphics g)
    {
        //Invoice title:
        string InvTitle = "International Food Company";
        //Title Font:
        Font InvTitleFont = new Font("Arial", 24, FontStyle.Regular);
        //Title Color:
        SolidBrush HeadBrush = new SolidBrush(Color.Blue);
        //Title Height:
        int InvTitleHeight = (int)(InvTitleFont.GetHeight(g));
        //Title Length:
        int lenInvTitle = (int)g.MeasureString(InvTitle, InvTitleFont).Width;
        //Coordinate:
        int CurrentX = leftMargin + (InvoiceWidth - 
    	lenInvTitle) / 2; //to set the title in center 
        int CurrentY = topMargin + InvTitleHeight;
        //draw the title:
        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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here