JRDataSource is interface that represents the abstract representation of a JasperReports data source. All data source types must implement this interface.
We could create JRDatasource using java code, but there is a stipulation that the class made as the datasource needs to implement JRDataSource interface.
Now, in this article I will talk about:
1. Setting the datasource using custom JRDataSource.
2. Setting the datasource using JRDataSourceProvider.
To start with,
Setting the datasource using custom JRDataSource.
The prerequisites for the creating a custom datasource are:
1. JRDataSource
2. Factory class setting the JRDataSource.
Setting the datasource using JRDataSourceProvider
The prerequisites for the creating a custom datasource are:
1. JRDataSource
2. JRDataSourceProvider implemented class.
For showing setting of each of the methods I have created a youtube video.
==VIDEO LINK==
In the sample I have created, what I intend to do is that I want to know the names, is directory(boolean true/false) and the size on disk, of the folder whose path is passed in the constructor of the datasource. Now in my datasource I have 3 columns
NAME,
SIZE and
IS_DIRECTORY.
In both the cases we need to create a JRDatasource class .. that is the class which implements JRDataSource, so in the sample it looks like this
/**
* JR DataSource Class
* @author Ankur Gupta
*/
public class JRFileSystemDataSource implements JRDataSource {
File[] files = null;
int index = -1;
public JRFileSystemDataSource(String path) {
File dir = new File(path);
if (dir.exists() && dir.isDirectory()) {
files = dir.listFiles();
}
}
@Override
public boolean next() throws JRException {
index++;
if (files != null && index < files.length) {
return true;
}
return false;
}
@Override
public Object getFieldValue(JRField jrf) throws JRException {
File f = files[index];
if (f == null) {
return null;
}
if (jrf.getName().equals("name")) {
return f.getName();
} else if (jrf.getName().equals("IS_DIRECTORY")) {
return new Boolean(f.isDirectory());
} else if (jrf.getName().equals("totalSpace")) {
return new Long(f.length());
}
// Field not found...
return null;
}
/**
* This method is responsible for setting the field names in the provider.(Required for the provider)
* @return
*/
public static String[] fieldNames() {
String[] fieldNames = {"name", "IS_DIRECTORY", "totalSpace"};
return fieldNames;
}
}
CODE SCRIPTLET #1
The
fieldNames() method is not required for custom JRDataSource , but is required for JRDataSource Provider.
Now for the custom JRDatasource
1. The JRDataSource as shown above.(Remove the last method not required.)
2. The Factory Class for the custom JRDataSource looks like.
/**
*
* @author Ankur Gupta
*/
public class FactoryClassDataSource {
/**
* Factory Class responsible for setting the JRdatasource.
* @return
*/
public static JRDataSource generateDS(){
return new JRFileSystemDataSource("Path of the desired folder");
}
}
CODE SCRIPTLET #2
This is it, now you can compile these two classes , and place the jar file in the class path.
Now for the JRDatasource Provider.
1. The JRDataSource as shown as above in the code scriptet #1.
2. Next is the JRDataSourceProvider class shown as below.
/**
* JRDatasource Provider
* @author Ankur Gupta
*/
public class JRFileSystemDataSourceProvider implements JRDataSourceProvider{
@Override
public boolean supportsGetFieldsOperation() {
return false;
}
@Override
public JRField[] getFields(JasperReport jr) throws JRException, UnsupportedOperationException {
ArrayList fields = new ArrayList();
String [] fieldNames = JRFileSystemDataSource.fieldNames();
for (String s : fieldNames) {
JRDesignField field = new JRDesignField();
field.setName(s);
field.setValueClassName("java.lang.String");
fields.add(field);
}
return (JRField[]) fields.toArray(new JRField[fields.size()]);
}
@Override
public JRDataSource create(JasperReport jr) throws JRException {
return new JRFileSystemDataSource("Enter the path of folder");
}
@Override
public void dispose(JRDataSource jrds) throws JRException {
}
}
CODE SCRIPTLET #3
Now, you can compile the classes and get the jar and place it in the classpath of iReport.
This was the portion you need to complete in creating the JAR file, now we need to set the datasource in thr iReport .
For setting the datasource as custom JRDataSource, you need to enter the qualified path of the factory class. In iReport it looks like :
|
Custom JRDataSource
|
Now you need to create the fields in the iReport by doing a right click on the field node and remember that the name of the field should be same as in the datasource . In the sample we need to create 3 fields as name, IS_DIRECRTORY,totalSpace.
And then place these fields in the detail section of the report and then preview the report and then you could see the contents of the folder(In the sample the folder path is set to C drive.)
For setting the datasource as JRDataSourceProvider, you need to set datasource by selecting to create a new datasource of type JRDataSourceProvider. In the sample it looks like
|
JRDataSourceProvider |
Now the difference in the custom JRDataSource and JRDataSource Provider is that in this function you will not be worried for creating the field you could directly fetch it by going to the
Report query, navigate to
DataSource Provider tab and click on
Get Fields from dataSource , it will display all the fields in case of this sample it look like :
You then use the fields in the report and you can obtain similar structure of folder.
Here is the sample ZIP file
This ZIP file will contain
1, TestRun PDF
2. JRXMLs for both the custonm JRDataSource as well as JRDataSource Provider
3, JAR file which is needed to be placed in the classpath of iReport.
You could follow the video and sample and learn how to set the datasource with JRDataSource easily.
Please put you questions or demands for clarification in the comments section below.
Happy Coding.,,,!!!