I was describing how a simple yet extensible report-generator could be implemented quickly to somebody. I’m posting it here as some of you might find it useful (and I can refer to this link in future conversations
).
The concept:
…is really simple. The idea is to look for a placeholder like @Fruit and replace it with “Apple”. However to make the whole thing extensible, reflection is used. When calling the report generator, you need to specify a reportInput object (can be of any type), in addition to the file-paths of input and output reports. The report-generator uses reflection to determine the properties available on the reportInput object. For each property, it derives a tag name and substitutes the derived tag name with the actual property value in the input file. The text read from the input file after making replacements is finally written to the output file. For further extensibility, the tag format is not hard-coded and can be specified as an argument.
Before (an RTF file with placeholders):
After (an RTF file with placeholders replaced with values):
The code:
public static class SimpleReportGenerator
{
public static void Generate(string inputFilePath, string outputFilePath, object reportInput, string tagFormat)
{
if (string.IsNullOrEmpty(inputFilePath))
throw new ArgumentException(“inputFilePath”);
if (string.IsNullOrEmpty(outputFilePath))
throw new ArgumentException(“outputFilePath”);
if (reportInput == null)
throw new ArgumentNullException(“reportInput”);
if (string.IsNullOrEmpty(tagFormat))
throw new ArgumentException(“tagFormat”);
string inputFileText = File.ReadAllText(inputFilePath);
StringBuilder reportOutput = new StringBuilder(inputFileText);
Type reportInputType = reportInput.GetType();
PropertyInfo[] properties = reportInputType.GetProperties();
foreach (PropertyInfo property in properties)
{
string propertyTag = String.Format(tagFormat, property.Name);
object propertyValueObj = property.GetValue(reportInput, null);
string propertyValue = (propertyValueObj != null) ? propertyValueObj.ToString() : String.Empty;
reportOutput.Replace(propertyTag, propertyValue);
}
File.WriteAllText(outputFilePath, reportOutput.ToString());
}
}
An example:
Defining ReportInput
public class ReportInput
{
public string ReportTitle { get; set; }
public string ReportHeading { get; set; }
public string ReportBody { get; set; }
public string ReportAuthor { get; set; }
public DateTime ReportDate { get; set; }
}
Creating a ReportInput for testing
public ReportInput GetTest()
{
ReportInput input = new ReportInput() { ReportAuthor = “John Doe”, ReportBody = “A quick brown fox jumped over a lazy dog”, ReportDate = DateTime.Now, ReportHeading = “The new report”, ReportTitle = “Here we go” };
return input;
}
Generating a report
string input = “testreport.rtf”;
string output = “testreport_out.rtf”;
ReportInput reportInput = GetTest();
// “@{0}” indicates that a property named “Foo” corresponds to “@Foo” tag in the input file.
SimpleReportGenerator.Generate(input, output, reportInput, “@{0}”);







Very neat idea. If there only was also a method for inserting/replacing images into the rtf document it would be a solid and valid solution.
Hi,
i createad a report template with MS WORD, but the placeholders aren’t the string continous ( es…” @{….fs20\lang1024\loch\f3\fs20\lang1024 …. ReportTitle}} , so when run the application don’t replace placeholder with value.
How can I avoid this?
What version of Word are you using?