Previously
Previously, when presented with a heap of data like this:
with a little html coding I turned it into this:
So the question is how?
How NOT to do it?
My first attempt had heaps of HTML code scattered inside my program. It worked, but it was so messy to try to maintain. Every time I wanted to change something, I needed to edit syntax, recompile & test.
Second attempt, was reading the C# report generation libraries. <YUK!>
Third attempt, was looking into XSLT and XML transforms. <Bigger YUK!>
Generally I found that I needed to learn a whole new library/language just to write a little HTML.
I needed a simpler solution.
Which was?
Lets look at some simple HTML, something like this
<html>
<body>
<h1>Name: [add name here]</h1>
etc,etc,etc
</body>
</html>
Simple enough right?
So we save this HTML off as our ‘template’, then the main code looks like:
- Load the template in
- Edit the template with a set of copy-paste actions
- Save the completed report
Quite straight forward right?
Show me the code!
Ok:
void makeReport()
{
StringBuilder buffer = new StringBuilder();
// read the template file
buffer.append(File.ReadAllText("template/report.html"));
// make changes
buffer.replace("[add name here]", "mark gossage");
// save the final copy
File.WriteAllText("result/report.html",buffer.ToString()) ;
}
That’s it, kind of trivial isn’t it? 4 lines of code. But it works!!!!
I coded this example in C#, but you could have used python, perl, C++ or any other language you are familiar with.
What about a more complex example?
Life does get a bit more complex when you want a multiline table, but its still not that hard.
Starting with an html template like this:
<html>
<body>
<h1>Some Table Data</h1>
<table>
<tr><td>Name</td><td>Date</td></tr>
<!-- begin row-->
<tr>
<td>[add name here]</td>
<td>[add data here]</td>
</tr>
<!-- end row-->
</table>
</body>
</html>
You can do the same thing, you just need to duplicate the data between the ‘begin row’ and ‘end row’ as many times as needed.
The code looks generally like this:
void makeReport()
{
// assuming buffer holds the template
// find the section
string data = buffer.ToString();
int startIdx = data.IndexOf("<!-- begin row-->");
int endIdx = data.IndexOf("<!-- end row-->");
startIdx+=start.Length; // startIdx is at end of the 'start' string
// get the 'row'
string row=data.Substring(startIdx, endIdx - startIdx);
// temp buffer for working with
StringBuilder temp=new StringBuilder();
// for each item needed
for(...)
{
temp.append(row); // add the row in
// make changes
temp.replace("[add name here]", ...);
temp.replace("[add date here]",...);
}
// replace the 'row' with the data
buffer.replace(row,temp.ToString());
// save the stuff
}
This works perfectly, but is a little untidy, as it leaves the ‘begin row’, ‘end row’ tags in the file. But its only a couple of lines of code to fix that issue.
Conclusion
Another short & simple post.
No complex frameworks, no clever use of the language.
Just some simple common sense & problem solving.
You could write some kind of helper functions/class to do this job for you (I did).
Now my reports just need a little work in some HTML and a lot of search-replace.
Happy Coding,
Mark
No comments:
Post a Comment