[]
In addition to a report definition, FlexReport needs the actual data to create the report. In most cases, the data comes from a database, but there are other options. The following sections explore how to retrieve data from other sources.
For retrieving the report data in FlexReport, following DataSource properties of C1FlexReport should be set:
ConnectionString
RecordSource
To set data source, use the following code:
C1FlexReport rep = new C1FlexReport();
//initialize DataSource
DataSource ds = rep.DataSource;
ds.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\...\ComponentOne Samples\Common\C1NWind.mdb;";
ds.RecordSource = "Employees";
If these properties are set, C1FlexReport initializes the data source and uses them to load the data from the database automatically.
Many applications need to work on the data outside C1FlexReport and load it into DataTable objects. In such cases, you can use DataTable objects as report data sources, avoiding the need to load them again while rendering the report.
This approach is also useful in applications where:
Security restrictions dictate that connection strings must be kept private and only the data itself may be exposed (not its source).
The database is not supported by OleDb (the provider used internally by C1FlexReport).
The data does not come from a database at all. Instead, the DataTable is created and populated using custom code.
To use a DataTable object as a C1FlexReport data source, simply load the report definition and then assign the DataTable to C1FlexReport.DataSource.Recordset property. For example:
// load DataTable from cache or from a secure/custom provider
DataTable dt = GetMyDataTable();
// load report definition (before setting the data source)
rep.Load(@"reportFile", "reportName");
// use DataTable as the data source
rep.DataSource.Recordset = dt;
private DataTable GetMyDataTable()
{
DataTable result = new DataTable();
result.Columns.Add("ID", typeof(int));
result.Columns.Add("Caption", typeof(string));
result.Rows.Add(1, "Red");
result.Rows.Add(2, "Blue");
result.Rows.Add(3, "Green");
return result;
}
You can use custom objects as data sources. The only requirement is that the custom object must implement the IC1FlexReportRecordset interface.
IC1FlexReportRecordset is a simple and easy-to-implement interface that can be added to virtually any collection of data with ease. This is often more efficient than creating a DataTable object and copying all the data into it. For example, you could use custom data source objects to wrap a file system or custom .xml or .flxr files.
To use custom data source objects, load the report definition and then assign the object to the C1FlexReport's Recordset property of the DataSource class. For example:
public class MyRecordset: IC1FlexReportRecordset {
private int _recNo;
private int _recCount;
public MyRecordset() {
_recCount = 60;
}
public int RecCount {
get {
return _recCount;
}
set {
_recCount = value;
}
}
// IC1FlexReportRecordset implementation
public string[] GetFieldNames() {
return new string[] {
"ID",
"Caption"
};
}
public Type[] GetFieldTypes() {
return new Type[] {
typeof(int), typeof(string)
};
}
public object GetFieldValue(int fieldIndex) {
switch (fieldIndex) {
case 0:
return _recNo + 1;
case 1:
return string.Format("Caption {0}", _recNo + 1);
default:
return null;
}
}
public bool BOF() {
return _recNo < 0;
}
public bool EOF() {
return _recNo >= _recCount;
}
public void MoveFirst() {
_recNo = 0;
}
public void MoveLast() {
_recNo = _recCount - 1;
}
public void MovePrevious() {
--_recNo;
}
public void MoveNext() {
++_recNo;
}
public int GetBookmark() {
return _recNo;
}
public void SetBookmark(int bkmk) {
_recNo = bkmk;
}
public int Count {
get {
return RecCount;
}
}
}
private IC1FlexReportRecordset GetMyCustomDataSource() {
return new MyRecordset() {
RecCount = 3
};
}
private void btnGet_Click(object sender, EventArgs e)
{
// get custom data source object
IC1FlexReportRecordset rs = GetMyCustomDataSource();
// load report definition (before setting the data source)
rep.Load(@"..\..\Products Report.flxr", "Products Report");
// use custom data source object in C1FlexReport component
rep.DataSource.Recordset = rs;
PdfFilter pf = new PdfFilter();
pf.Preview = true;
pf.FileName = @"..\..\Products Report.pdf";
rep.RenderToFilter(pf);
}
Stored procedures can assist you in achieving a consistent implementation of logic across applications, improve performance, and shield users from needing to know the details of the tables in the database. One of the major advantages of stored procedures is that you can pass the parameters to have the database filter the recordset. This returns a smaller set of data, which is quicker and easier for the report to manipulate.
You can populate a report from a stored procedure in the C1FlexReport Wizard. To open the C1FlexReport Wizard, click the New Report button from the Reports tab the C1FlexReportDesigner application.complete the following:
In Visual Studio by selecting Edit Report from the C1FlexReport context menu
In Visual Studio by selecting Edit Report from the C1FlexReport Tasks menu
From the C1FlexReportDesigner application, click the New Report button from the Reports tab
Populating a report from a stored procedure is no different than using SQL statements or straight tables. In the first screen of the C1FlexReport Wizard, click the ellipses button to choose a data source. Then choose a Stored Procedure from the list of available Data sources:
Select Next and continue through the wizard.
For loading other forms of data, you have two options:
You can use the DataSource's ConnectionString and RecordSource properties to select the data source:
In the Designer, use the DataSource dialog box to select the connection string (by clicking the ellipses button "..."), then pick the table or sproc you want to use from the list. For example:
connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Windows 8.1\Documents\ComponentOne Samples\Common\C1NWind.mdb;Persist Security Info=False;" RecordSource = "[Products by Category]"
(In this case the stored procedure name has spaces, so it's enclosed in square brackets).
You can create the data source using any of the method you want, then assign it to the DataSource's property.
The method you use requires you to write code, and is useful when you have your data cached somewhere and want to use it to produce several reports. It overrides the previous method (if you specify ConnectionString, RecordSource, and Recordset, C1FlexReport uses the Recordset).
The syntax is different depending on the type of connection/adapter you want to use (OleDb, SQL, Oracle, and so on). The easier way to get the syntax right is to drag tables or sprocs from Visual Studio's Server Explorer onto a form. This adds all the cryptic elements required, and then you can go over the code and pick up the pieces you want.
You can specify stored procedures as data sources by their name. If the sproc has parameters, you pass them as parameters. For example, in a report definition built against MSSQL and ADVENTURE_WORKS.mdf database, the SQL request that is specified in C1FlexReportDesigner (adjust the path to ADVENTUREWORKS_DATA.MDF as needed) is:
PARAMETERS Employee Int 290;
DECLARE @RC int
DECLARE @EmployeeID int
set @EmployeeID = [Empoyee]
EXECUTE @RC = [C:\ADVENTUREWORKS_DATA.MDF].[dbo].[uspGetEmployeeManagers]
@EmployeeID