Home > FAQ
 
  JasperReports FAQ      
   
 

Swing application exits when closing the JasperViewer frame

 
  This happens if you directly use the JasperViewer class in your Swing application.
The viewer application implemented in this class should be considered more like a demo application that shows how the JRViewer component can be used in Swing applications to display reports.
Your application unexpectedly terminates when you close the report viewer frame because the JasperViewer class makes a call to the System.exit(0).
To get around this, use the constructor that allows you to set the isExitOnClose to "false".
But you are encouraged to create your own viewer that uses the more basic visual component implemented by the JRViewer class. Feel free to copy what code portion you might want to keep from the supplied JasperViewer class.
 
  (back to top)  
 

Cannot use the && logical operator in report expressions

 
  If you want to create some complex report expressions in which you have to use the Java AND logical operator, you might be surprised to see an error when compiling you report design. The error message would say something like this:
"The entity name must immediately follow the '&' in the entity reference."
Don't worry! This is because the '&' character is a special XML character and the XML parser is confused when it encounters such characters in the body of an XML element.
The solution is to use the XML special syntax that allows you to introduce XML special characters in the body of an XML element. Put your expression content between the <![CDATA[ and ]]> character sequences like in the following demo text field expression:
<textFieldExpression>
    <![CDATA[$F{MyNumber}.intValue()>=0 &&
    	$F{MyNumber}.intValue()<=25 ? 
    	"in range" : 
    	"out of range"]]>
</textFieldExpression>
 
  (back to top)  
 

java.io.InvalidClassException: ... serialVersionUID = xxx ...

 
  When upgrading to a new version of the library, you need to recompile your XML report design and regenerate the *.jasper files.  
  (back to top)  
 

Images are not appearing in XLS format

 
  The Jakarta POI library that we use when exporting the report to XLS format does not currently support images.
A newer XLS exporter implementation that uses the JExcelApi library (JExcelApiExporter) is available since JasperReports 1.2.1 and it supports images.
 
  (back to top)  
 

Dynamic element formatting

 
  Some reports may require that the same kind of data be displayed differently, depending on its significance.
For example, someone would want to highlight on an orders list, all the orders that have a total value greater than $100, like in the following table:

OrderID City Date Value
10251 Buenos Aires 07/15/2001 98.64
10263 Paris 09/19/2001 106.75
11320 Caracas 10/19/2001 88.10

There are now three ways to achieve this:
  • conditional styles
  • styled text
  • switching between two different text fields place one on top of the other using the <printWhenExpression>
 
  (back to top)  
 

"Page i of n" trick

 
  Quite often we might need to put at the beginning of our reports, values that are calculated only after the entire document is generated.
The most common situation of this kind would be the display of the total number of pages on the page footer or header of each page.
How to do that, since the report is filled page by page and the total number of pages is known only when we reach the end of our document?
Well, that's easy!
JasperReports allows us to specify the exact moment at which an expression for a text field is evaluated. To display the total number of pages, we only need to put on our page footer (or any other report section) a text field that will use the PAGE_NUMBER report variable in its expression. For this field we will specify that the evaluation time should be "Report", because only when the end of the report is reached, this system variable will contain the total number of pages on our report.
The text field declaration in the XML report design file for the total number of pages in a document will look like this:
<textField evaluationTime="Report">
    <reportElement x="280" y="10" width="275" height="20"/>
    <textElement textAlignment="Left">
        <font fontName="Helvetica" size="14"/>
    </textElement>
    <textFieldExpression class="java.lang.Integer">
        $V{PAGE_NUMBER}
    </textFieldExpression>
</textField>
If we remove the attribute evaluationTime from the <textField> element, the text field expression will be evaluated when the section is filled (default behavior) so we will obtain the current page number on the document.
To display the current page number and the total number of pages simultaneously, like in "Page 3 of 5" phrases, we need two text fields with the same expression (PAGE_NUMBER variable value), but with different evaluationTime attributes:
evaluationTime="Now" for the current page number (default)
evaluationTime="Report" for the total number of pages
There are 5 possible values for the attribute evaluationTime: Now, Report, Page, Column and Group. For more information about this attribute, see the <textField> element in the Schema Reference.
An example is also supplied in the sample application.
 
  (back to top)  
 

