Recently, I made a function about exporting PDF, so I wrote a blog to record it.
1. Preparation.
The development tools I use are eclipse and TIBCO Jaspersoft studio 6.17.0
Needless to say, eclipse software is mainly TIBCO Jaspersoft studio 6.17.0, which is used to draw newspaper report templates
Software download address: Click me to jump
Skip the installation process and install by default.
2. Start drawing the template.
File - > New - > Jasper report - > blank A4 (i.e. blank template) - > set the report name - > select the data source (I will pass it through java code at that time, and here the template will be blank directly, i.e. select one Empty Record) - > finish
The area of the template design interface is described below. There are multiple band s in the middle template design area, which can be deleted by right clicking
Title: title area. If there are multiple pages of data, it will only be printed on the first page
Page Header: header area. In case of multiple pages, each page will be printed
Column Header: Column Header area, which prints the list data together with the Detail area below. In case of multiple pages, each page will be printed
Detail: multiple detail areas can be added, and multiple list data can be printed in combination. In case of multiple pages, each page will be printed
Column Footer: the bottom area of the list. In case of multiple pages, each page will be printed
Page Footer: the area at the bottom of the page. In case of multiple pages, each page will be printed
Summary: total area, which will only be printed on the last page
This is the template drawn by the company's demand style. Specifically analyze the contents; Some unused sections are deleted, leaving only title, four detail and page footer sections. Where detail1 is a single data, using text field, detail2 and detail4 are circular data, and a sub report is nested, that is, it is divided into header static text and sub report subreport, and detail 3 and title are pure static text. In addition, each small block is covered with a layer of frame. The advantage of using frame is that you can draw a border to circle a certain type of elements. Here, it is recommended to use a rectangular box, so that these elements can be operated as a whole. (if you have used android studio, you should also be familiar with this, which is nothing more than defining parameters, binding elements, dragging them to the design area and designing them into the expected style)
The difference between $p, $f and $V: P is the transfer parameter and cannot be empty. F is the carried data, which can be empty and V is the sum; P is defined in Parameters and F is defined in Fields.
Note: when defining P, F and V, you need to specify the type of this field. If the specified type is different from the type of the incoming value, an error will be reported.
The specific levels of elements are:
Note: DejaVu Sans is the best choice for the English part of the module. This font can be used by directly adding dependencies in springboot. Select other fonts. If there is no such font on the server, it needs to be imported manually, otherwise an error will be reported. Although this problem can be set in the configuration file to ignore, it will cause the display to be different from the expectation.
When the data is not worth it, null will be displayed. If you want to set it to blank, check Blank when null in the above figure.
This is probably the main template. Then prepare to design the sub template and bind it. The two sub template styles are:
Note: all margins are set to zero here, otherwise the embedded main template will be very separated and unsightly.
$V needs to be defined in Variable.
Primary sub report Association:
In step 1, select Subreport and drag it to the corresponding location. The Subreport window will pop up. Select the specified sub templates in order.
Step 2: click the subreport element to edit the details
Note: Expression is to query the location of the sub template. I set it as dynamic and use P to pass the path of the sub template. Select new net for data source Expression sf. jasperreports. engine. data. Jreancollectiondatasource ($f {sub1}) sub1 is a list collection used to save the data of sub templates.
3. Display template effect
Basically, the template is completed, and then run to see the style (write the pass parameter of $P):
There is no problem with the template here. You need to convert the jrxml file into jasper file. Then start the java side call and parameter transfer.
The above is to generate all jrxml files into jasper files, and the following is to generate only the current jrxml files.
4.java development
1. Add dependency
Because the version of TIBCO Jaspersoft studio is 6.17.0, the dependent versions I added are also 6.17.0. During the learning process, some partners said that inconsistent versions may lead to problems. Although there is no problem here, I still choose the same version to be safe. After all, don't make myself uncomfortable.
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.17.0</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-functions</artifactId> <version>6.17.0</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-fonts</artifactId> <version>6.17.0</version> </dependency>
Note: jasperreports dependency is the basic method jar, and jasperreports functions is the function jar. For example, the dateformat function used in my template needs to import this jar, otherwise it will not be recognized and an error will be reported. Jasperreports Fonts is a self-contained font, that is, DejaVu Sans font in the above template. When I write the requirements, I use Arial font at the beginning, and then there is no problem locally, but it can't be put into the test environment. The log shows that there is no Arial font. Although it can be added in the test environment, if I change another environment later, will an error be reported, Therefore, it is not recommended to manually add fonts to each PC. if you have to use Arial fonts, you need to do relative operations in the resource file, which will be written later. I won't talk about it here first.
2. Put the template in the designated position
Create jasper folder under resource, and then put jrxml and jasper files into this path, including fonts folder and fonts XML is used to add fonts, msyh ttf is the ttf file of Microsoft elegant black font. jasperreport. The properties file is used to set jasperreport to ignore the problem that there is no font error_ extension. Properties is used to configure the newly added font path.
fonts.xml
<?xml version="1.0" encoding="UTF-8"?> <fontFamilies> <fontFamily name="It's Microsoft yaheia"> <normal>jasper/fonts/msyh.ttf</normal> <bold>jasper/fonts/msyh.ttf</bold> <italic>jasper/fonts/msyh.ttf</italic> <boldItalic>jasper/fonts/msyh.ttf</boldItalic> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> <exportFonts> <export key="net.sf.jasperreports.html">'It's Microsoft yaheia', Arial, Helvetica, sans-serif</export> <export key="net.sf.jasperreports.xhtml">'It's Microsoft yaheia', Arial, Helvetica, sans-serif</export> </exportFonts> </fontFamily> </fontFamilies>
jasperreport.properties
net.sf.jasperreports.awt.ignore.missing.font=true
jasperreport_extension.properties
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory net.sf.jasperreports.extension.simple.font.families.dejavu=jasper/fonts/fonts.xml
3. Preparation of public methods:
public class JasperReportUtil { static JasperPrint getJasperPrint(InputStream jasperStream, Map parameters, List<?> list) throws JRException { JRDataSource dataSource = null; if (null == list || list.size() == 0) { dataSource = new JREmptyDataSource(); } else { dataSource = new JRBeanCollectionDataSource(list); } JasperPrint jasperPrint = JasperFillManager.fillReport(jasperStream, parameters, dataSource); return jasperPrint; } public static void exportToPdf(String jasperPath, Map parameters, List<?> list, HttpServletResponse response) throws Exception { OutputStream outputStream = response.getOutputStream(); try { ClassPathResource resource = new ClassPathResource(jasperPath); response.setContentType("application/pdf"); InputStream jasperStream = resource.getInputStream(); JasperPrint jasperPrint = getJasperPrint(jasperStream, parameters, list); JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream); } catch (Exception e) { e.printStackTrace(); outputStream.write("Exception Reading Report".getBytes()); } finally { outputStream.flush(); outputStream.close(); } } }``` exportToPdf Parameters of this method: 1.Template path; two.data list;3 seeing the name of a thing one thinks of its function response,Used to get the output stream.
4. Call method
control layer
@RequestMapping(value = "/printPdf",method = RequestMethod.POST)
@NoAuthorized
public void printPdf(Map<String, Object> parameters,
HttpServletResponse response,Long headId) throws IOException {
Service.printPdf(parameters,response,headId);
}```
headeId is the specific data displayed
service layer
//resultList is the data returned after querying the database. Because it involves the company database, the specific Sql will not be displayed. List<Map> resultList = new ArrayList<map>(); List<HashMap> list = new ArrayList<>(); List<Object> list2 = new ArrayList<>(); List<HashMap> list3= new ArrayList<>(); HashMap<String, Object> item2 = new HashMap<String, Object>(); parameters.put("ReplenishmentSub1", new ClassPathResource("jasper/Replenishment_sub1.jasper").getPath()); parameters.put("ReplenishmentSub2", new ClassPathResource("jasper/Replenishment_sub2.jasper").getPath()); for (Map map : resultList) { item2.put("CHANNEL_FROM",map.get("from")+""); item2.put("CHANNEL_TO",map.get("to")+""); item2.put("ADDRESS1_EN",map.get("address")+""); item2.put("ADDRESS2_EN",""); item2.put("ADDRESS3_EN",""); item2.put("NO_OF_PACKAGE", ""); List<Map> lines = The specific query data is the same as above and will not be displayed; for(int i=0;i<lines.size();i++){ HashMap<String, Object> item = new HashMap<String, Object>(); item.put("ITEM_CODE", lines.get(i).get("ITEM")+""); item.put("ITEM_DESC", lines.get(i).get("ITEMDESC")+""); item.put("ITEM_QTY", new BigDecimal(lines.get(i).get("QTY")+"")); list.add(item); list3.add(item); } } item2.put("sub1", list); item2.put("sub2", list3); list2.add(item2); try { JasperReportUtil.exportToPdf("jasper/test_main.jasper",parameters,list2,response); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }
The overall logic is to transfer $P to the template through the parameters attribute. The queried data needs to be loaded into a list transfer template. Each $F is a value in the Hashmap, and all the data of the sub template also needs to be loaded into a list. Therefore, there are three lists, two are the data of the sub template and one is the data of the parent template, The list of the child template has a hierarchical relationship with the data of the parent template, that is, list2 > item2 > (list = list3 = $F of the parent template) > item; Note: item is the data map of the child template, item2 is the data map of the parent template, list and list3 are the list set of the child template, and list2 is the list set of the parent template.
5. Test display:
That's it.
5. Summary
This article is summarized and written after my development, so some places may be omitted. If there are any problems, you can leave a message. In addition, I hope you can point out some mistakes.