Wellcome to RReport, the package that will allow you to include printing, reporting (DHTML and PDF) and prevewing capablities into your .NET applications in a few minutes.
The main features or RReport are:
Before you start reading this section you must note that there are 2 ways for creating reports:
You can, of course, also combine both approaches. For example, you can create a report template (*.rep file) and modify it at runtime.
A Rreport is made of Rareas. A RArea is a group of objects (RObject) that will be printed together (in the same page). Typical examples of areas in a report are:
The source code to create an area looks like this:
[c#]
// create report
Report Rep=new Report();
RArea HDR_PurchaseOrder= new RArea();
HDR_PurchaseOrder.width=16.429;
HDR_PurchaseOrder.height=4.074;
Rep.addArea(HDR_PurchaseOrder);
[vb.net]
' create report
As already stated, an RArea contains of a set of objects (RObject). These are the elements that are actually printed. The following Robjects are currently available:
The following example creates the page footer for the Purchase order report:
[c#]
RArea PFOOTER_PurchaseOrder= new RArea();
RField TextPageNumber=new RField();
TextPageNumber.name="TextPageNUmber";
TextPageNumber.setConstant(false);
TextPageNumber.setdefaultValue("[Page]");
TextPageNumber.x=0.238;
TextPageNumber.y=0.185;
TextPageNumber.width=3;
TextPageNumber.height=0.423;
TextPageNumber.Align=RField.ALIGN_LEFT;
TextPageNumber.Expand=false;
TextPageNumber.Compress=false;
TextPageNumber.FontColor=Color.Black;
TextPageNumber.FontType=new Font(new FontFamily("Arial"),8);
PFOOTER_PurchaseOrder.add(TextPageNumber);
rep.setPageFooter(PFOOTER_PurchaseOrder);
The code:
Actually this would not be necessary. When you create a new RReport it already contains a default pager footer like this one.
If you are using RReport Visual Builder you will not do this, you will read the definition of your report from a file:
[c#]
Report report=new Report();
if (!report.importReport("examples\\DatabaseSource\\DBorder.rep")) {
Console.WriteLine("Error, exiting");
Application.Exit();
}[vbnet]
' load report from file
Dim report as Report
report=new Report()Console.WriteLine("loading report")
if (not report.importReport("examples\PDF_DHTML\order.rep")) then
Console.WriteLine("Error, could not load file")
end
end if
If you want to modify a RField in a report created with the Visual Builder you can do it like this:
[c#]
RField f=(RField) report.getAreaByName(name).getItemByName(elementName);
[vbnet]
Dim f as RField
f=report.getAreaByName(name).getItemByName(elementName)
Areas can be nested by linking them to a superarea (see RArea.setLinkedArea() ). After a repetition of an area is printed, all subareas are printed automatically.
For example:
detailArea.setLinkedArea(headerArea);
will result in detailArea being printed after each repetition of headerArea. See RDatabaseSource to learn how to retrieve the information from a database and define relationships between tables.
Let's suppose your report has 2 areas (header and detail). You have 2 options:
[c#]
report.setHeaderArea(hdr);
report.addArea(detail);
report.prepare(); // this prints report header
report.printArea(detail); // we must now print the detail area
report.endReport();
[vbnet]
report.setHeaderArea(hdr)
report.addArea(detail)
report.prepare() ' this prints report header
report.printArea(detail) ' we must now print the detail area
report.endReport()
[c#]
report.seHeaderArea(hdr);
report.addArea(detail);
detail.setLinkedArea(hdr);
// link detail to header
report.prepare(); // this prints header and detail
report.endReport();
[vbnet]
report.seHeaderArea(hdr)
report.addArea(detail)
detail.setLinkedArea(hdr) ' link
detail to header
report.prepare() ' this prints header and detail
report.endReport()
You can create a group of areas using RReport Visual Builder. A group of areas is made of:
The groups of areas will allow you to automatically print a header and/or a footer based on the values of one or more fields.
The groups of areas must be used together with a RSource (normally a RDatabaseSource) and you should set a value for the "RArea.setGroupByFields()" property of the detail area, there is no other special treatment, you can print the group's detail area as you would print any other area.
RReport will automatically print the group header and footer areas whenever the values of the "group by" fields change. Note that the header and footer area share the same RSource as the detail area.
For example , if you are printing the following data in you group detail:
Article Id =1 , Name=Printer , Category=Hardware
Article Id =2 , Name=Scanner , Category=Hardware
Article Id =3 , Name=Antivirus , Category=Software
Article Id =4 , Name=Editor , Category=Software
Article Id =5 , Name=Linux , Category=Software
and you set Group by "Category". The result will be:
Note that RReport will NOT SORT the values. You must provide the data for the detail area in the correct order. In the previous example you would use a sql statement like: "select * from Articles order by Category" to make sure all articles in the same category come together.
You can find an example of use of groups in the examples/groups folder.
After you have defined your report (either programatically or with the Visual Builder) , you will need to print it. First you must decide if you want to print it directy or you want to preview it.
In order to print a report you must follow these steps:
Note: report header anf footer and page header and footers are printed automatically. If you need to execute your own code before these areas a printed you must use a RAreaListener.
Tip: if you make all your areas dependent of the report header using the setLinkedArea(), then all areas will be printed automatically when you call prepare(). (i.e. the header will be printed and all its subareas).Note: the prepare() method will print one repetition of the report header. If you assign a RSource (array, table in database ...) to the report header, several repetitions of the header and all subareas will be printed. For each new report header repetition a page break and a initialisation of the page number is automatically performed. In this way you can print more than 1 report at once.
If you want to preview the report you can:
[c#]
// use windows's default preview dialog
report.setPreview(true);
report.useSystemPreviewWindow=true;
report.prepare();
// Print here ....
report.endReport();
[vbnet]
' use windows's default preview dialog
report.setPreview(true)
report.useSystemPreviewWindow=true
report.prepare()
' Print here ....
report.endReport()
[c#]
Win= new RReportWindow(rep);
report.prepare();
// Print here ....
report.endReport();
Win.showNow();
[vbnet]
' create preview window
Dim Win as RReportWindow
Win= new RReportWindow(report)
report.prepare()
report.endReport()
Win.ShowNow()
If you want to create your own preview window we advise you to use our preview winvow RReportWindow.cs as starting point.
Areas are programatically printed by:
However you can also use a Rsource object. In this case the report will automatically assign the values to the fields and print the area as many times as needed. There are 2 implemented Rsource classes, but you can implement your own class.
The following example uses the class RArraySource to print the lines of a Purchase Order:
[c#]
private static void Example2() {
// example: array as data source
Win= new RReportWindow(rep,MainWindow);
DETAIL_PurchaseOrder.setDataSource(new RArraySource(columnsNames,columnsData));
rep.prepare();
//print here
rep.printArea(DETAIL_PurchaseOrder);
rep.endReport();
Win.show();
}
The array columnsNames contains the names of the fields and the array columnsData contanins the values. See Examples .
Note: you can use a RAreaListener in order to execute your own code before each repetition of the area is printed.
Note: objects defined as constant (see RObject.setConstant()) will not be modified by the data source (RSource).
The class RDatabaseSource is a subclass of RSouce. It will therefore allow you to print the contents of a table in a database. Furthermore RDatabaseSource supports nested areas. This means you can print an area that contains subareas.
Let's suppose you must print 2 Invoices. Invoice number 1 and invoice number 2. You have a database that contains two tables: INVOICES and INVOICESLINES.
You have defined the following areas for this:
in order to programatically print the two invoices you must:
You can easily simplify this process by using RDatabaseSource in the following way.
[c#]// create source table
OleDbConnection con1=new OleDbConnection();
con1.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\RReportNET\\RReport2.mdb";
con1.Open();
OleDbCommand sta1=con1.CreateCommand();
sta1.CommandText="SELECT * FROM INVOICES";RDatabaseSource headerTable=new RDatabaseSource(con1,sta1);
headerArea.setDataSource(headerTable);// create source table
OleDbConnection con2=new OleDbConnection();
con2.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\RReportNET\\RReport2.mdb";
con2.Open();
OleDbCommand sta2=con.CreateCommand();
sta2.CommandText="SELECT * FROM INVOICES";
RDatabaseSource linesTable =new RDatabaseSource(con2,sta2);
linesArea.setDataSource(linesTable);// link areas
linesArea.setLinkArea(headerArea);// link fields
linesTable.setToFields("ID");
linesTable.setFromFields("ID");// link tables
linesTable.setLink(headerTable);
This means the following:
You can also use parameters in your SQL statement. For example:
sta1.CommandText="SELECT
* FROM INVOICES where IDate>'[%dateParam]'";
RDatabaseSource mySource=new RDatabaseSource(con1,sta1);
in this case you must provide a value for the parameter before you run the report:
mySource.setParameter("dateParam","01/01/2001");
RReport can also export your report to DHTML. This is usefull if you are using rreport in a web environment.
In order to export to DHTML you must call the following methods:
[c#]rep.setDHTMLActive(true); // select DHTML mode
rep.disablePrinting(true); // do not send output to printer/ / print report now
rep.prepare();
....
rep.endReport();// get DHTML output
string htmlString=rep.getHTML();
[vbnet]
rep.setDHTMLActive(true) ' select DHTML mode
rep.disablePrinting(true)rep.prepare()
...
rep.endReport()' get dthml output
dim htmlString as string
htmlString= rep.getHTML()
The class DHTMLLayer is in charge of converting the reports to DHTML code.
Whenever you export to DHTML you must take into account that the browser requires all to be stored in files. If you create a chart or a barcode, the resulting image must be stored in a image file. The following properties are used for the configuration of this:
[c#]
report.exportImagesFormat="png"; // store the chart or barcode as png file
report.exportDirectory="c:\\web\\images"; // store the file in this subdirectory
report.imagesHTMLPrefix="images\\"; // the resulting DHTML will look like this: <IMG SRC="images/XXXXXX.jpg" >
If you are using a RPicture object for printing images, the "ImageHTMLAddress" property will be used when exporting to DHTML. In RReport Visual Builder the property is called "HTML image".
For example:
picture.ImageHTMLAddress="/images/file.jpg"
will generate <IMG SRC="/images/file.jpg" > as part of the DHTML code. In the case of RPicture you must place the file in the correct directory, RReport will not create the file.
RReport can also export your report to PDF. This is usefull if you are using rreport in a web environment. In order to export to PDF you must call the following methods:
[c#]
rep.disablePrinting(true); // do not send output to printer/ / print report now
rep.prepare();
....
rep.endReport();
rep.exportPDF("output.pdf"); // set pdf output file
[vbnet]
rep.disablePrinting(true)
' print report now
rep.prepare()
...
rep.endReport()
rep.exportPDF("report.pdf")
RReport uses a free J# library called iText
that creates PDF files. You will need version 1.00-1b, Click
here to download the pdf library. If the link is not working let
us know and we will send you the library per email.
You must install the PDF library by including the reference iTextdotNET.dll
, JSharpLib.dll in your project (zlib.dll must be in the same directory). You
will also need the J# redistributable package (available from Micorosft's web
site) and you will have to add a reference to vjscor.dll and vjslib.dll.
The class PDFLayer is in charge of converting your report to PDF using iText.
Note 1: if you try to create a PDF file in a Web application (aspx file), you must make sure you provide the correct path in the exportPDF() method. If you do not provide the path you can't be sure where the file will be created (sometimes in /windows/system32 which is not allowed). Furthermore the web server normally requires you to create the file in the web directory or subdirectory, otherwise it will fail.
Note 2: If you get the following error while opening the generated pdf file:
illegal operation 'BT' inside a text object
You must check you have copied the iText fonts and hyph subdirectories in your application's working directory.
If you are developing a web application you can also use RReport to create your reports. The reports can be created as DHTML pages or PDF.
Creating DHTML output in a aspx page:
<%@ Page language="VB" AutoEventWireup="false" Trace="true" Debug="true" %>
<%@Import Namespace="System.Drawing" %>
<%@Import Namespace="System.IO" %>
<%@Import Namespace="System.Drawing.Imaging" %>
<%@Import Namespace="J4L.RReport" %>
<%@ OutputCache Duration="100" VaryByParam="none" %>
<%
' load report from file
Dim report as Reportreport=new Report()
if (not report.importReport("c:\j4l\RReportNET\examples\DatabaseSource\DBorder.rep")) then
Console.WriteLine("Error, exiting")
end if
' create preview window
Dim Win as RReportWindow
report.setDHTMLActive(true)
report.disablePrinting(true)
' this will print the Header Area and all dependent areas
report.prepare()
report.endReport()
dim htmlString as string
htmlString= report.getHTML()Response.ClearContent()
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.Write(htmlString)
Response.End()
%>
Creating PDF output in a aspx page:
<%@ Page language="VB" AutoEventWireup="false" Trace="true" Debug="true" %>
<%@Import Namespace="System.Drawing" %>
<%@Import Namespace="System.IO" %>
<%@Import Namespace="System.Drawing.Imaging" %>
<%@Import Namespace="J4L.RReport" %>
<%@ OutputCache Duration="100" VaryByParam="none" %>
<%
' load report from file
Dim report as Report
report=new Report()
if (not report.importReport("c:\j4l\RReportNET\examples\DatabaseSource\DBorder.rep")) then
Console.WriteLine("Error, exiting")
end if
' create preview window
Dim Win as RReportWindow
report.setDHTMLActive(false)
report.disablePrinting(true)
report.setPDFFile("report.pdf")
' this will print the Header Area and all dependent areas
report.prepare()
report.endReport()
Response.ClearContent()
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = "application/pdf"
Response.Redirect("report.pdf")
Response.End()
%>
You will find the following examples shipped with the product:
Note: you will need to modify the connection string of the examples DBOrder*.rep since they point to "c:\j4l\ReportVD\RReport2.mdb".
You can use the properties expand and compress to specify how the Rfield class will behave if the text is too long or too short:
You can very easily draw a frame around the page,an area, or all areas of the same type.
The following example draws a frame around the report’s page:
rep.setPageFrameStyle(new RLineStyle(1, Color.Black,RLineStyle.LINE_NORMAL));
The following example draws a frame around the report’s header:
PHDR_PurchaseOrder.setFrameType(RArea.FRAME_AREA);
PHDR_PurchaseOrder.setFrameStyle(new RLineStyle(1 , Color.Black,RLineStyle.LINE_NORMAL));
The following example draws a frame around the report’s header
DETAIL_PurchaseOrder.setFrameType(RArea.FRAME_PAGE);
DETAIL_PurchaseOrder.setFrameStyle(new RLineStyle(1, Color.Black,RLineStyle.LINE_NORMAL));
Note that in this example only one frame for all the lines of the "purchase order" will be created. If we use RArea.FRAME_AREA instead, a frame for each line is created.
If you want to print a table you may also want to print a grid to separate rows and columns inside this table.
DETAIL_PurchaseOrder.setGrid({8,10,12});
DETAIL_PurchaseOrder.setHorizontalGrid(true);
DETAIL_PurchaseOrder.setGridStyle(new RLineStyle(1,Color.Black,RLineStyle.LINE_NORMAL));
This code will:
If you use the RJTable class to construct your report, you dont have to worry about this. Just call:
MyRJTable.SetHRDFrameStyle(new RLineStyle(1,Color.Black,RLineStyle.LINE_NORMAL));
MyRJTable.SetLINFrameStyle(new RLineStyle(1,Color.Black,RLineStyle.LINE_NORMAL));
MyRJTable.SetLINGridFrameStyle(new RLineStyle(1,Color.Black,RLineStyle.LINE_NORMAL));
To create frames and grid for the table.