A hole in the Jasperreport

Source: Internet
Author: User
Mac Book Pro 10.13.6
Jaspersoft Studio community version 6.6.9
JDK 8

Install Jaspersoft Studio
Jasper Report is divided into a professional version (paid) and a community version (free). If it is only used to design some basic report templates, the community version is enough. You can download it from here and choose Jaspersoft Studio.

  jaspersoft-studio.png Problems you may encounter during installation
If everything went well during installation, you can skip this section directly.

  install-jasper-studio.png
If you encounter the above error during installation, you can try the solution:

Step 1
System Preferences-> Security & Privacy-> General

  security-privacy.png
Step 2
If Step 1 does not solve the problem, open Terminal and execute the following command:

# sudo bash
# xattr -cr "/ Applications / TIBCO Jaspersoft Studio 6.6.0.app"

If you are curious about this xattr, you can execute man xattr to read the explanation.

Understanding Report Band
There are many kinds of Bands built into Jasper Studio. Different Bands have different uses and have different default behaviors. Except for the Background Band, the total height of other Bands should be less than or equal to the maximum height of a page minus the top and bottom margins.

Title
By default, it will only appear at the very top of the first page. It can also be controlled as shown below on a separate page.

  title-on-new-page.png Page Header
The header will appear at the top of each page by default. When the Title and Summary Band are set to be displayed on a separate page, the header will not be displayed.

Detail
Detail Band is amazing, it can automatically iterate over all elements in DataSource, if DataSource is null, only static text will be displayed. By default, the Detail Band will repeat as many times as there are records in the Query of the Main Dataset.

See here for a more detailed explanation.

Page Footer
The footer will appear at the bottom of each page by default.

Last Page Footer
If you want to put some different content on the footer of the last page, you can consider using this band.

Summary
By default, it will be displayed at the end of the report. Like Title Band, it can also be set to be displayed on a separate page. If the report is based on statistics, it will generally put some calculated content, such as: maximum value, minimum value, average value, total value, etc. Of course, according to actual needs, you can also put any content.

  summary-on-new-page.png Background
As the name suggests, this is generally the background of the report, such as watermarks. Its maximum height can be the same as the height of a page of the report.

Other Band
Column Header, Group Header, Group Footer, Column Footer, No Data These bands are also easier to understand according to their names. The specific explanation is explained in more detail in this article.

Global Settings
In the global settings of the page, you can set the page size, margins, size units, page orientation, etc.

  page-format.png
A small suggestion is, if the design draft is what unit of measurement, what unit of measurement is set here, and then set the size as the design draft, to avoid the tedious size conversion when designing the template.

One thing to note about page margins is that even if the top, bottom, left, and right are set to 0, and the final exported PDF is printed, the margins are not necessarily 0, because the printer may have default margin settings.

  printer-settings.png page number
In the report, there is almost always a need to display the page number, such as Page x of y. It seems simple, and preset components are already provided in Jasper Studio.

  page-x-of-y.png
This built-in component is implemented through two Text Fields. If the accuracy of alignment is not high, it is convenient to use this component directly. The principle is to use the $ V {PAGE_NUMBER} variable twice, but just set different evaluation timings. Set the Evaluation Time to Now for the page number of each page and Report for the total page number.

However, if the precision is very high, this method is not suitable. We need to use a Text Field to implement it. For specific methods, please refer to here.

Set Chinese and English as different fonts (Font Set)
I believe that the use of Word software for Chinese and English typesetting may have responded to this demand. It is necessary to set different fonts for Chinese and English in an article. This menu item can be set in Word, but in Jasper Report Realizing this requirement is not so simple.

Mainly involves the following steps:

Create Font Set
The steps to create Font Extension and Font Set are relatively intuitive, just refer to the official documentation.

Referencing font files in Java code
If there is no corresponding font in the system where the server is located, an error will be reported when Jasper Report tries to generate a PDF. The following steps are required to solve:

First, you need to export the Jar package containing fonts from Jasper Studio. Once click Window> Preferences> Jaspersoft Studio> Fonts, select the created Font Set and the fonts it contains and click Export.

