ARTICLE

How to use C# to Print Invoice

Posted by Mostafa Kaisoun Articles | C# Language May 14, 2012
This is a trial to print Invoice with C# using PrintPreviewDialog control and PrintDocument control.
Reader Level:
Download Files:
 

 Introduction

This is a example of how to print an Invoice with C#. It shows:

  • 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 an Invoice total?

Clipboard04.jpg

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 the database; also you can change my SQL string to bind a DataGrid with data.

About the Code

Bind the DataGrid in frmInvoice form with all Orders:

// 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 " +
    "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 the 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 the Font Height and Font Width and coordinate then use the 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.

COMMENT USING