Bands larger than one page

 
  Sometimes the content of a particular report band is larger than one page and we have to find a way to force page breaks at certain points, inside the band structure.
Of course, this issue does not concern all the report bands. I imagine that we shall never have page or column headers or footers larger than one page ... but who knows?
If the title band or the summary band are larger than one page, you should consider placing their content into a subreport element and applying the following trick to this particular subreport. This might even work for the page or column headers, but never for the page or column footers, since the engine judge them to be of fixed height and do not perform stretch for the elements placed on those sections.
We have eliminated from our discussion some of the report sections and all that remains are the group headers and footers and the detail band.
The group headers and footers will be treated together, so let's start with the detail band.
If we have a detail band that contains so many elements on it that we have to split it on multiple pages, we have to find a way to introduce page breaks. But there is no such "page break" element available in JasperReports, so what to do?
The only way to deliberately introduce page breaks in JasperReports is by using the isStartNewPage attribute of the <group> element. We cannot use this to solve our problem.
Normally, the reporting engine starts a new page or column every time it sees that the band it has to fill does not fit on the remaining space on the current page. This is why we have that validation performed when the report design is compiled, so that the bands do not have a height greater than the page height. Without such a constraint, the reporting engine would get confused and behave uncontrollably.
So, in order to solve our problem, we have to find a way to somehow pass this band height validation check.
Well, we could do that by splitting the detail band content on multiple bands, each one of them smaller that one page, so that the report design remains valid.
And what other report bands could we use? Group headers and footers of course.
We could place some of our detail elements on a special group header, some of them will probably remain on the detail section, and the rest could go on the group footer. The only condition to this is that the group header and footer should always accompany our detail section, so that all three behave like a normal large detail band.
That's the easiest part, because we can introduce a dummy group that will break with every row in the data source. Such a group would have an expression like the following:
<groupExpression>$V{REPORT_COUNT}</groupExpression>
If one dummy group is not sufficient for you and you have a giant detail band, you could introduce as many dummy groups as you want to, all of them with the same dummy expression.
Problem solved.
Hey, we forgot about that other situation when one of the group headers or footers is larger than one page.
No problem. The solution is the same. You just have to introduce a new group, with the same expression as the one which poses the problem, and to split that group header or footer content between the two. Those two groups will break together and behave like one, so you can distribute the elements on their headers and footers as you want to.
The band height validation check could be passed this way.
 
  (back to top)  
 

Making HTML, XLS or CSV friendly reports

 
  When generating reports, the JasperReports engine uses the absolute position of each report element to layout the content of each page. Absolute positioning the report elements allows full control over the content of the output documents.
The PDF format supports absolute positioning of the text and graphic elements on a document page and this is why it is widely used on various platforms. You can be sure that once created, a PDF document will look the same no matter what is the viewer's platform.
The JasperReports proprietary document format (JasperPrint objects) is also based on absolute positioning of elements on the page. The position and size of each element are defined by the x, y, width and height properties.
However, other document formats such as HTML or XLS, do not support absolute positioning of the text and graphic elements. The content of such documents is arranged in a grid or table structure.
Of course, some may argue that absolute positioning of elements in HTML is possible thanks to CSS, but you can be sure that the CSS standard functionality is far from being implemented in all browsers or that the same HTML document won't look the same everywhere.
This is why the JasperReports built-in exporters that produce HTML, XLS or CSV documents use a special algorithm in order to arrange the elements present on a certain document page in some sort of a grid.
When the report designs are very complex or agglomerated, passing from absolute positioning to grid or table layout produces very complex tables with many unused rows and columns, to make it for the empty space between elements or their special alignment.
There are a few, very simple guidelines that should be followed by those who want to obtain optimized HTML, XLS or CSV documents when using the built-in JasperReports grid exporters.
  1. Minimizing the number of rows and columns in the grid oriented formats (minimizing the number of "cuts").
    To do that, you have to make sure you align your report elements as often as you can, both on the horizontal and the vertical axis and that you eliminate the space between elements.

    1. Inefficient layout:

      Inefficient layout

    2. Grid friendly layout:

      Grid friendly layout

  2. Avoiding overlapping report elements.
    Make sure report element will not overlap when the report will be generated. This is because if you have two elements that share some region, it will be impossible for them to share the same cell in the resulting grid structure. You might obtain some unexpected results if elements overlap.

  3. Give up using page headers and page footers.
    Especially when you want to obtain documents in which the page breaks are not relevant (CSV for example), make sure that you suppress the page header and page footer sections in your report design. You could also minimize the top and bottom margins for your report, so that when exported to HTML, XLS or CSV, your documents will be made of a single chunk, without page separators.
 
  (back to top)  
 

