Friday 31 July 2009

Sick of my phone

I am totally sick of my phone just now. For the past five years I have been using Nokia phones, mainly S60 smartphones. However, over the last few years I have been getting more and more frustrated with the S60 OS. It sees to me that once Nokia gained control of Symbian (at least I think it did) things started getting bad.

At the present time, I use an N96 - when it wants to work. Recently, one of my friends at work got hold of the HTC Hero, a smartphone that uses Google's Android 1.5. As far as I am concerened, it out cools the iPhone. However, I dont know if I want to get another smartphone. Right now I am thinking about getting a normal phone and some form of Internet Tablet/PDA - ironically I am looking at getting a Nokia N810. My reasons for this? Well, out of the box it runs a Linux, but you can also install Android on it as well :).

PDF Generation with PDFJet

As mentioned previously, I have been working a lot on report generation. Where I work just now, we produce a lot of reports. A lot of them are produced manually and are very large. An ideal candidate for automation.

I need to produce them in a number of different formats, pdf is the first one I tackled. All of the reports I need to produce use tables, so I needed to find a .Net pdf library that had this functionality. I took a look at what was on offer, open source, closed source and commercial. I went for a lib called PDFJet. This is a fairly mature Java pdf library that has been ported over to .Net for C# http://www.pdfjet.com/. Its fairly cheap and whilst it lacks a lot of in depth examples, there are quite a few available on their website. The support is really good too - if you have a question, the guys are able to provide feedback very quickly.

It is very well featured, but I am basically using it to generate tables from datatables. I have been using it in earnest for about a week now, so I will try and post some examples of how it can be used here. There are two ways of creating a table with PDFJet, you can use a delimited text file holding the data you need or you can build a table programatically. Doing it in the code is quite tricky, to do this you need to build a list of lists of type cell - not as easy as it sounds... However, I am very impressed with this library and the things it can do.

Automatically invoke methods from a given class

Had an interesting problem at work this week. I have been working on a way to automatically generate a number of (lengthy) reports in a number of different formats. Each report has a number of sections that in turn hold a number of subsections. Each subsection holds either a chart or a table. Each report needs to be presented as either a pdf, a doc, an xls or a csv file. Some of the sections in each report are used in other reports.

I came round to designing each section as a class, in each class is a method that generates either a datatable to build a table from or a chart generated as an image. I wanted the generation of these datatables and images to be as generic as possible, the methods called provide the objects I needed but the way I call them needed to be as generic as I could get it. So, instead of putting together a method that calls all of these other methods I came up with the idea of building a list of all the methods I need to call in order to generate a report. To do this, I used reflection.

Firstly, I needed to get a list of all the method names I wanted to call.
List<MethodInfo> sectionNames = new List<MethodInfo>();
Sections s = new Sections(conn);
Type t = s.GetType();
MethodInfo[] mi = t.GetMethods();
foreach (MethodInfo method in mi)
{
sectionNames.Add(method);
}


In this example, Sections is the name of the class holding the methods I need to generate a report. It populates its datatables from a database, so the conn variable holds the connection string needed. There are a lot of sections in the report I was working on, so I split each section up as partial classes. Using GetMethods () on my class returns all of the available methods within that class. With that information, I simply create a list of type MethodInfo and add each element of the array I have created to the list. I dont really need to do this, but at some point I am going to want to sort the list, which is a little easier than sorting the array (from my perspective). I now have a list of all the method names available in my class. The next thing I do is get rid of some of the generic methods, like GetType(). I dont know if there is a cleaner way of doing this, so all I am doing right now is deleting a range from the list:


sectionNames.RemoveRange(8, 4);

Now I have almost everything I need. Next up, I need to invoke the method and capture its return. The first type of report I tackled was a pdf. The library I am using to create these pdf's uses delimited text files to create tables (it can be done programatically, but I havent mastered this yet). So, I need to create a dictionary holding the name of the text file I want to create and the name of the method to create it from. Now, I also mentioned that my report will also hold charts generated as images - so the dictionary I create needs to hold a string and an object, not a string and a datatable or any other type. It may not be the cleanest way to do it, but I can cast the object as a datatable later on, anyway...
Dictionary<string, Object> content = new Dictionary<string, Object>();


Thats my dictionary ready to go, I just need to populate it with filenames and object. This isnt as hard as it seems, because my list contains type MethodInfo I can use the Invoke method to call all of the methods in the list. Thats a bit of a mouthful really, so it is better to demonstrate:


foreach (MethodInfo method in sectionNames)
{
object obj = method.Invoke(s, null);
content.Add(method.Name + ".txt", obj);
}


I loop through each MethodInfo type in my list. I create an object called obj, this becomes the return from each of the methods I call using Invoke. Once called and invoked, I add the result to my dictionary, on success the dictionary contains a key value pair representing a string filename and an object. You can see in the example above that the filename is always a .txt - this is bad when it comes to images (I am not creating any just yet). But, this can be worked around by getting the type of the object etc. However, right now this is all I need to create my text files to use with my pdf generation. I simply loop through the dictionary creating a textfile from the contents of the object (which is a datatable dont forget), the string is the filename the text file is created with.

Its not very efficient just now, I need to manage the methods in the dictionary - I need to remove the generic ones prior to adding them and I need to sort them in order, both things I either do manually or not at all right now. But this is a nice little example of how methods can be gathered from a class and then dynamically invoked. The complete source for this example is as follows:


/// <summary>
/// Creates a Dictionary of strings and object representing the content we want to build
/// </summary>
/// <returns>a Dictionary of strings and objects holding the filename and the datatable</returns>
private Dictionary<string, Object> Contents()
{
List<MethodInfo> sectionNames = new List<MethodInfo>();
Sections s = new Sections(conn);
Type t = s.GetType();
MethodInfo[] mi = t.GetMethods();
foreach (MethodInfo method in mi)
{
sectionNames.Add(method);
}
sectionNames.RemoveRange(8, 4);
sectionNames.Sort();
Dictionary<string, Object> content = new Dictionary<string, Object>();
foreach (MethodInfo method in sectionNames)
{
object obj = method.Invoke(s, null);
Console.WriteLine(obj);
content.Add(method.Name + ".txt", obj);
}
return content;

I will also post the file creation method that works with this after the weekend as well as some bits and peices to do with the pdf library I am using. But hopefully this should be enough to get someone else on the right track if they are also considering such a soloution.