pdf links

PDF Rendering
Convert PDF to Image (.NET)
Convert PDF to image on Android (Xamarin)
Convert PDF to image on iOS (Xamarin)
Convert PDF to image in Windows Store apps (.NET)
Convert PDF to image in Windows Phone apps (.NET)
PDF to image in Universal Windows Store apps (.NET)
Free PDF Viewer control for Windows Forms (.NET)
How to integrate PDF Viewer control in WPF app (.NET)
Creating WPF PDF Viewer supporting bookmarks (.NET)
Cross-platform PDF Viewer using GTK# (MONO)
Silverlight PDF viewer control (Silverlight 5)
Multithreaded PDF rendering (.NET)
Convert pdf to image in Silverlight app (C# sample)
How to set fallback fonts for PDF rendering (C#)
Avoiding the out-of-memory exception on rendering (C#)
PDF viewer single page application (WebAPI, AngularJS)
PDF viewer control for Windows 10 universal applications
Use custom ICC profile for CMYK to RGB conversion
PDF layers - separate images, text, annotations, graphics

PDF Forms Creation PDF Security
Conversion to PDF/A
Other topics
PDF Document Manipulation PDF Content Generation
Fixed and Flow layout document API (.NET)
Creation of grids and tables in PDF (C# sample)
How to create interactive documents using Actions (C# sample)
Text flow effects in PDF (C# sample)
How to generate ordered and bulleted lists in PDF (C# sample)
Convert HTML to PDF using flow layout API (C# sample)
How to use custom fonts for PDF generation (.NET)
Create document with differently sized pages (C#)
Create PDF documents using MONO (C#/MONO/Windows/OSX)
How to use background images for content elements (C#/PDF Kit/FlowLayout)
Add transparent images to PDF document (C#)
Draw round rect borders in PDF documents(C#)
ICC color profiles and and ICC based colors in PDF (C#)
How to use bidirectional and right to left text in PDF (C#)
Create PDF documents from XML templates (C# sample)
How to resize PDF pages and use custom stamps (C#)
Add header and footer to PDF page (.NET sample)
How to use clipping mask for drawing on PDF page
Fill graphics path with gradient brushes in PDF (Shadings)
Apitron PDF Kit and Rasterizer engine settings
Add layers to PDF page (optional content, C# sample)
How to create free text annotation with custom appearance
PDF Content Extraction PDF Navigation
PDF to TIFF conversion
Contact us if you have a PDF related question and we'll cover it in our blog.

2015-03-25

Create PDF invoice in Windows Forms application (C# .NET sample)

Introduction


Very common scenario where our .NET PDF library comes into play is invoices or reports generation. With fixed and flow layout API offered by Apitron PDF Kit for .NET, such tasks become quickly solvable.

This post demonstrates how to create basic Windows Forms PDF invoice creation application, similar to the one many companies use on their daily basis. It generates PDF invoice based on entered company and customer info using Apitron PDF Kit .NET component.

The complete sample can be found in Samples\Windows Forms folder inside the download package available on our website.

Solution overview


Our application uses Windows Forms and is written in C#, it has just a single window with all necessary controls in place. It represents an invoicing tool for imaginary company called “Home Depot” which is selling various tools for home use.

Company and customer information should be entered in multiline textboxes and products list should be filled using the data grid below. When the user finishes with the invoice, he or she clicks the Generate button and gets branded PDF invoice created. Image below demonstrates the running app main window with entered information.


Pic. 1 PDF Invoice generator application, main window
As you can see from this screenshot, the controls layout is very basic, but as it’s not the main point in this example, we decided to keep it simple and paid the most attention to the PDF generation part of the app.

Here you can see the resulting invoice generated from data set shown on the first picture. As an addition to the entered data, it contains the company logo in the page header and stamp image. See the image below:


Pic. 2 Created PDF invoice

The code


We won’t dive into windows forms specifics here and focus only on PDF generation and related code. A few functions responsible for this are listed below:

/// <summary>
/// Generates the invoice based on entered data.
/// </summary>
/// <param name="stream">Stream to save the resulting pdf into.</param>
private void GenerateInvoice(Stream stream)
{
    // base path for images
    string imagesPath = @"..\..\images";
    // create document and register styles
    FlowDocument document = new FlowDocument();
    /* style for products table header, assigned via type + class selectors */
    document.StyleManager.RegisterStyle("gridrow.tableHeader",
        new Style() {Background = RgbColors.LightSlateGray});

    /* style matching all cells in rows with class "centerAlignedCells" set
        and all cells in rows with class "centerAlignedCell" set */
    document.StyleManager.RegisterStyle("gridrow.centerAlignedCells > *,
 gridrow > *.centerAlignedCell",
        new Style() {Align = Align.Center, Margin = new Thickness(0)});

    /* style matching all elements in rows with class "leftAlignedCell" set */
    document.StyleManager.RegisterStyle("gridrow > *.leftAlignedCell",
        new Style() {Align = Align.Left, Margin = new Thickness(5, 0, 0, 0)});

    /* default style for any cell in any grid row, assigned via type + child selectors,
 makes it right aligned */
    document.StyleManager.RegisterStyle("gridrow > *",
        new Style() {Align = Align.Right, Margin = new Thickness(0, 0, 5, 0)});

    // create resource manager and register image resources
    ResourceManager resourceManager = new ResourceManager();
    resourceManager.RegisterResource(
        new Apitron.PDF.Kit.FixedLayout.Resources.XObjects.Image("logo",
        Path.Combine(imagesPath, "storeLogo.png"), true) {Interpolate = true});

    resourceManager.RegisterResource(
        new Apitron.PDF.Kit.FixedLayout.Resources.XObjects.Image("stamp",
        Path.Combine(imagesPath, "stamp.png"), true) {Interpolate = true});

    // construct page header which includes store logo and the text "Invoice"
    document.PageHeader.Margin = new Thickness(0, 40, 0, 20);
    document.PageHeader.Padding = new Thickness(10, 0, 10, 0);
    document.PageHeader.Height = 120;
    document.PageHeader.Background = RgbColors.LightGray;
    document.PageHeader.LineHeight = 60;
    document.PageHeader.Add(new Image("logo"
       {Height = 50, Width = 50, VerticalAlign = VerticalAlign.Middle});
    document.PageHeader.Add(new TextBlock("Invoice")
                            {
                                Display = Display.InlineBlock,
                                Align = Align.Right,
                                Font = new Font(StandardFonts.CourierBold, 20),
                                Color = RgbColors.Black
                            });

    // page content section with padding
    Section pageSection = new Section() {Padding = new Thickness(20)};

    // add company info section
    pageSection.AddItems(CreateInfoSubsections(new string[] {txtCompany.Text, 
        "Bill to:\r\n" + txtCustomerInfo.Text}));

    // add horizontal line for visual separation
    pageSection.Add(new Hr() {Padding = new Thickness(0, 20, 0, 20)});

    // add products grid        
    pageSection.Add(CreateProductsGrid());

    // add new line after grid
    pageSection.Add(new Br {Height = 20});

    // insert empty padding section and stamp image
    pageSection.Add(new Section() {Width = 250, Display = Display.InlineBlock});
    pageSection.Add(new Image("stamp"));

    // add page section into document
    document.Add(pageSection);
    // save document to stream
    document.Write(stream, resourceManager, new PageBoundary(Boundaries.A4));
}

Creates information sections located above the products table:

/// <summary>
/// Creates several info sections side by side based on given list of strings.
/// </summary>
/// <returns>
/// List of created sections with textual information.
/// </returns>
private IList<Section> CreateInfoSubsections(string[] info)
{
    List<Section> createdSections = new List<Section>();
    double width = 100.0/info.Length;

    for (int i = 0; i < info.Length; i++)
    {
        Section section = new Section() {Width = Length.FromPercentage(width),
Display = Display.InlineBlock};

        using (StringReader reader = new StringReader(info[i]))
        {
            string currentLine = null;

            while ((currentLine = reader.ReadLine()) != null)
            {
                section.Add(new TextBlock(currentLine));
                section.Add(new Br());
            }
        }
        createdSections.Add(section);
    }

    return createdSections;
}

Creates products grid:

/// <summary>
/// Creates products grid.
/// </summary>
private Grid CreateProductsGrid()
{
    // create grid content element and its define columnts
    Grid productsGrid = new Grid(20, Length.Auto, 30, 50, 55, 60);
    // add header row
    productsGrid.Add(new GridRow(new TextBlock("#"), new TextBlock("Product"), 
        new TextBlock("Qty."),
        new TextBlock("Price"), new TextBlock("Disc.(%)"), new TextBlock("Total"))
                        {
                            Class = "tableHeader centerAlignedCells"
                        });

    Decimal invoiceTotal = 0;

    // enumerate the list of products and create grid rows
    foreach (ProductEntry product in products)
    {
        TextBlock pos = new TextBlock(product.Pos.ToString()) {Class = "centerAlignedCell"};

        TextBlock description = new TextBlock(product.Description) 
           {Class = "leftAlignedCell"};

        TextBlock qty = new TextBlock(product.Qty.ToString()) {Class = "centerAlignedCell"};

        TextBlock price = new TextBlock(
           product.Price.ToString(CultureInfo.InvariantCulture));

        TextBlock discount = new TextBlock(
           product.Discount.ToString(CultureInfo.InvariantCulture));

        TextBlock total = new TextBlock(
           product.Total.ToString(CultureInfo.InvariantCulture));

        productsGrid.Add(new GridRow(pos, description, qty, price, discount, total));
        invoiceTotal += product.Total;
    }

    // append "total" row
    productsGrid.Add(new GridRow(new TextBlock("Total(USD)") {ColSpan = 4},
        new TextBlock(invoiceTotal.ToString(CultureInfo.InvariantCulture)) {ColSpan = 2}));

    return productsGrid;
}

Definitions for all used styles and their descriptions can be found at the beginning of the GenerateInvoice function which is responsible for combining all parts of the invoice together.


Conclusion


Using small piece of code we managed to create a fully functional Windows Forms PDF invoice generator. Apitron PDF Kit offers unlimited capabilities for developers interested in PDF processing and a good way to start is to read the book, describing it step by step with code samples and references to original specification. This free book is available for download from our website.

We created plenty of C# samples for various platforms and included them in our download package. These samples demonstrate every aspect of PDF processing and, sometimes, can be adapted to your applications with minimal modifications. Windows desktop, Windows Phone, Windows Store, Xamarin iOS and Android, .NET/Mono – our component covers them all. We also offer free evaluation and royalty-free licensing. Contact us if you have any questions and we’ll do our best to help you. 

Downloadable version of this article can be found by the following link [PDF].

No comments:

Post a Comment