# Reporting: Expense Report with Business Objects

> A C# sample generates a pixel-perfect expense report using the MailMerge engine with business objects as the data source. XML deserialization via XmlSerializer maps data into typed classes, and calculated properties like totals and tax values live in the objects themselves.

- **Author:** Bjoern Meyer
- **Published:** 2014-05-09
- **Modified:** 2026-03-05
- **Description:** A C# sample generates a pixel-perfect expense report using the MailMerge engine with business objects as the data source. XML deserialization via XmlSerializer maps data into typed classes, and calculated properties like totals and tax values live in the objects themselves.
- **3 min read** (522 words)
- **Tags:**
  - Reporting
  - Tutorial
- **Web URL:** https://www.textcontrol.com/blog/2014/05/09/reporting-expense-report-with-business-objects/
- **LLMs URL:** https://www.textcontrol.com/blog/2014/05/09/reporting-expense-report-with-business-objects/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2014/05/09/reporting-expense-report-with-business-objects/llms-full.txt

---

In this tutorial, you will learn how to create this pixel-perfect **Expense Report** using Text Control Reporting and business objects as a data source:

![Reporting: Expense Report with Business Objects](https://s1-www.textcontrol.com/assets/dist/blog/2014/05/09/a/assets/tx_sample_expense_results.webp "Reporting: Expense Report with Business Objects")An expense report contains general data such as the purpose of the expense, the pay period and a statement number. Additionally, it should list the employee details and finally, the expenses itself. The class diagram of the business object is illustrated below:

![Reporting: Expense Report with Business Objects](https://s1-www.textcontrol.com/assets/dist/blog/2014/05/09/a/assets/tx_architecture.webp "Reporting: Expense Report with Business Objects")- **Expenses:** This is an IEnumerable wrapper object for the separate **Expense** reports. This object is passed to Text Control Reporting.
- **Expense:** The expense report itself.
- **Exployee:** Information about the employee referenced in **Expense**.
- **LineItem:** Details of each expense referenced in **Expense**.

The business object **Expenses** has some useful features. It contains XML Serialization attributes which allows us to use an XML data source that is deserialized into the business object automatically.

```
[XmlType("expenses", IncludeInSchema = true)]
public class Expenses : List<Expense>
{
    [XmlElement("expense")]
    public List<Expense> expenses { get; set; }
}

...
```

The attributes define which XML element is mapped to which member of the object. An [XmlSerializer](http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.110%29.aspx) is used to deserialize the XML in order to create a new instance of the business object.

```
XmlSerializer serializer = new XmlSerializer(typeof(Expenses));
Expenses expenses = (Expenses)serializer.Deserialize(
    new StreamReader("expense_report_data.xml"));
```

Additionally, we don't need to store all values in our XML file (or database in real life applications). The business object contains the logic and the code to calculate specific field values internally. All inverted members in the above illustration are not imported from the XML, but calculated on the fly in the business object itself.

The following code shows how the **Total** value is calculated based on existing values:

```
public double Total
{
    get
    {
        double dTotal = 0;

        foreach (LineItem item in this.LineItems)
        {
            dTotal += item.line_total;
        }

        return dTotal - this.Advances;
    }
}
```

In order to start the merge process itself, only 1 line of code is required:

```
mailMerge1.MergeObjects(expenses);
```

Text Control's Reporting engine [MailMerge](https://docs.textcontrol.com/textcontrol/windows-forms/ref.txtextcontrol.documentserver.mailmerge.class.htm) is mapping the merge fields to the business object members and related objects automatically.

The sample project, written in C#, is very easy to use:

1. Start Visual Studio and load the sample project.
2. Compile and start the project.
3. The template is already merged and you can use the arrow buttons to navigate through the created documents.
    
    ![Sample project: Text Control Reporting](https://s1-www.textcontrol.com/assets/dist/blog/2014/05/09/a/assets/tx_results.webp "Sample project: Text Control Reporting")

You can [download the sample project](https://s1-www.textcontrol.com/assets/dist/blog/2014/05/09/a/assets/tx_reporting_expensereport.zip) and test it on your own. At least, a [TX Text Control .NET for Windows Forms trial version](https://www.textcontrol.com/product/tx-text-control-dotnet-winforms/download/) is required.

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Creating Your First ASP.NET Reporting Application](https://www.textcontrol.com/blog/2020/01/01/creating-your-first-aspnet-reporting-application/llms.txt)
- [New Online Sample: Build your First Report](https://www.textcontrol.com/blog/2019/07/03/build-your-first-report/llms.txt)
- [Create your First Document with ReportingCloud](https://www.textcontrol.com/blog/2019/02/19/create-your-first-document-with-reportingcloud/llms.txt)
- [MailMerge: Starting Each Merge Block on a New Page](https://www.textcontrol.com/blog/2016/09/09/mailmerge-starting-each-merge-block-on-a-new-page/llms.txt)
- [Using MailMerge with JSON Data](https://www.textcontrol.com/blog/2015/08/04/using-mailmerge-with-json-data/llms.txt)
- [Merging Documents with RESTful Web API's](https://www.textcontrol.com/blog/2015/07/31/merging-documents-with-restful-web-apis/llms.txt)
- [Windows Forms: Printing Multiple Pages Per Sheet](https://www.textcontrol.com/blog/2015/07/24/windows-forms-printing-multiple-pages-per-sheet/llms.txt)
- [Inserting Watermark Images to All Pages Dynamically](https://www.textcontrol.com/blog/2015/07/17/inserting-watermark-images-to-all-pages-dynamically/llms.txt)
- [Reporting: Sorting Merge Block Rows by Column Name](https://www.textcontrol.com/blog/2015/07/15/reporting-sorting-merge-block-rows-by-column-name/llms.txt)
- [MailMerge with the Entity Framework Using Database First](https://www.textcontrol.com/blog/2015/06/24/mailmerge-with-the-entity-framework-using-database-first/llms.txt)
- [Checked and Unchecked Check Boxes with IF Fields](https://www.textcontrol.com/blog/2015/03/25/checked-and-unchecked-check-boxes-with-if-fields/llms.txt)
- [Reporting: Conditional Formatted Text Blocks](https://www.textcontrol.com/blog/2015/03/13/reporting-conditional-formatted-text-blocks/llms.txt)
- [Reporting Best Practices and How-To Guides](https://www.textcontrol.com/blog/2015/02/05/reporting-best-practices-and-how-to-guides/llms.txt)
- [MailMerge: Master Table and Client Tables](https://www.textcontrol.com/blog/2015/01/28/mailmerge-master-table-and-client-tables/llms.txt)
- [MailMerge: Formatting Numeric Strings in Merge Fields](https://www.textcontrol.com/blog/2015/01/22/mailmerge-formatting-numeric-strings-in-merge-fields/llms.txt)
- [MailMerge: Merge CheckBoxes During the Merge Process](https://www.textcontrol.com/blog/2015/01/12/mailmerge-merge-checkboxes-during-the-merge-process/llms.txt)
- [MailMerge: Conditional INCLUDETEXT Fields](https://www.textcontrol.com/blog/2015/01/08/mailmerge-conditional-includetext-fields/llms.txt)
- [HTML5 Technical Considerations - The Concept Explained](https://www.textcontrol.com/blog/2014/10/16/html5-technical-considerations-the-concept-explained/llms.txt)
- [TX Text Control Web: Attaching Events to Ribbon Elements](https://www.textcontrol.com/blog/2014/10/07/tx-text-control-web-attaching-events-to-ribbon-elements/llms.txt)
- [TX Text Control Web: Customize the Ribbon Bar](https://www.textcontrol.com/blog/2014/10/03/tx-text-control-web-customize-the-ribbon-bar/llms.txt)
- [Text Control Web - Fundamental Concepts: The Data Source](https://www.textcontrol.com/blog/2014/10/02/text-control-web-fundamental-concepts-the-data-source/llms.txt)
- [Reporting: Removing Empty Table Rows](https://www.textcontrol.com/blog/2014/09/30/reporting-removing-empty-table-rows/llms.txt)
- [MS Word Content Controls Field Adapter Classes](https://www.textcontrol.com/blog/2014/08/05/ms-word-content-controls-field-adapter-classes/llms.txt)
- [Reporting: Merge Blocks and Structured Numbered Lists](https://www.textcontrol.com/blog/2014/07/29/reporting-merge-blocks-and-structured-numbered-lists/llms.txt)
- [Creating Avery Labels Using Text Control Reporting](https://www.textcontrol.com/blog/2014/07/22/creating-avery-labels-using-text-control-reporting/llms.txt)
