In part 6 of this series, I setup the structure for creating reports. In this post I will review the details to creating a simple Income Statement Report.
In my report I will have data structures that differ from my normal application data. I have defined a custom class named IncomeStatement to store the specialized data for this report.
Using dependency injection, I call the transaction service, WorkingTransactions method. Using Linq, I query the list to return only the transactions with an account number greater than or equal to 400. The income statement should only contain transactions which are of the account types of income (400), cost of goods (500), and expense (600).
Create Income Statement
The CreateReport method takes in the IncomeStatement data and returns a file path to the report it will create. It stores the file path in a variable as the value will be used two times in the method.
It sets up an XmlSerializer to save the IncomeStatement data as XML. It uses a MemoryStream to save the serialized XML IncomeStatement data. This Microsoft forum post has more information on the process.
During a debug session, the XML data is written to file for manual review later.
The IncomeReport.xsl template is loaded. It contains the report design. It is used to transform the serialized income statement XML into FO-XSL.
Another memory stream called foReportMemoryStream is used to store the PDF file generated for the report.
Fo XSL Write Income Statement
The create method calls this method. This is only called once and simply separates the steps to naturally comment the code.
FoNet is used here. The options are set. A MemoryStream is used to retrieve the Fo XSL data and a separate stream is used to save the PDF file.
Below are the available options for Fo.NET PDF file creation. I am only using some of the identifier options.
The report templates can get very large quickly. They do support imports which I use to split up the different sections of my reports. Another benefit to splitting up the sections is code re-use. Many parts can be re-used in different reports.
IncomeReport.xsl imports Transaction.xsl. It is used by calling xsl:call-template with the identification name.
The XML file is exported when the project build is DEBUG. The root element is IncomeStatement. This is what is set as <xsl:template match="IncomeStatement"/> in the template.
The Transactions element contains multiple Transaction records.
The Transactions template uses a table for alignment and placement. It uses a xsl:for-each to loop through and print each transaction record. I am using a Microsoft name space to format the date properly.
Income Statement PDF
The final report looks like this. I plan on adding a chart to this report in the next article of this series.
The complete source code for this project is located on Github.
If you found this article helpful, use the tweet button below to spread the word. Thank you.