Write the name in the dialog box for exporting Font to Jar package and save it. For example, SampleFontSet.jar. This Jar package is different from the ordinary Jar package, it contains some additional information needed by Jaspersoft.

Introduce font Jar package in code dependency.

  jasper-font-set.png Embed fonts in PDF
Some people may wonder whether embedding the fonts used in the report into the exported PDF will cause performance problems. After all, the font file size of general Chinese characters is relatively large, tens of trillions. When exporting PDFs with Japser, only a subset of the font files used will be embedded, so there is almost no need to worry about the volume of the exported PDF.

Measure the actual width of the Text Field (using Font Set)
If the font set on the Text Field is a custom Font Set, then you need to pay attention, it is not so easy to measure the true width. The current solution is to separate the Chinese characters and non-Chinese characters in the text, and then set them to the corresponding font, and then measure the width of each, and finally add up the actual width of the text.

Separate Chinese characters and non-Chinese characters
  
  private static Pair <String, String> splitHanAndOthers (String str) {
        StringBuilder hanToken = new StringBuilder ();
        StringBuilder othersToken = new StringBuilder ();

        for (int i = 0; i <str.length ();) {
            final int codePoint = str.codePointAt (i);

            if (UnicodeScript.of (codePoint) == UnicodeScript.HAN) {
                hanToken.append (str.charAt (i));
            } else {
                othersToken.append (str.charAt (i));
            }
            i + = Character.charCount (codePoint);
        }

        return Pair.of (hanToken.toString (), othersToken.toString ());
    }

Measure the actual width of the text
    private static float getWidth (JRPrintText jrPrintText, String text, String fontName) {
        final DefaultJasperReportsContext instance = DefaultJasperReportsContext.getInstance ();

        final JRDefaultStyleProvider defaultStyleProvider = jrPrintText.getDefaultStyleProvider ();
        JRPrintText printText = new JRBasePrintText (defaultStyleProvider);
        printText.setText (text);
        printText.setFontName (fontName);
        printText.setFontSize (jrPrintText.getFontsize ());

        final JRStyledText hanTextFullStyledText = printText.getFullStyledText (JRStyledTextAttributeSelector.getAllSelector (instance));
        final JRTextMeasurer measure = JRTextMeasurerUtil.getInstance (instance) .createTextMeasurer (jrPrintText);
        final JRMeasuredText measuredText = measure.measure (hanTextFullStyledText, 0, 0, false);
        return measuredText.getTextWidth ();
    }

Calculate the total width
    
private float getTotalWidth (JRPrintText jrPrintText, String text) {
        final Pair <String, String> hanAndOthers = splitHanAndOthers (text);
        final String han = hanAndOthers.getLeft ();
        final String others = hanAndOthers.getRight ();

        final float hanWidth = getWidth (jrPrintText, han, "JianSong");
        final float othersWidth = getWidth (jrPrintText, others, "CorporateS");
        return hanWidth + othersWidth;
    }

Image Display picture
Path problem
Add an Image component in Jasper Studio, set the path of an image correctly, and click the preview to see the displayed image. But careful students will find that the path of the picture in the .jrxml template file is an absolute path, which is definitely not feasible in the actual production process.

Therefore, a method was found by searching, which can solve the path problem of static pictures. Write an expression like this in the expression of the Image component:

this.getClass (). getResourceAsStream ("/ images / logo.png")
  image-expressio
n.png
There are several other scenarios that may work directly by writing relative paths, which I have not verified.

Parameter transmission
In fact, the expression of the Image component not only supports the path of writing pictures, but also reads the pictures into memory in the code and passes them directly in the form of InputStream, but to ensure that each Stream can only be consumed once, do not reuse the same InputStream, if you want to reuse, consider using the isUsingCache property of the Image component. However, there are several other types supported by Jasper:

* java.lang.String
* java.io.File
* java.net.URL
* java.io.InputStream
* java.awt.Image
* net.sf.jasperreports.engine.JRRenderable
Examples can refer to this.