Excel color palette

 
  JasperReports allows you to use any color for your report elements.
However, when exporting to XLS format, you have to be aware that this type of files supports only a limited set of colors.
Here is the Standard Excel Color Palette containing all the 40 colors that XLS may use. Make sure you use one of these colors if you want to eventually export your reports to XLS format.

  #FFFF00 YELLOW   #003300 DARK_GREEN
  #969696 GREY_40_PERCENT   #808000 DARK_YELLOW
  #99CC00 LIME   #FF00FF PINK
  #CC99FF LAVENDER   #FF99CC ROSE
  #FFFF99 LIGHT_YELLOW   #3366FF LIGHT_BLUE
  #008000 GREEN   #FF6600 ORANGE
  #C0C0C0 GREY_25_PERCENT   #993300 BROWN
  #339966 SEA_GREEN   #993366 PLUM
  #FF9900 LIGHT_ORANGE   #800080 VIOLET
  #FF0000 RED   #333399 INDIGO
  #003366 DARK_TEAL   #000000 BLACK
  #FFFFFF WHITE   #00CCFF SKY_BLUE
  #99CCFF PALE_BLUE   #333333 GREY_80_PERCENT
  #00FFFF TURQUOISE   #CCFFFF LIGHT_TURQUOISE
  #008080 TEAL   #CCFFCC LIGHT_GREEN
  #000080 DARK_BLUE   #666699 BLUE_GREY
  #FFCC00 GOLD   #0000FF BLUE
  #33CCCC AQUA   #00FF00 BRIGHT_GREEN
  #333300 OLIVE_GREEN   #800000 DARK_RED
  #808080 GREY_50_PERCENT   #FFCC99 TAN

If the colors you use in your report designs do not match any of these acceptable colors, the XLS exporter will use a special algorithm to determine which is the nearest one by comparing the RGB levels. But the results might not be always what you expect.
JasperReports supplies a way to avoid this, enlarging the number of possible color choices. If the export is performed using the JExcelApiExporter class, one have to consider the JExcelApiExporterParameter.CREATE_CUSTOM_PALETTE export parameter. It is a flag specifying whether the standard color palette should be customized so that the XLS result uses the original report colors.
If this flag is not set, the nearest color from the standard XLS palette is chosen for a report color.
If the flag is set, the nearest not yet modified color from the palette is chosen and modified to exactly match the report color. If all the colors from the palette are modified (the palette still has a fixed size), the nearest color from the palette is chosen for further report colors.
 
  (back to top)  
 

Returning values from subreport

 
  There was no easy way to return to a master report values that were calculated inside a subreport. A new tag <returnValue> is available at subreport level and enables users to map master report variables to subreport variables and also specify the way the returned value should be handled (used in a calculation or just copied).
The supplied demo/samples/subreport sample show how this new feature can be used.
 
  (back to top)  
 

Fake title and summary sections

 
  The title and the summary are special report sections that are not accompanied by the page header and footer on the pages that they occupy. This is more obvious when the title or the summary overflows.
