Skip to main content
Windward

Advanced Programming Example

engine-wiki-logo.pngOverview

This article contains information on advanced .NET Engine features.

Multiple Report Formats

Now let’s assume that all documents created by this method need to have their subject set to the company name, and reports need to be generated in different formats, depending on the user’s request. So we will add these features.

In the case of HTML reports, we also need to make an extra call to set it to use cascading style sheets. The default for HTML is basic HTML 3.2 with no style sheets, and this does not match the final report format as well as HTML with CSS can.

The code for this example (RunReport) can be downloaded at CSharpCommandLineExample.

// Initialize Windward Reports. This only needs to be called once. Place in startup code.
...
Report.Init();
...

public static void MultipleFormats(InputStream xml, InputStream rtf, OutputStream out, int typ) {
    // Create a report process
    Report report;
    string ext = filename.Substring(filename.LastIndexOf('.') + 1);
    switch (ext) {
        case "htm":
            report = new ReportHtml(template, output);
            ((ReportHtml)report).CssType = ReportHtml.CSS.NO;
            break;
        case "html":
            report = new ReportHtml(template, output);
            ((ReportHtml)report).CssType = ReportHtml.CSS.INCLUDE;
            break;
        case "pdf":
            report = new ReportPdf(template, output);
            break;
        case "rtf":
            report = new ReportRtf(template, output);
            break;
        case "sml":
            report = new ReportSpreadML(template, output);
            break;
        case "txt":
            report = new ReportText(template, output);
            break;
        case "xhtml":
            report = new ReportHtml(template, output);
            ((ReportHtml)report).CssType = ReportHtml.CSS.INCLUDE;
            ((ReportHtml)report).Spec = ReportHtml.BROWSER.XHTML;
            break;
        case "xml":
            report = new ReportWordML(template, output);
            break;
        default:
            Console.Error.WriteLine("Unknown extension {0}", new Object[] { ext });
            return;
    }

    // set the subject
    report.Subject = “An Acme, Inc. Report”;

    // run the report process
    report.ProcessSetup();
    IreportDataSource data = new XmlDataSourceImpl(xml, false);
    report.ProcessData( data, “” );
    report.ProcessComplete();
}

HTML and Images

The HTML format cannot include embedded images. So when generating an HTML report that has images, you need to take a look at ReportHtml.SetImagePath() and ReportHtml.

Report.Init()

You do not have to call Report.Init() but you are strongly encouraged to do so when your application first installs. If you do not call it, it will be called when you create your first report object. This method checks your license, initializes logging, and configures the system. By calling it when first loading, you insure that all of these operations will succeed at that time.

You should also catch LicenseException if thrown by Init and handle that. If a LicenseException is thrown, you will not be able to generate reports.

Signing PDF Reports

If you wish to sign a PDF file using a Verisign certificate, please go to:

http://itextpdf.sourceforge.net/howtosign.html

Creating Uuencoded Images

If you are creating uuencoded bitmap images for the <wr:out … type=”BITMAP”/> command, a very useful reference is www.ietf.org/rfc/rfc2045.txt. The program we use for uudecoding is at jakarta.apache.org/commons/codec/.

Data Source Map

You can pass a map to the data source before processing the report. This allows you to add data to the report at runtime on a per report basis. For example, you could add a map entry where the key is username and the value is the name of the user creating the report. Then in the template, you could have < wr:out value=”${user}”/> and it will print the user’s name at that location in the final report. An example of this is in Sample 12, which is located at: .../Program Files/Windward Studios/Windward Reports/Samples/sample12

Re-Running the Same Template

If you are going to produce multiple reports using the same template, then first create a template using ProcessReport.setup(). Then use ProcessReport.duplicate() to get a copy of the template an produce the report using that template. You can call duplicate once for each report you have to generate using the same template.

SQL Views

For the ADO data source, you can also add views. This can be set up to use the same template for different subsets of data. For example, you could create a view like addView( “customer”, “select * from CUSTOMERS where CUSTOMER_ID = 3”) and then in the template have <wr:query select=”select * from ${customer}”> . See Sample 12 for an example of this.

Multiple Data Sources

You can also set Windward Reports to use multiple data sources when processing a template. In this case, the template is processed with one data source, creating an intermediate file. This intermediate file retains all tags that did not match data in the first data file.

The intermediate file is then processed a second time with a second data source. This again produces an intermediate file. This processing can be repeated any number of times. Each time you process a data source, you pass in the name of that data source and all tags assigned to that data source, and only tags assigned to that data source, are processed. Any tag for a different data source is treated as text.

datasource=”” is a data source

So what happens if a tag has no datasource=”” attribute? In that case it is applied to the default data source, which has a name just like any other data source. But its name is an empty string.

You can actually put datasource=”” in a tag and get the same result. And that is why for a single data source, you call processData(…, “”);

If you have tags marked with a data source and you never process that data source, those tags will appear in the final output.

Here is our code, once again using just PDF output to keep it simple, showing part of a method:

// Create a report process
Report proc = new ReportPdf( rtf, out );

// parse the template file
proc.ProcessSetup();

// merge an xml file with the report. We did not set a datasource= in the tags for this datasource.
proc.ProcessData( new XmlDataSourceImpl(new FileStream( “data.xml” ), true), null);

// merge a SQL database with the report. We used datasource="SqlData" in the tags for this datasource.
// This is the last data source being merged.
Proc.processData( new AdoDataSourceImpl(typeof(SqlConnection), "Data Source=jessica\sqlserver2008;Initial Catalog=AdventureWorks;Integrated Security=SSPI"), "SqlData" );

// generate the final report
proc.ProcessComplete();

That’s it. There are additional settings you can set, both in ProcessReportAPI and for each of the individual report types. You should also take a look at the sample programs which are complete implementations of everything shown here and more.

The Report Locale

The report locale that is used when creating reports can affect the final report in tricky ways. The locale is used primarily to:

  • Set the default locale in the output report (RTF only)
  • Display the print time field
  • Display the OutTag when the type attribute is set.

If you do not call ProcessReportAPI.setLocale() and do not set a value for report.locale, then the report locale is taken from the template file. In the template file it is the settings \deflang1033\deflangfe1033 shown in the very first line of the file. The setting 1033 is English US. If you change these (for example to 1031 for German Germany) then it is in German. We have found no way to change this in Word itself!

If you set a value for report.localein the app.exe.connfig file, it will use this locale. This overrides the template file’s locale, but is overridden by a call to ProcessReport.setLocale(). This is set as follows:

<add key=”report.locale” value=”en_US”/>

If you call ProcessReport.setLocale, that will override any other setting. If you pass LOCALE_DEFAULT, it will use the template’s locale. If you pass SYSTEM_LOCALE, then it will use the system locale. The system locale is the locale set by the locale Windows is running under. If you call ProcessReport.setLocale( locale ) and the locale you pass in is a Locale object, it will use that locale. There is no way using setLocale() to set it back to the locale defined by report.locale.

Other Settings

There are two other locale settings in app.exe.config. These settings have no effect on the locale used to generate the report.

system.locale points to one of the resource property files. These determine the text printed to the console when Windward Reports runs.

report.charset is used when creating TXT and HTML reports only and sets the character set to use when generating the report. (And HTML can override this to use utf-8.) This is only used when the output format cannot handle Unicode.

  • Was this article helpful?