Let’s go to the topic and introduce today’s JasperReport, ireport or jasperstudio, and then two are its visualization tools.
What is JasperReport?
This product actually has many domestic users. It is a foreign product, and it can be said that it is widely used in the JAVA reporting field.
When I first came into contact with this report, I liked it very much. The most important thing is its visualization tool, which really made me unable to stop. I could actually design JAVA reports by simply drawing pictures. Speaking of drawing, we can use visual tools to design report templates visually, and the file formats it supports are very wide, including EXCEL, WORD, PDF, HTML, XML, CSV, etc.
Doesn't it look very powerful? It's designed at one time and reused multiple times. Of course, powerful things often have two sides. I encountered this and tortured me for a long time. I will describe it in detail later.
JasperReport's big breasts
I said earlier that JasperReport or ireport or jasperstudio is actually inaccurate. The second brother ireport and the third brother jasperstudio are actually jasper's auxiliary visual design tools. You can design jasper reports without using it, and write more XML whites. Before 5.5, this tool was called ireport. After 5.5, with the birth of my third brother Jasperstudio, ireport was completely replaced. In fact, these two tools are basically the same, one-child compatriots.
Specific workflow:
①First, Jasper will obtain the XML file of the format information that needs to be output, and then compile a .jasper type file from the XML file. Then this jasper file can be loaded in our application to generate the final report. Do you have a very familiar feeling? Yes, this is very similar to Java and needs to be compiled.
The following picture shows the ireport operation interface. It’s similar to jasperstudio, so I won’t post it. You can download it on Baidu by yourself.
Let me briefly introduce each type of band in the picture above.
(1) Title band: The title segment is only displayed on the top part of the first page of the entire report. Except for the first page, no matter how many pages there are in the report, the content in the Title band will no longer appear.
(2) pageHeader Band: As the name suggests, the content in the pageHeader segment will appear in every page in the entire report, and will be displayed at the top of the page. If it is the first page of the report, the content in the pageHeader will be displayed under the Title Band. In all other pages except the first page, the content in the pageHeader will be displayed at the top of the page.
(3) pageFooter Band: Displayed at the bottom end of the page.
(4) lastPageFooter Band: Displayed at the bottom of the last page.
(5)Detail Band: Report content segment, content that needs to be repeated in the design report in this band, and the content in the Detail segment will appear on every page.
(6) columnHeader Band: For the header segment of the Detail Band, generally in this segment, the header of the report is drawn.
(7) columnFooter Band: for the end of the table of the Detail Band.
(8)Summary Band: The total segment of the table appears after the Detail band on the last page of the entire report. It is generally used to count the total value of one or several fields in the report.
The above is all the visualization tools. In fact, it is very simple to use. You can find it by exploring it. Since it is a real record of the pit, this is naturally not the point, so I won’t talk about it.
Applications in code
These are the steps I have summarized. Maybe the description is not very accurate. Please do it.
①Design templates, generate JRXML files, ↑↑The above visualization tool designs the template styles you need
② Compile templates, JRXML is compiled into Jasper files, just like .java and .class files in java, the program needs to run the binary file of *.jasper.
In fact, this step can be directly compiled with ireport to generate .jasper, and of course it can also be compiled through the jasper program at runtime. However, it is recommended that if compiled in the program, the jasper version is best consistent with the ireport or jasperstudio version.
③Execute report (data is filled into report)
1. Load the template to generate a Jasperreport object
2. Use JasperFillManager to generate JasperPrint object
④Finally, use JRXlsxExporter to export the report or display it
Loading templates
Since we have generated .jasper or .jrxml files using visualization tools, we naturally need to let the program load it.
Loaded code, return jasperport object
if (urlPath.endsWith(".jrxml")) { //compile jrxml to jasper try { InputStream is = url.openStream(); jasperReport = JasperCompileManager.compileReport(is); } catch (IOException e) { throw new BaseException("Load jasper error", e); } catch (JRException e) { throw new BaseException("The jrxml template transform to jasper file error", e); } catch (Throwable e) { throw new BaseException("The jrxml template transform to jasper file error", e); } catch (Throwable e) { log.error(e); throw new BaseException(e.getMessage()); } } else if (urlPath.endsWith(".jasper")) { try { InputStream is = url.openStream(); jasperReport = (JasperReport) JRLoader.loadObject(is); } catch (IOException e) { throw new BaseException("Load jasper error", e); } catch (JRException e) { throw new BaseException("The jrxml template file error", e); } catch (Throwable e) { log.error(e); throw new BaseException(e.getMessage()); } } else { throw new BaseException("Invalid file!"); }Get the data source in the report
Here I use javabean to get it
JRDataSource dataSource = null; if (fieldValues != null && fieldValues.size() > 0) { dataSource = new JRBeanCollectionDataSource(fieldValues); } else { dataSource = new JREmptyDataSource(); } fieldValues is the collection of pojos obtained in the database.
Perform report filling
Get the jasperprint object
Map<String, Object> parameterValue = new HashMap<String, Object>();jasperPrint = JasperFillManager.fillReport(jasperReport, parameterValue, dataSource);
Finally, we use JRXlsxExporter to export the report
This is also the place where the most configuration parameters are required
baos = new ByteArrayOutputStream();exporter = new JRXlsxExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
exporter.exportReport();
Completed, the data has been written into the output stream. You decide how to output it yourself, is it much more brief than other methods of code introduction.
Indeed, JasperReport has an incomparable advantage in code writing, and various APIs have been packaged. But it may be that Chacha has done too much and there are many problems.
JasperReport's problem
1. The blank space before two rows
If you use the above code to export EXCEL, you will find that the background of Excel is white, without Excel's small grids. This is because the default background of jasper is white, so it is easier to be compatible when exporting other formats. Of course, it is not necessary to export EXCEL. Just add the following two lines to solve it.
//Remove the blank exporter.setParameter before two lines(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE); exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,Boolean.TRUE); //Set the background color of the Excel table to the default white exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE);
2. The data volume is large, the title is written multiple times
If you have a lot of Sheet data, you may encounter the situation where the table header is printed multiple times. In this case, you need to add the height setting.
Field pageHeight = JRBaseReport.class.getDeclaredField( "pageHeight"); pageHeight.setAccessible(true); pageHeight.setInt(jasperReport, Integer.MAX_VALUE);
3. Cell type problem
Sometimes, the Excel report we export needs to be calculated using Excel functions. If all of them are in text formats, we naturally cannot calculate it. In this case, we need to use
//Automatically select the format exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
Remember, when designing a report, select the correct type of the Field field.
4. The problem of multiple Sheets
The simple example above is just a file containing a Sheet page. What if our requirement is to export multiple Sheets in one file? Don't worry, this Japser has already thought of it for us.
Just change the export steps above to the following
baos = new ByteArrayOutputStream();exporter = new JRXlsxExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, listJasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);//Set to true, in an excel, each individual jasper object is placed in a sheet exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,Boolean.TRUE);
JRExporterParameter.JASPER_PRINT_LIST, pass in a collection of listJasperPrints, each JasperPrint is a Sheet page.
5. There is no error reported in Linux startup, but the report cannot be exported
In fact, this problem has bothered me for a long time. Later, with the help of the boss, I remembered the problem, because it didn't throw an Exception at all, but an Error. I saw that some classmates asked this question online, so I posted it.
You can use throwable to capture the error message and get the error message: java.lang.InternalError: Can't connect to X11 window server using ':0.0' as
Solution: Modify tomcat/bin/catalina.sh and add JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"
6. Big data memory overflow and memory leakage issues! !
I need to talk about the difference between EXCEL 03 and 07 versions. I remember that the 03 version only supports 65532 lines, but after 07 version, it became much larger. I forgot the specific number, it is not the same order of magnitude anyway.
JRXlsxExporter supports exporting xlsx files.
JRXlsExporter is an xls file, which is easy to identify. The exported tools are the same as those in Excel.
Then there are the memory overflow and memory leak issues. I believe that friends who play JAVA have basically encountered this.
The most common solution to memory overflow is to increase the memory size of the container and increase the memory size of tomcat. You can use Baidu, there are many methods, so you won’t remake the wheel.
Here is a reminder that if you are using tomcat, the configuration methods of Windows installation, decompression and Linux are different, so please pay attention.
What I need to introduce here is the JasperReport method. In fact, JasperReport has a solution to big data. It was launched in a very early version, the emulator of JRFileVirtualizer.
What is this thing used for? In fact, it will write data to a temporary file on the hard disk according to the parameters you set, which solves the problem of excessive memory usage and overflow when filling reports.
Currently, JasperReport has 3 emulators, all of which are used to solve this problem.
They are:
①JRFileVirtualizer
②JRSwapFileVirtualizer
③JRGzipVirtualizer
What is the difference between these three emulators?
First, I launched the earliest JRFileVirtualizer. When I was testing, when I exported about 30W of data, it would report memory overflow. Later, after adding this, I could export it normally. This emulator will generate a temporary file for each object and store it on the hard disk to solve the memory usage problem. However, because there are many temporary files generated, the memory consumption of file creation and deletion is invisibly increased, so it is not very recommended.
//Write multiple files JRFileVirtualizer virtualizer = new JRFileVirtualizer(2, catchPath); Map<String, Object> parameterValue = new HashMap<String, Object>(); parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
virtualizer.setReadOnly(true);
catchPath is the file cache path and must exist, otherwise an error will be reported.
Then there is JRSwapFileVirtualizer, which was launched to solve the problem of JRFileVirtualizer. This emulator will only create a temporary file, and each object will account for a part of this file, so the memory consumption of file creation and deletion is reduced. In fact, this is not particularly recommended.
//Write a single file RSwapFile arquivoSwap = new JRSwapFile(catchPath, 4096, 25);JRAbstractLRUVirtualizer virtualizer = new JRSwapFileVirtualizer(2, arquivoSwap, true); Map<String, Object> parameterValue = new HashMap<String, Object>();parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
virtualizer.setReadOnly(true);
Finally, there is JRGzipVirtualizer. When you see Gzip, you don’t know if you have any connection to the word compression. That's right, this emulator uses a special compression algorithm that can compress memory footprint to one-twentieth or one-tween, which is amazing.
JRAbstractLRUVirtualizer virtualizer = new JRGzipVirtualizer(2);Map<String, Object> parameterValue = new HashMap<String, Object>();parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);jasperPrint = JasperFillManager.fillReport(jasperReport, parameterValue, dataSource);
Having said so much, in short, there are three types of emulators to solve the memory overflow problem. I have also read many blogs that use JRFileVirtualizer to solve the memory big data problem. Then I want to say here that I least recommend using JRFileVirtualizer emulator because it not only consumes a lot of files to create, but also has a very serious bug and memory leak! ! ! There is also JRSwapFileVirtualizer that has this problem.
In addition, it should be noted that without using the emulator, there will be memory leakage problems. When you export the report, dump the stack information and find that there are many instances of the net.sf.jasperreports.engine.fill.JRTemplatePrintText class, which cannot be recycled and cannot be recycled! ! ! And this problem still exists in the latest version of japserreport 6.x. There are many such problems in the jasper community and Stack Overflow, but there is no solution.
Here we recommend the JRGzipVirtualizer emulator. Although there are still leak problems, due to the unique compression algorithm, the memory leakage problem has been controlled to a very small range. It is considered a solution to alleviate the leaked memory usage by about 90%.
In general, I have given up this plan now, and I wrote it out so that my brothers will avoid detours later. After getting a POI tool class, I will next prepare to change all reports into POI export methods. Speaking of which, the POI big data solution is quite good.