Sometimes is useful to have a title section that starts after the page header on the first page or a summary section that gets accompanied by the page header and footer on all the pages that it overflows to.
This can be achieved by introducing fake title and summary sections.
A fake title can be the group header section of a report group that breaks only once per report. Such a dummy group would have an empty group expression. Its header will get printed only once at the beginning of the report.
The fake summary can be introduced also by using the footer section of such a dummy group with an empty group expression.
 
  (back to top)  
 

Support for large reports

 
  For filling and exporting large documents that would normally eat up memory and crash with an OutOfMemory exception, there is now a new feature called "report virtualizer" that uses serialization of temporary data on disk to optimize memory consumption.
This can be seen in action in the supplied /demo/samples/virtualizer sample provided. This new feature is a contribution from Works Inc.
 
  (back to top)  
 

Exporting to SVG format

 
  It is very easy to export a JasperReports generated document to SVG format, even though there is no specialized SVG exporter implementation available.
The help comes from the Batik library, which provides an implementation of the java.awt.Graphics2D abstract class. This in turn can be used in combination with the existing JRGraphics2DExporter to produce SVG content for a given page or a page range.
For exporting the first page of an in-memory JasperPrint document to SVG, the code should look like this:
	
DOMImplementation domImpl = 
    GenericDOMImplementation.getDOMImplementation();
Document document = 
    domImpl.createDocument(null, "svg", null);
SVGGraphics2D grx = 
    new SVGGraphics2D(document);

