Source code for a simple .NET report application
This simplified .NET report program shows you the basic C# code you would need to create a .NET report application.
This C# program completes the basic needs for any Genero Report Writer program:
- Creates the data model.
- Loads the data into memory.
- Configures the output of the report.
- Streams the data to the report engine.
The report is a simple example of a C# report program. In a real world situation, the data would be read from another source, and an iterator would read the data into memory and into the data stream one record at a time.
using FourJs.Report.Runtime;
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace Sales
{
//The XmlRoot annotation causes an global element declaration to be produced in the schema.
[Serializable]
[XmlRoot]
public class Sales
{
//The XmlElement annotation maps a property to an XML element.
//The Genero Engine does not support optional variables so setting "IsNullable = true" is mandatory.
//If a variable needs to be optional then set the variable to null whenthere is no value.
//If a primitive type needs to be optional then use the c# nullable type
//instead (e.g "int?" for "int").
[XmlElementAttribute(IsNullable = true)]
public String shopName;
public int zipCode;
public DateTime day;
//This and any other public collection will be serialized in the order they are declared descending //recursively into the classes contained in the collections.
[XmlElementAttribute(IsNullable = true)]
public List<SalesItem> items;
public Sales(String shopName, int zipCode, DateTime day)
{
this.items = new List<SalesItem>();
this.shopName = shopName;
this.zipCode = zipCode;
this.day = day;
int i = 0;
items.Add(new SalesItem("Tablelamp", SalesItem.Category.Furniture, 23.00, null));
items.Add(new SalesItem("Tablelamp", SalesItem.Category.Furniture, 267.00, items[i++]));
items.Add(new SalesItem("Officechair", SalesItem.Category.Furniture, 155.00, items[i++]));
items.Add(new SalesItem("Grandfather clock", SalesItem.Category.Furniture, 329.00, items[i++]));
items.Add(new SalesItem("Scissors", SalesItem.Category.Supplies, 19.00, items[i++]));
items.Add(new SalesItem("Measuring tape", SalesItem.Category.Supplies, 23.00, items[i++]));
items.Add(new SalesItem("Sunglasses", SalesItem.Category.Travelling, 15.95, items[i++]));
items.Add(new SalesItem("Penknife", SalesItem.Category.Travelling, 6.25, items[i++]));
items.Add(new SalesItem("Ornateangel", SalesItem.Category.Art, 1.95, items[i++]));
}
/** Default Constructor that is required for deserialization.
In this program this is never used.
*/
public Sales()
{
}
/**
Runs the report using the design file specified in args[0] or "SalesList.4rp" otherwise.
The program creates the file "SalesList.pdf" and opens it using
System.Diagnostics.Process.Start which will typically
invoke the Acrobat Reader.
*/
static void Main(string[] args)
{
String designFile;
String outputFilename = "SalesList.pdf";
if (args.Length == 0)
{
designFile = "..\\SalesList.4rp";
}
else
{
designFile = args[0];
}
FormatHandler handler = new FormatWriter(outputFilename);
PDFRenderer renderer = new PDFRenderer(handler);
FourRpLayouter report = new FourRpLayouter(designFile, renderer);
report.debugLevel = 9;
Sales data = new Sales("Columbus Arts", 75038, new DateTime());
report.runFromSerializable(data);
// open the file
System.Diagnostics.Process.Start(outputFilename);
}
}
public class SalesItem
{
public enum Category { Furniture, Art, Supplies, Travelling };
[XmlElementAttribute(IsNullable = true)]
public String articleName;
public Category category;
public double price;
public double runningTotal;
//The previous item is passed to allow computing the running total.
public SalesItem(String articleName, Category category, double price, SalesItem previousItem)
{
this.articleName = articleName;
this.category = category;
this.price = price;
this.runningTotal = previousItem == null ? price : previousItem.runningTotal + price;
}
/** Default Constructor that is required for deserialization.
In this program this is never used.
*/
public SalesItem() { }
}
}
An overview of the simple report
public class Sales- whereSalesrepresents the sales of a particular shop on a particular day.Public class SalesItem- whereSalesItemrepresents the individual items sold in the shop on that day.
The classes are not required to implement any specific interfaces or to be extensions of a specific class. These classes are annotated to hint to the serializer how these objects are to be serialized to XML.
- The Report Model Objects, which specify the data the report will include.
- A
mainmethod to run the report using a simple list design and to view the result in PDF format.
Using this API is the method proposed in this example.
Mandatory C# classes to be imported
using FourJs.Report.Runtime;
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
XML annotations
Serializable- The
Serializableannotation marks classes that should be serialized.[Serializable] XmlRoot- The
XmlRootannotation causes a global element declaration to be produced in the schema.... [XmlRoot] public class Sales { ... XmlElementAttribute- The
XmlElementAttributeannotation maps a property to an XML element.[XmlElementAttribute(IsNullable = true)] public String shopName;Note:The Genero Report Engine does not support optional values. If a variable needs to be optional, use "
isNullable=true" and set the variable to null when there is no value.
Genero Report Writer APIs and C# code highlights
- Use a handler
object.
FormatHandler handler = new FormatWriter(outputFilename); - Define a renderer according to the expected output format. In this example, the
PDFRendereris specified. See Change report output format (C#) for a summary of your choices.PDFRenderer renderer = new PDFRenderer(handler); - Create the report object specifying the report design file and the renderer
object.
FourRpLayouter report = new FourRpLayouter(designFile, renderer); - Specify the data.
Sales data = new Sales("Columbus Arts", 75038, new DateTime()); - Run the report.
report.runFromSerializable(data);The following is an alternative method for running a report, using a data file (.xml) instead of a database.
In our simple program, no iterator is specified. All the data is in memory, and the standard iterator goes through that list in memory, done internally by
runFromSerializable. To see code that uses an iterator, examine the code in the OrderReportCSharp demo.report.runFromXML("my_data_file.xml"); - Generate the report file on
disk.
File result = new File(outputFilename);