[JAVA] I tried printing a form with Spring MVC and JasperReports 3/3 (Spring MVC control)

Previous article

https://amg-solution.jp/blog/3674 Reference page

I made a form like this

image.png

This is controlled on the Java side.

Check the entire flowchart

As I wrote at the time of creation, JasperReport outputs the form like this.

Load the form template ↓ Compile the template ← 1, Embed the data required for compilation! ↓ Embed data in the template ← 2. Create the necessary data here! ↓ Output as PDF file ← 3. Write Java compilation process!

The work to be done this time is numbered. Let's do it step by step.

Embed font file

Create a ** fonts ** folder in the resource folder of the form and copy ipaexg.ttf.

image.png

Next, write the font settings that JasperReport reads. Create the following xml in the ** fonts ** folder.

ipaexg.xml


<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
  <fontFamily name="IPAexg">
    <normal>fonts/ipaexg.ttf</normal>
    <pdfEncoding>Identity-H</pdfEncoding>
    <pdfEmbedded>true</pdfEmbedded>
  </fontFamily>
</fontFamilies>

It basically has the same meaning as set in JasperReport, so I don't think it needs explanation.

Finally, create an extension file called jasperreports_extension.properties directly under ** resource **. JasperReport will now compile IPA fonts.

jasperreports_extension.properties


net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.ipaex=fonts/ipaexg.xml

The pre-files needed for compilation are now ready.

Create data to be embedded in the form.

How to create data

Now that the template file has been created, create the data to be embedded. JasperReport is designed to read ** parameters in a map ** and ** fields in a list **. First, let's create a model to embed in the list.

Check the position of the form

First, check the location of the jrxml file.

image.png

Make sure it's under ** resource / report ** (well, anywhere under resource is fine)

Make a model

Let's make a model to put data. It's not a particularly difficult program. I am making a constructor so that I can easily enter data.

SampleProductModel.java


import lombok.Data;

@Data
public class SampleProductModel {

	private String Product_name;
	private int Price;
	
	public SampleProductModel(String name, int Price){
		this.Product_name = name;
		this.Price = Price;
	}
}

This is the abbreviation used with ** lombok **. If you have not installed the library, please add Getter and Setter.

Make Dao.

Since I made a model, I accessed it from the database. I want to have a body like that. Let's create a data access object. Let's put the display data in the method called find ().

SampleProductDao.java



import tsugaruinfo.entity.SampleProductModel;

public class SampleProductDao {

	public List<SampleProductModel> findByAll(){
		List<SampleProductModel> result = new ArrayList<>();
	
		SampleProductModel data1 = new SampleProductModel("Noribento",400);
		SampleProductModel data2 = new SampleProductModel("Makunouchi lunch",500);
		
		result.add(data1);
		result.add(data2);
		
		return result;
	
	}
}

This time, I got only two types of data, Nori-bento and Makunouchi-bento.

Make a Controller.

Then, prepare the address where you can download this PDF.

Let's make a controller

ProductController.java



@Controller
public class ProductController {

	@Autowired
	ResourceLoader resource;

	@RequestMapping(value = "/sample", method = RequestMethod.GET)
	public String sample() {
		
		return null;
	}

The controller settings are omitted. (If you have a controller that can be accessed from the local server properly) ResourceLoader is needed to load jrxml later. Let's get it ready now.

Now let's create the data. First from the parameters

ProductController.java


		//Data creation
		HashMap<String, Object> params = new HashMap<String, Object>();
		
		//Header data creation
		params.put("Client_name", "Yamamoto Securities");
		params.put("Date_today", "May 1, 2018");

Next, create the field data. You just created the mechanism to create it.

ProductController.java



		SampleProductDao dao = new SampleProductDao();
		
		List<SampleProductModel> fields = dao.findByAll();

Compile and output the form

This time I want to make it a download format, so I made this method.

ProductController.java


