thangalin Posted April 21, 2016 Share Posted April 21, 2016 BackgroundSometimes many reports and subreports must use the same default format (e.g., "YYYY/MM/dd") while only a handful of fields are an exception (e.g., "YYYY/MM").QuestionWhat are the exact steps to ensure all date fields use the same date format, which can be changed in one location, without having to modify each field individually, such that individual fields can easily override the default?ResearchHere is a list of resources that fail to answer this question:http://community.jaspersoft.com/questions/543426/settign-default-format-factory-globally - no answerhttp://community.jaspersoft.com/questions/528989/decimal-formatting-rounding-mode-problem - suggests "sending an instance" of a DefaultFormatFactory subclass, but does not explain howhttp://stackoverflow.com/a/4018242/59087 - suggests setting a FormatFactory report property ("formatFactoryClass"), but does not explain howhttp://community.jaspersoft.com/wiki/how-show-pure-arabi%D1%81-numbers-report - provides an example DefaultFormatFactory subclass, but no answer shows how to use ithttp://community.jaspersoft.com/questions/539398/dont-get-custom-formatfactory-work-using-jrparameterreportformatfactory-parameter - shows a line of code that sets the REPORT_FORMAT_FACTORY parameter, but doesn't show how to get the reportParams instance, and also doesn't use Jaspersoft Studiohttp://community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v610/default-parameters - suggests that "the user can replace the default one" but doesn't mention how; also, refers to a "format factory class" property name, but doesn't indicate how to set it (from withint Jaspersoft Studio)http://www.dynamicreports.org/forum/viewtopic.php?f=1&t=250 - some code is given, but isn't a comprehensive examplehttp://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/JRParameter.html#REPORT_FORMAT_FACTORY - suggests using the "formatFactoryClass" attribute of the report template, but doesn't say how to set it (i.e., where to go within Jaspersoft Studio to change that particular attribute)http://www.spagoworld.org/jforum/posts/list/46.page - drops a "dateformat" in the REPORT_PARAMETERS_MAP, but doesn't indicate whether it is used globally, how it was set, etc.http://community.jaspersoft.com/questions/517926/date-field-timezone-locale-na - shows how to instantiate a custom DateFormatter, but must be applied on a field-by-field basisThe Definitive Guide seems to copy the Javadocs verbatim, which doesn't offer any additional insight.IdeasHere's how I thought it might be possible to set the formatFactoryClass attribute for a given report:Create a new ProjectOpen Project ExplorerRight-click on project nameSelect PropertiesExpand Jaspersoft StudioClick PropertiesClick Configure Workspace Settings buttonClick AddSet property name to any of: {net.sf.jasperreports.formatFactoryClass, or formatFactoryClass, or format.factory.class}Set value to (supply your own instance): com.package.reports.ReportFormatFactoryClick OK to close Properties DialogClick OK to close PreferencesClick OK to close Properties for ProjectThis would also require a Library that includes the com.package.reports.ReportFormatFactory class inside. Link to comment Share on other sites More sharing options...
hozawa Posted April 22, 2016 Share Posted April 22, 2016 Have you considered creating a custom function?http://community.jaspersoft.com/wiki/jaspersoft-studio-expression-editor-how-extend-it-and-contribute-your-own-functions-part-2-0 Link to comment Share on other sites More sharing options...
Solution thangalin Posted April 22, 2016 Author Solution Share Posted April 22, 2016 The following seems to work: Click Window >> PreferecesSelect CapabilitiesCheck DevelopmentClick OKNext:Open the Project ExplorerRight-click Project nameSelect PropertiesSelect Java Build PathClick the Source tabClick Add FolderSelect Create New FolderSet Folder Name to: srcClick FinishSelect srcClick OKSet Default output folder: Project Name/buildClick OKCreate a report as usual (with a text field that uses a date, either a parameter or a field), then:Select the report in the Outline panelOpen the Properties panelSet Format Factory Class to: com.company.reports.ReportFormatFactoryNext, create some source code inside the "src" directory in a package (folder) named "com.company.reports". Paste the following into a file named "ReportFormatFactory.java" that is saved in that directory:import java.text.DateFormat;import java.util.Locale;import java.util.TimeZone; import net.sf.jasperreports.engine.util.DefaultFormatFactory; /** * Delegates creation of date and number formatters to JasperReports' default * formatters. This class ensures that dates are formatted consistently across * all reports. */public class ReportFormatFactory extends DefaultFormatFactory { /** * Returns a DateFormat instance that creates dates in YYYY/MM/dd format. * * @param pattern Unused. * @param locale Passed to the DefaultFormatFactory instance. * @param timezone Passed to the DefaultFormatFactory instance. * * @return An object that can format dates. */ @Override public DateFormat createDateFormat( String pattern, Locale locale, TimeZone timezone ) { return super.createDateFormat( "YYYY/MM/dd", locale, timezone ); }}When you run the report, the date should be formatted as YYYY/MM/dd.If you want to change the format (e.g., to "dd/MM/YYYY"), update the date format line in the source code and then restart Jaspersoft Studio (the classloader does not seem to reload the ReportFormatFactory class after modification).To avoid having to restart each time the date format changes, use a resource bundle:Create a new project folder called i18nRight-click on the project nameSelect New >> FolderSet Folder name to i18nClick FinishRight-click on i18nSelect New >> OtherExpand Messages EditorSelect ResourceBundleClick NextSet the name to ReportsLocaleAdd a Locale (e.g., en_US)Click FinishAdd the i18n directory to the build process:Right-click i18nSelect Build Path >> Configure Build PathClick Add FolderCheck i18nClick OKClick OK againChange the createDateFormat method: @Override public DateFormat createDateFormat( String pattern, Locale locale, TimeZone timezone ) { String dateFormat = DATE_FORMAT_DEFAULT; try { ResourceBundle rb = ResourceBundle.getBundle( "ReportsBundle" ); String df = rb.getString( DATE_FORMAT ); if( df != null ) { dateFormat = df; } } catch( Exception e ) { // If the resource bundle isn't found, use the default date format. // TODO: Pass this exception into a logger. } return super.createDateFormat( dateFormat, locale, timezone ); }And add these constants to the class definition (immediately after the publc class declaration, around line 15/16): private final static String DATE_FORMAT = "date.format"; private final static String DATE_FORMAT_DEFAULT = "YYYY/MM/dd"; Restart Jaspersoft Studio, then: Edit the ReportsLocale fileAdd a date.format propertySet the property value to: dd/MM/YYYYSet the property value for all locales.When the report is run, the date should look like 29/02/1976, for example. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now