Introduction
There are many tools out there for reports, varying by price, capabilities and learning curves. I wanted an ASAP tool (As Simple As Possible :-)) to produce HTML outputs and view them with emphasis on dynamic creation capability. Once we have an HTML previewer, there are plenty of PDF converters out there, that may carry on to provide us the final professional touch. I personally recommend the PDF virtual printers for their ease of use.
I started out with making a reporter for ADO DataSet
s. I used XSLT with .NET's XSL and XPath capabilities, and off I went.
The general idea
The design is pretty straight forward. We take XML and a pre-created XSLT and transform into HTML.
I've decided on the following line of functionality:
Validate()
- make sure this is a well formed schema with consecutive data.
PreTransformationEdits()
- if we need to edit the XML before we transform.
Transform()
- merge the XML and XSLT into a happy HTML.
PostTransformationEdits()
- for last minute HTML edits.
ShowHtml()
- the actual previewing.
The specifics
The DataSet
is provided as stream, and it is firstly validated as a proper DataSet
XML schema. I've not spent much time on any other validations since DataSet
s are usually well formatted :
XmlNodeList Tables =
XmlData.SelectNodes("/*/xs:schema/xs:element/xs:complexType/xs:choice/xs:element",
m_NamespaceMgr);
if ( Tables.Count == 0 )
{
throw new Exception( C_ERR_NO_TABLES );
}
Now, we run the pre-transformation edits. We have to install the dynamically set attributes such as font color etc. into the style tag part of the XSLT in order to impact the HTML. This is done in the AmendCSSAttributes()
.
Next, we have to calculate the right widths each column will now have in order to fit A4, done in the ParseColumnWidths()
function.
Now, the actual transformation: we combine the input XML with the XSLT resource embedded in the project into the resulting HTML.
Assembly myAssembly = Assembly.GetAssembly( this.GetType() );
XSLTStream = myAssembly.GetManifestResourceStream( C_TRANSLATOR_RESOURCE_NAME );
XPathDocument styleSheet = new XPathDocument( XSLTStream );
XslTransform XslTransformer = new XslTransform();
XslTransformer.Load( styleSheet,null,null );
XslTransformer.Transform( XmlData,null,OutputStream,null );
OutputStream.Seek( 0 ,SeekOrigin.Begin );
The next phase is the post-transformation edits, which I defined but didn't really need as per now.
And lastly, we show the result using an embedded IExplorer control (AxSHDocVw.AxWebBrowser
control). For that, we first have to save the result as a temporary HTML file. So, I generate it into the temporary internet cache folder and name it with a new GUID to make it unique.
What to expect / not expect
- The tool knows its ways around the printer (thanks to one dear Chris Sells and his great book - Windows Forms Programming in C#).
- You can require it to expand beyond A4 or squeeze right into it.
- You can decide on the fly on font colors and background colors for the table header and row lines.
- You can decide which scroll bars will appear (width/height/both/none).
- You can set any row height and font size you wish.
- You can pick your own application consistent icon and title for the previewer screen.
What is missing?
- More HTML table styling.
- Page breaks. Although XSLT code documents how it should be done, still the job is out there.
- Title / Subject / Abstract inside the HTML.
- Directly accepting
DataSet
s instead of stream - a real easy one, will be added soon.
Writing this package has a lot to do with predefining the right scope for it. You can easily upscale the requirements of this library, the most blunt requirement would be to make the tool support more report types (i.e., not only tables).
Quick example
dsQueryResult =
SqlHelper.ExecuteDataSet(Connstr,
CommandType.Text,"Select * from suppliers" );
dsQueryResult.WriteXml( @"C:\temp\result.xml",XmlWriteMode.WriteSchema );
FileStream read = new FileStream( @"c:\temp\result.xml",FileMode.Open );
ReportViewer rpView = new ReportViewer();
rpView.CellScrollBehaviour = ReportViewer.CellScrollBars.Horizontal;
rpView.RowColor = Color.Green;
rpView.AppTitle = "My demo view";
rpView.StretchLayout = false;
rpView.ShowReport( read );
read.Close();
dsQueryResult.Dispose();
Future versions
This is the first version and any future version very much depends on my tight schedule.
You are invited to send suggestions etc. to me, please keep them as less tedious as possible :-) ( i.e., code snippets and not complete attachments ).
Best of luck.