Problems you may encounter when using InputStream
net.sf.jasperreports.engine.JRException: java.io.IOException: The byte array is not a recognized imageformat.
      at net.sf.jasperreports.engine.export.JRPdfExporter $ InternalImageProcessor.processImageRetainShape (JRPdfExporter.java:1747)
      at net.sf.jasperreports.engine.export.JRPdfExporter $ InternalImageProcessor.process (JRPdfExporter.java:1604)
      at net.sf.jasperreports.engine.export.JRPdfExporter $ InternalImageProcessor.access $ 300 (JRPdfExporter.java:1532)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportImage (JRPdfExporter.java:1472)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportElements (JRPdfExporter.java:1090)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportFrame (JRPdfExporter.java:3117)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportElements (JRPdfExporter.java:1098)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportPage (JRPdfExporter.java:1053)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportReportToStream (JRPdfExporter.java:917)
      at net.sf.jasperreports.engine.export.JRPdfExporter.exportReport (JRPdfExporter.java:537)
      at net.sf.jasperreports.engine.JasperExportManager.exportToPdfFile (JasperExportManager.java:155)
      at net.sf.jasperreports.engine.JasperExportManager.exportReportToPdfFile (JasperExportManager.java:503)
      at com.finger.hr.controllers.HRCreatePDFController $ 2.run (HRCreatePDFController.java:244)
Caused by: java.io.IOException: The byte array is not a recognized imageformat.
      at com.lowagie.text.Image.getInstance (Unknown Source)
      at net.sf.jasperreports.engine.export.JRPdfExporter $ InternalImageProcessor.processImageRetainShape (JRPdfExporter.java:1742)
      ... 12 more

The solution is strange, and I do n’t know why.

If the parameter passed is an independent InputStream type field, there will be the above error. The solution is to wrap this separate field into a Java object (: D).

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class PhotoDto {
    private InputStream photo;
}

List List display line number
Whether it is List or Table, if you just want to display a simple line number, the easiest way is to use $ V {REPORT_COUNT}. If there is some more complicated calculation logic for the line number, it is best to deal with it in the code and then pass it to Jasper as a field of the data to render directly.