JRGraphics2DExporter exporter = new JRGraphics2DExporter();
exporter.setParameter(
    JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(
    JRGraphics2DExporterParameter.GRAPHICS_2D, grx);
exporter.setParameter(
    JRExporterParameter.PAGE_INDEX, new Integer(0));
exporter.exportReport();\\

grx.stream(new FileWriter(new File("MyReport.svg")), true);

 
  (back to top)  
 

Empty report problem

 
  If you do not supply any data source when filling a report template, or if that data source supplied, either directly or obtained by the engine through the execution of a query, does not contain any records, the report-rendering engine will not produce any output by default (whenNoDataType="NoPage" by default).
If you want to see something being generated even when there is no data in the supplied data source, then you should try set the whenNoDataType property to "AllSectionsNoDetail" for you report template.
Another possibility is to provide a customized output to replace the empty report. You can do that by setting the whenNoDataType property to "noData". Then you have to add and customize the noData section in the report template.
 
  (back to top)  
 

Why don't I see my subreport?

 
  Subreports are just normal report templates that are embedded into some other containing report template. When no data source is supplied to them or when the supplied data source does not contain any records, subreports could behave in different ways, depending on the whenNoDataType property.
By default, the engine does not generate anything for the subreports or reports that did not receive any data thought their data source. And this is the most common reason for not seeing subreports being generated at runtime. The easiest way to check this is to instruct the engine to generate at least some of the subreport sections so that we can see the subreport is there. You can do that by setting the whenNoDataType property of the subreport template to the "AllSectionsNoDetail" value.
Another possibility is to provide a customized output to replace the entire empty subreport. You can do that by setting the whenNoDataType property of the subreport template to "noData". And of course, you have to add and customize the noData section in the subreport template.
 
  (back to top)  
 

What "Crosstab data has already been processed" exception means?

 
  This exception is thrown if more data is added to the crosstab dataset after the crosstab has already been rendered.
This usually happens when a crosstab element is linked to the main dataset of the report (does not use a subdataset run) and the resetType attribute of the crosstab dataset does not match the place where the crosstab is rendered.
Crosstabs are special components that display aggregated data. And when they are linked to the main dataset of the report, you simply cannot put them in the detail section, because there is no data to aggregate from a single record.
Such crosstabs could only reside on a group footer or on the summary section of the report and have the appropriate resetType value, so that their dataset is initialized each time after they are rendered.
If you still think you need to render one crosstab for each detail in the master document, then almost certainly this crosstab should be linked to a subdataset and not to the main dataset of the report.
 
  (back to top)  
 

System property org.xml.sax.driver not specified

 
  JasperReports uses the SAX 2.0 API to parse the XML files. However, it is not tied to a particular SAX 2.0 implementation, like Xerces for examples, but instead you are able to decide at runtime what XML parser you are using.
To instantiate the parser class, JasperReports uses the createXMLReader() method of the XMLReaderFactory class.
In this case, it will be necessary at runtime to set the org.xml.sax.driver Java system property to the full class name of the SAX driver, as specified in the SAX 2.0 documentation.
You can achieve this in two ways. We shall explain both using the Xerces XML parser, just like we do it in the provided samples. If you use a different SAX 2.0 XML parser, you have to modify the name of the parser class accordingly.

The first way you can set a system property is by using the -D switch in the command line when you launch the Java Virtual Machine:
java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser 
        MySAXApp sample.xml
In all the provided samples we use the Ant build tool to perform different tasks. We supply this system property to the JVM using the <sysproperty> element of the <java> built-in task:
<sysproperty 
        key="org.xml.sax.driver" 
        value="org.apache.xerces.parsers.SAXParser"/>
The second way to set a system property is by using the java.lang.System.setProperty(String key, String value) method like this:
System.setProperty(
    "org.xml.sax.driver",
    "org.apache.xerces.parsers.SAXParser"
    );
Check the jsp/compile.jsp and WEB-INF/classes/servlets/CompileServlet.java files in the /demo/samples/webapp sample provided, to see this in action.
 
  (back to top)  
 

RowsExceededException is thrown when exporting large reports to Excel

 
  When exporting large reports, using a report virtualizer might not be enough in the case of the Excel exporter. There is one more limitation to be considered here: even if a single page per sheet is set, it's still possible that some pages contain more than 65536 rows (ie. the maximum number of rows allowed to be contained in an Excel sheet). In this case, a RowsExceededException will be thrown, and the report execution will be interrupted.
In order to avoid this, the new MAXIMUM_ROWS_PER_SHEET export parameter was introduced. When set, it specifies a customized number of rows (<= 65535) allowed to be shown in a sheet. If any sheet contains more rows than that number, a new sheet is created for the remaining rows to be displayed. Negative values or zero mean that no limit has been set, and Excel will manage the rows amount by itself.
As an alternative, especially if you need to export multiple reports at a time having different numbers of allowed rows, you can set the PROPERTY_MAXIMUM_ROWS_PER_SHEET property in any of your report templates. If set, this property will take precedence over the export parameter.
 
  (back to top)  
 

Why is the first record missing from my subreport?

 
  This is probably caused by the fact that you pass to your subreport the same data source as the one used by the master report. The data source expression of you subreport would look like this:
<dataSourceExpression>
  $P{REPORT_DATA_SOURCE}
</dataSourceExpression>
It is highly unlikely you really want to do that, since the subreport will move the record pointer in the data source it receives and thus will "consume" the master report data, making it end abruptly.

The most common situation where we face this problem is when the master report does not need to iterate on anything, but rather give the data source to one of its subreports.
Such subreports could be placed on the title band of the master. The master report consumes the first record of the data source before passing it further to its surepbort, hence the observed effect.

Even in cases like these, when the master report does not actually iterate on anything, but rather passed a data source to its subreport, it is not normal to pass the built-in REPORT_DATA_SOURCE parameter to the subreport as shown above. Instead, the subreport data source should be passed in from the parent application using a user-defined parameter in the master report and not passed in as the data source of the master report itself.
...
<parameter name="MySubreportDataSource" 
    class="net.sf.jasperreports.engine.JRDataSource"/>
...

<subreport>
...
<dataSourceExpression>
  $P{MySubreportDataSource}
</dataSourceExpression>
...
</subreport>
 
  (back to top)  
 

How to keep group together?

 
  Sometimes you want a specific report group not to break across subsequent pages, but to stay together on the same page, if possible.
In many cases, the minHeightToStartNewPage attribute of a group is enough to prevent a group starting too low on a page, minimizing the risk that the group will break onto the next page.
However, this does not work in all cases, because sometimes it would require a value that is too high for the minHeightToStartNewPage attribute and thus introduces too much unwanted white space in the document.

The second solution is to separate the content of the un-breakable group into a separate subreport and put that subreport in a master report band (probably the detail band) that has isSplitAllowed="false". Such refactoring means that the query of the master report should be modified so that the master report iterates on group records alone (something like a GROUP BY clause would be needed in SQL, or the query should retrieve values from the parent database table, not making a join with the child table) and that the subreport receives a filter value as parameter, to use in its query so that it displays only the child records belonging to the current group record in the master.
 
  (back to top)  
 

When should I compile my report templates and how?

 
  The exact moment when report compilation needs to occur depends on whether report design templates change during the application's execution.

In many cases, report designs (JRXMLs) do not change at runtime - the application only provides dynamic data and parameter values to predefined report templates to produce runtime reports.
In such cases, report designs can be considered application source code and it is recommended to compile them during the application build process and to include the compile reports (*.jasper files) in the binary/deployed application. Read more on how to do this in the JasperReports Tutorial section on report compilation.

In more complex scenarios, report templates need to be generated, changed or deployed at runtime, hence reports have to be compiled at runtime.
In such cases it is recommended to use the JDT-based report compiler because:
  • It doesn't need to use (temporary) files, like the JDK-based report compilers.
  • It uses the context classloader to resolve classes, while JDK-based report compiler work with a filesystem classpath that needs to be set up by the user.
To use the JDT-based report compiler, one simply has to include the JDT compiler jar distributed with JasperReports (or a JDT core jar downloaded from Eclipse).
The failure to include the JDT compiler jar in your application may result in errors like CreateProcess: javac -classpath or package net.sf.jasperreports.engine does not exist. The simplest solution to fix such errors is to leverage the JDT report compiler, thus avoiding the need of properly setting up a JDK-based report compiler.
 
  (back to top)  
 

How to use Java 5 expressions in a report?

 
  Java 5 enhancements such as autoboxing/unboxing can be leveraged to make report expressions more concise and simpler to understand.
For instance, the following JRXML fragment
<parameter name="A" class="java.lang.Integer">
  <defaultValueExpression>
    new Integer(3)
  </defaultValueExpression>
</parameter>
...
<textField>
  <reportElement x="280" y="150" width="200" height="35">
    <printWhenExpression>
      Boolean.valueOf($P{A} != null)
    </printWhenExpression>
  </reportElement>
  <textFieldExpression class="java.lang.Integer">
    new Integer($P{A}.intValue() * 2)
  </textFieldExpression>
</textField>
would look like this when using autoboxing/unboxing:
<parameter name="A" class="java.lang.Integer">
  <defaultValueExpression>3</defaultValueExpression>
</parameter>
...
<textField>
  <reportElement x="280" y="150" width="200" height="35">
    <printWhenExpression>
      $P{A} != null
    </printWhenExpression>
  </reportElement>
  <textFieldExpression class="java.lang.Integer">
    $P{A} * 2
  </textFieldExpression>
</textField>

To use Java 5 syntax in the report expressions, you need to make sure that the report compiler compiles Java 5 code.

JDK-based report compilers automatically compile Java 5 code when using JDK 5 or newer.

The JDT-based report compiler, which is recommended when compiling reports at runtime (see this FAQ), needs to be configured to compile Java 5 code. This can be done by including the following properties in the jasperreports.properties file (which needs to be placed on the application's classpath):
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.codegen.TargetPlatform=1.5
 
  (back to top)  
 

Why is the JasperViewer closing my Tomcat server?

 
  I'm a little embarrassed to write this FAQ, but many similar questions posted on the JasperReports forums indicate that this might be very useful to some people out-there.

First of all, if you experience this, it means we are talking about a Web application. The JasperViewer is a Swing based desktop application. So the first thing you should ask yourself is: "How should I expect a desktop Swing client application to work within a Web server?"
If you did not ask yourself this yet, then please take your Web application and deploy it on a different computer and try to access it using a browser from your computer. What do you see when you get to the point where the JasperViewer should pop-up? Do you see it opening up on your computer, which is the client machine? Of course not! You see it being open on the other machine, which is now the server.
While you were working with the Web server on your computer, everything went well, because you probably did not realize that your machine acted both as a server and as a client at the same time.

I will not attempt to explain more about what client/server architecture is and how Web applications are supposed to work. There are better people and books that explain this and I recommend you look for them and read them.
I will only say that if you want to display reports using the Swing viewer inside a Web application, than the Swing viewer should be deployed as a Java applet and not called directly from within server-side code. Please take a look at the /demo/samples/webapp sample provided with the JasperReports project package and see how we make use there of the jasperreports-xxx-applet.jar to display reports in Web environment.

The FAQ here explains why applications exit when the JasperViewer is closed.
 
  (back to top)  
 

Why is my text not displayed correctly in PDF?

 
  When your PDF reports contain texts that do not stretch properly (i.e. are truncated or leave some space unused), or have improper line spacing, the probable cause is that the Java/AWT and PDF fonts used for the report text elements do not match.

The fontName attribute of a report text element is resolved to a Java/AWT font which is used at report fill time to compute several text layout attributes including how much does the element need to stretch in order to accommodate its contents, or what part of the text does fit if the element is not allowed to stretch. When the report gets exported to PDF, the text layout parameters computed at fill time are used along with a PDF font determined by the pdfFontName attribute of the text element. If the PDF font metrics are not identical to the metrics of the Java/AWT font, then the text in the PDF output might not fit entirely or might not use the entire space reserved for the text element.

Because of this, the JasperReports engine works by the contract that the Java/AWT font (specified using the fontName attribute) and the PDF font (specified using the pdfFontName attribute) resolve to the same physical font (or to fonts that have identical metrics).

One thing to pay attention to is making sure that the fonts set in the report via fontName attributes are actually available in the Java VM, because AWT silently uses the default font when a specific font cannot be loaded.

When confronted with such issues it is useful to display the report in JasperViewer, as the viewer would use the same Java/AWT fonts that were involved in computing the text layout attributes (assuming that the fonts are still available in the JVM). If the report displays properly in JasperViewer, then it is very likely that the PDF fonts do not match the Java fonts.

One more possible cause of text not displaying properly in PDF (even when the fonts match) is the fact that the default AWT and PDF line breaking policies differ slightly. The solution to this issue is to instruct the PDF exporter to use the AWT line breaking policy. This is done by setting the FORCE_LINEBREAK_POLICY exporter parameter to true, or by setting the net.sf.jasperreports.export.pdf.force.linebreak.policy property to true either globally (in jasperreports.property) or at report level.
 
  (back to top)  
 

Why do some elements disappear in HTML or XLS output?

 
  The most probable cause of this is the fact that these elements overlap with some other elements. The HTML, XLS and the ODT exporters are so-called grid exporters. They arrange the content of a document page in a grid using a positioning algorithm. In each cell of the resulting grid we can put only one element, so the elements that are placed behind some other elements will be ignored when exporting to these formats and will not appear. The missing elements could overlap with only one or few pixels, but that is enough for then to be removed from the grid.
To avoid this effect, you should follow the recommendations in this other FAQ about making grid exporter friendly reports.
 
  (back to top)  
 

How can I suppress page headers and footers when exporting to XLS?

 
  When exporting a document, we can filter out content using an ExporterFilter instance that we pass as value for the JRExporterParameter.FILTER exporter parameter.

But in case no filter instance is passed in, the exporter searches for some configuration properties with a given prefix, both at report level (exporter hints) and globally, in order to decide if a default exporter filter instance should be created on-the-fly and used internally, when exporting the current document.
If created, this default exporter filter will filter out content from the exported document based on element origin information. Elements present in JasperReports generated documents keep information about their origin. The origin of an element is defined by its parent section in the initial report template, and optionally the name of the group and/or subreport that the element originated from.

Removing page headers and page footers from the document when exporting to XLS can be achieved by putting these custom properties in the report template:
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.1" 
  value="pageHeader"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.2" 
  value="pageFooter"/>
If you want to remove page headers and page footers, but keep the first page header in place (useful when all pages are exported to the same sheet, in a flow layout) the following properties have to be used in the report template:
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.keep.first.band.1" 
  value="pageHeader"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.2" 
  value="pageFooter"/>
Note that there is no property prefix available to keep the last occurrence of a band. If you would want to keep the last page footer, then the best solution is to actually use the <lastPageFooter> section of the report template.

If you want to remove both page headers and page footers and also the group footers of a group called ProductGroup, that comes from a subreport called ProductReport this custom properties are needed:
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.1" 
  value="pageHeader"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.2" 
  value="pageFooter"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.band.3" 
  value="groupHeader"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.group.3" 
  value="ProductGroup"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.report.3" 
  value="ProductReport"/>
Note that the number at the end of the properties names is just an arbitrary suffix. The only thing that counts is that the suffix be the same for properties referring to the same filter. The last three properties in the above example define the filter that will exclude group header of ProductGroup from ProductReport subreport. Instead of the numeric suffix, you could put any suffix, as long as it does not coincide with suffixes from other filters. The following example will exclude the same group header while keeping its first occurrence:
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.keep.first.band.myGroupFilter" 
  value="groupHeader"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.keep.first.group.myGroupFilter" 
  value="ProductGroup"/>
<property 
  name="net.sf.jasperreports.export.xls
    .exclude.origin.keep.first.report.myGroupFilter" 
  value="ProductReport"/>
The xls token inside the properties prefixes refer to the particular export format that is targeted and the general syntax of the origin exporter filter properties is:
net.sf.jasperreports.export.{format}
  .exclude.origin.{suffix}.{arbitrary_name}

net.sf.jasperreports.export.{format}
  .exclude.origin.keep.first.{suffix}.{arbitrary_name}
Other supported format tokens are pdf, html, rtf, odt, xml, txt, csv and graphics2d, while the only accepted suffixes are band, group and report.

These properties make best sense when placed inside a report, to filter our specific portions of that particular document, but they also work globally, if placed in the jasperreports.properties file (see Configuration Reference). This would allow removing the page headers and page footers from all reports, when exporting to XLS, for example.

All the above examples can be tested by putting the properties in the MasterReport.jrxml file of the /demo/samples/subreport sample provided with the project distribution package.
 
  (back to top)  
 

Why don't I see Asian characters (CKJ) in the generated PDF file?

 
  In order to solve these problems, you'll have to do some initializing work.

1. When exporting reports to PDF format, JasperReports uses the iText library. If iText has to deal with CJK (Chinese Japanese Korean) fonts, it requires 2 extra libraries: iTextAsian.jar and iTextAsianCmaps.jar. Add these jars in the classpath of your application.

2. In order to be able to read the text generated with iText using CJK fonts, you will also need to download and install the special Acrobat Reader Asian font pack (if you don't, it's possible that your Reader will still ask you to install it while opening a PDF file containing CJK fonts).
A good point to start this operation would be
here.

3. Then, in your report set the pdfFontName attribute with an appropriate font name existing in the Adobe Reader font pack (for example, pdfFontName="STSong-Light"). Set the pdfEncoding with an appropriate encoding for that charset (i.e. pdfEncoding="UniGB-UCS2-H"). Set isPdfEmbedded to "false".

4. If you need to export your report to other formats, set the fontName attribute with an appropriate true type font name installed on your OS, or use the
FONT_MAP export parameter.
And that's all.
 
  (back to top)