	/**
	 *Jasper report compilation. Return the binary file.
	 * @param data
	 * @param response
	 * @return
	 */
	private byte[] OrderReporting2(HashMap<String, Object> param, List<SampleProductModel> data) {
		InputStream input;
		try {
			//Get the form file
			input = new FileInputStream(resource.getResource("classpath:report/Blank_A4.jrxml").getFile());
			//List as data source for fields
			JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(data);
			//Compile the form
			JasperReport jasperReport = JasperCompileManager.compileReport(input);
			
			JasperPrint jasperPrint;
			//Inject parameter and field data
			jasperPrint = JasperFillManager.fillReport(jasperReport, param, dataSource);
			//Output form in Byte format
			return 	JasperExportManager.exportReportToPdf(jasperPrint);
			
		} catch (FileNotFoundException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (JRException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;

	}

In terms of points

  1. Must be done in the try {} section.
  2. PDF is returned in byte []. Is that the place to say?

This time I wanted to make it a download format, so I returned it as a byte, but if you change the method of ** JasperExportManager **, you can export it as a file as it is. try it!

Now, use this method to get the PDF form.

ProductController.java


		//Search data and output form
		byte[] output  = OrderReporting2(params, fields);

Download PDF

Now, let's distribute the spit out form as a download format.

ProductController.java


		response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + "sample.pdf");
        response.setContentLength(output.length);
		
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            os.write(output);
            os.flush();
            
            os.close();
        } catch (IOException e) {
            e.getStackTrace();

I will not explain the download in detail. See here.

I think the controller looks like this as a whole.

ProductController.java


@Controller
public class ProductController {

	@Autowired
	ResourceLoader resource;
	
	@RequestMapping(value = "/sample", method = RequestMethod.GET)
	public String sample( HttpServletResponse response) {
		
		/**▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ Data Creation Department ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ ▼**/
		//Header data creation
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put("Client_name", "Yamamoto Securities");
		params.put("Date_today", "May 1, 2018");
		
		//Field data creation
		SampleProductDao dao = new SampleProductDao();
		List<SampleProductModel> fields = dao.findByAll();
		
		/**▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ Data creation department ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲**/
		/**▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ Form output section ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ ▼▼▼▼▼**/
		//Search data and output form
		byte[] output  = OrderReporting2(params, fields);
		/**▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ Data creation department ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲**/
		
		/**▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ Data creation data download section ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼**/
		response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + "sample.pdf");
        response.setContentLength(output.length);
		
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            os.write(output);
            os.flush();
            
            os.close();
        } catch (IOException e) {
            e.getStackTrace();
        }
		/**▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ Data creation department ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲**/
        
        
		return null;
	}
	/**
	 *Jasper report compilation. Return the binary file.
	 * @param data
	 * @param response
	 * @return
	 */
	private byte[] OrderReporting2(HashMap<String, Object> param, List<SampleProductModel> data) {
		InputStream input;
		try {
			//Get the form file
			input = new FileInputStream(resource.getResource("classpath:report/Blank_A4.jrxml").getFile());
			//List as data source for fields
			JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(data);
			//Compile the form
			JasperReport jasperReport = JasperCompileManager.compileReport(input);
			
			JasperPrint jasperPrint;
			//Inject parameter and field data
			jasperPrint = JasperFillManager.fillReport(jasperReport, param, dataSource);
			//Output form in Byte format
			return 	JasperExportManager.exportReportToPdf(jasperPrint);
			
		} catch (FileNotFoundException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (JRException e) {
			//TODO auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;

	}
}

The main one is the ** sample ** method. OrderReporting2 is a subroutine. Of course, this time I divided the comments in an easy-to-understand manner, but it is also effective to divide the methods as a design.

Let's run

Let's run it

Start the server and access the corresponding address (/ sample).

image.png

The file has been downloaded properly. I will open it.

image.png

(Although it is a little off) You can see that the parameters are properly entered and the table is printed.

Since the forms belong to companies, I think that many of them are made on a commercial basis. It's free and can be used for commercial purposes, so why not use such a library?

Bonus extra edition

Recommended Posts

I tried printing a form with Spring MVC and JasperReports 3/3 (Spring MVC control)
I tried printing a form with Spring MVC and JasperReports 1/3 (JasperReports settings)
I tried printing a form with Spring MVC and JasperReports 2/3 (form template creation)
I tried printing a form with Spring MVC and JasperReports Extra edition (Variables edition)
I tried printing a form with Spring MVC and JasperReports Extra edition (image edition)
I tried to implement file upload with Spring MVC
I tried to create a shopping site administrator function / screen with Java and Spring
I tried GraphQL with Spring Boot
I tried Flyway with Spring Boot
I tried connecting to MySQL using JDBC Template with Spring MVC
I tried to create a Spring MVC development environment on Mac
I made a simple search form with Spring Boot + GitHub Search API.
I tried playing with BottomNavigationView a little ①
I tried Lazy Initialization with Spring Boot 2.2.0
I tried Spring.
Just input and output images with Spring MVC
I also tried WebAssembly with Nim and C
I tried to link JavaFX and Spring Framework.
I tried to break a block with java (1)
How to create an Excel form using a template file with Spring MVC
I tried to clone a web application full of bugs with Spring Boot
[I tried] Spring tutorial
I tried to read and output CSV with Outsystems
Spring Security usage memo: Cooperation with Spring MVC and Boot
I started MySQL 5.7 with docker-compose and tried to connect
[Ruby] I made a crawler with anemone and nokogiri.
I tried to get started with Spring Data JPA
I tried Spring Batch
I made a Restful server and client in Spring.
I tried OCR processing a PDF file with Java
I wrote a test with Spring Boot + JUnit 5 now
I tried to create a java8 development environment with Chocolatey
I tried to modernize a Java EE application with OpenShift.
[Rails] I tried to create a mini app with FullCalendar
Spring Boot Introductory Guide I tried [Accessing Data with JPA]
I tried to verify this and that of Spring @ Transactional
I want to make a list with kotlin and java!
I want to make a function with kotlin and java!
I tried JAX-RS and made a note of the procedure
I tried to create a padrino development environment with Docker
I tried OCR processing a PDF file with Java part2
I tried to get started with Swagger using Spring Boot
I made a simple MVC sample system using Spring Boot
Java Config with Spring MVC
I tried DI with Ruby
I tried Spring State machine
I tried UPSERT with PostgreSQL.
I tried BIND with Docker
I tried to express the result of before and after of Date class with a number line
I tried Spring Boot introductory guide [Building a RESTful Web Service]
I get a 404 error when testing forms authentication with Spring Security
I tried running a letter of credit transaction application with Corda 1
Create a parent-child relationship form with form_object (I also wrote a test)
I tried to make an Android application with MVC now (Java)
I tried deploying a Docker container on Lambda with Serverless Framework
Spring Boot Introductory Guide I tried [Consuming a RESTful Web Service]
I tried to make a group function (bulletin board) with Rails
I tried to make a machine learning application with Dash (+ Docker) part1 ~ Environment construction and operation check ~
I tried using Spring + Mybatis + DbUnit
I tried using JOOQ with Gradle
I tried morphological analysis with MeCab