_THIS Dafa
If the data passed to List (or Table) is a basic type (here, let's consider String as a basic type, in fact, as long as the objects that do not contain attributes meet the conditions), then when referring to a single data You have to pay attention, because the basic type of data does not exist in the field, so you need to make an article on the naming of the Field.

For example, dataSource is List <String>, then when defining Field, there is no need to refer to the field name of the object. At this time, we only need to define the field name as _THIS, and write $ F {_THIS} in the referenced place . For more explanation refer here.

Table Dataset Table Pit in the nest
Nesting Table in Table can achieve the effect of merging cells, but if the height of a row in the outermost Table exceeds the maximum height of the page, it will directly report an error instead of pagination.

Grouping effect in Table
Merge Cell? impossible!
You cannot directly merge cells in the Table component. You can only achieve similar effects by nesting Tables.

Indentation of negative numbers in Table Cell
When using the designer of Jasper Studio version 6.6.0, when setting the coordinate value on the interface, there will be a case of unsuccessful saving. The negative coordinates can only be set by directly modifying the template source file. It feels like a bug in the IDE, which should be fixed in a subsequent version.

When right indent is set to a negative number, left indent cannot be 0. If it is 0, right indent will not take effect: ((I do n’t know why: boom :)

Leverage the features of the Table component
If there is a need for grouping, you can consider using Table Group Header and Group Footer to display data such as group names and subtotals.

Text Field & Static Text
Strech
Regarding Strech, there is an attribute in the designer called Strech With Overflow. When this attribute is checked, it means that when the length of the data exceeds the length of the component, it will automatically wrap, which is equivalent to Overflow in the vertical direction, and Jasper does not. Support Horizontal Overflow.

Pattern
In Jasper, you can easily set the display format of some special text, such as: date, time, currency, number, percentage, etc.

  pattern.png SubReport
Compile issues
In the designer of Jasper Studio, you can refer to the subreport in the main report by directly referencing the * .jasper file. However, if you do this in the actual product code, it is not conducive to version control of the source code, because this * .jasper file is a temporary file after compilation.

  subreport-expression.png
We can pre-compile the template of the subreport in the production code, and then directly pass it to the main report in the form of parameters (for example, the following code passes the compiled "checklist.jrxml" subreport as the parameter to the main report, and The reference expression in the main report is written as $ P {checklist}).
    String subreport = "checklist";
    JasperReport jasperReport = null;
    try (InputStream inputStream = getResourceAsStream (subreport + ".jrxml")) {
        jasperReport = JasperCompileManager.compileReport (inputStream);
    } catch (IOException | JRException e) {
        e.printStackTrace ();
    }
    params.put (subreport, jasperReport);

Detail Band Repeated problem many times
The number of times the Detail Band is rendered is determined by the number of data items in the Main Dataset. If it is found that the Detail Band is repeatedly rendered multiple times, then please check whether the Query of the Main Dataset has been added, and there is more than one query. If there is no scene to set Main Dataset, you can choose One Empty Record.

Multi-column layout of pages
The multi-column settings in the page settings only affect the Detail Band, Column Header, and Column Footer.

HTML Markup limitations
The use of HTML Markup is actually not as good as expected, and its functions are relatively limited. Only labels and attributes related to text format are supported, and labels related to layout are not supported. So if you want to achieve some effects through CSS, it basically won't work.

The supported HTML tags are as follows:

b
u
i
font
sup
sub
li
br
This list is found from the source code, and there is no document (or maybe I did not search it) explicitly listed. The source code is here.

Position Type is set to the misunderstanding in Float
At the beginning, I didn't particularly understand the principle of this Float Position Type. After taking a lot of detours, I understood the usage of Float Position Type after a long time. In fact, it is mainly because the appearance displayed in the Jaser Studio designer is easy to mislead people.

Under normal circumstances, when designing a template, we will put some components in a well-organized and orderly manner and look comfortable. Float drifts relative to the element closest to it in the designer, and its relative position is determined during the design template stage. Some components have a relatively large shape displayed in the designer. If you want to arrange them neatly, the elements that need Float will have a relatively large relative distance. In fact, at this time we cannot believe what we see with our eyes, nor can we have obsessive-compulsive disorder in the designer. Because many times it takes some elements to appear to be stacked together, the rendered effect is what we need instead.

  position-type-float.png
We have a template design in the actual project that looks like this, does it look messy, but to use Float to achieve the effect we want, it must also be designed like this.

Time of time
District issues
Solving the problem of the time zone in the report is simple. You only need to pass the corresponding time zone to a variable built into the report.

Map <String, Object> params = new HashMap <> ();
params.put ("REPORT_TIME_ZONE", TimeZone.getTimeZone (ZoneId.of ("Asia / Shanghai")));
Locate element coordinates by code (final maximum method)
If the dynamic positioning of components cannot be achieved in Jasper Studio, there is basically only one way to go. If this path cannot be realized, either change the demand or replace the Jasper Report solution.

Reference link
community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v71/getting-started-jaspersoft-studio-0
community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v630/understanding-bands
community.jaspersoft.com/wiki/report-structure-jaspersoft-studio
communities.ca.com/blogs/rob.ensinger/2015/12/28/how-to-single-textbox-page-x-of-y-page-counts-in-jaspersoft-reports
stackoverflow.com/questions/10673263/show-page-x-of-y-using-a-single-text-field
community.jaspersoft.com/documentation/tibco-jaspersoft-studio-user-guide/v630/working-font-extensions
stackoverflow.com/questions/3623420/image-expression-url-in-jasper-reports
stackoverflow.com/questions/11949333/passing-the-list-of-primitive-type-objects-as-datasource-for-subreport
stackoverflow.com/questions/27903072/print-liststring-each-element-in-new-field
stackoverflow.com/questions/11949333/passing-the-list-of-primitive-type-objects-as-datasource-for-subreport

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.