Dynamic QR-Code Labels with Java and Spring Boot

Welcome to this tutorial on building a RESTful API using Spring Boot to generate QR code labels in Word documents. This guide provides detailed steps on setting up and implementing a Spring Boot application that generates QR codes and integrates them into Word documents. It covers everything from configuring the development environment to creating the API for QR code generation and incorporating it into Word documents for dynamic label creation. By following the tutorial, a fully functional solution for generating and inserting QR codes into Word documents will be achieved. Other barcode types such as UPC, EAN, GS1, PDF417, Data Matrix, and Code 128 may also be easily implemented using a similar process.


This tutorial illustrates the process of generating QR code labels with the Java Barcode Component QR Code jar and using a Spring Boot RESTful API application. It demonstrates how to create an API that accepts a POST request to dynamically generate QR codes and insert them as labels into Word documents. The guide covers setting up the Spring Boot application, handling data encoding, and generating the QR codes, ensuring a seamless integration into the document generation workflow.

Prerequisites

1. Create a New Spring Boot Project

  • Navigate to Spring Initializer
  • Choose Maven and Java
  • Select Spring Boot version 3.4.0
  • Set Java version to 17 (or 21)
  • Add the following dependencies: Spring Web and Spring Boot DevTools
  • Generate and download the project as a ZIP file

2. Open the Project in IntelliJ

  • Extract the ZIP file
  • Open the folder in IntelliJ IDEA
  • Load the Maven configuration by clicking on the Maven tab and refreshing dependencies

3. Test the Base Project

  • Run the project to ensure it starts successfully on port 8080 (or whichever port is configured). Modify the port if necessary. 

4. Configuring Dependencies

  • Update the pom.xml file with the following dependencies:
<!-- Apache POI Core for working with Word documents -->
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi</artifactId>
		<version>5.2.3</version>
	</dependency>
<!-- Apache POI OOXML for handling .docx files -->
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml</artifactId>
		<version>5.2.3</version>
	</dependency>
<!-- Apache POI OOXML Schemas (required for OOXML support)  -->
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml-schemas</artifactId>
		<version>4.1.2</version>
	</dependency>
<!-- XMLBeans dependency for POI -->
	<dependency>
		<groupId>org.apache.xmlbeans</groupId>
		<artifactId>xmlbeans</artifactId>
		<version>5.1.1</version>
	</dependency>
  • These dependencies allow or creating and interacting with Word documents.

5. Add the IDAutomation JAR File

  • Go to the File > Project Structure > Libraries
  • Click Add, locate the IDAutomation IDAQRCode.jar file and add it to the project

6. Create the Main Application Class

  • Ensure the proper import statements and Main Class configuration are correct.
  • The package and application name will depend on how it the project was set up but should be similar to the following code:
package com.idautomation.demo;

import org.apache.poi.util.Units;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import org.apache.poi.xwpf.usermodel.*;

import com.idautomation.qrcode.*;
import com.idautomation.qrcode.encoder.*;

import java.io.*;
import java.util.List;

@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}
}

  • This is the entry point for the Spring Boot application. The @SpringBootApplication annotation marks it as the main class.

7. Create the QR Code Controller Class

  • Insert the following code below the Main Application Class:
@RestController
@RequestMapping("/api/labels")
class QRCodeLabelController{

	@PostMapping(value= "/generate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
	public ResponseEntity<InputStreamResource> generateLabels(@RequestBody List<String> productIDs){
		try{
			XWPFDocument document = new XWPFDocument();
			try{
				XWPFTable table = document.createTable();
				table.removeRow(0);
				int columnsPerRow = 2;
				int currentColumn = 0;
				XWPFTableRow row = null;

				for (String productID : productIDs){
					if(productID != null & !productID.isEmpty()){

						String qrImageFile = productID + "-qr.jpeg";
						QRCode qr = new QRCode();
						qr.setDataToEncode(productID);
						new barCodeEncoder(qr,"JPEG", qrImageFile);

						if(currentColumn ==0){
							row =table.createRow();
						}

						XWPFTableCell cell = row.getCell(currentColumn);

						if(cell==null){
							cell = row.addNewTableCell();
						}

						XWPFParagraph cellParagraph = cell.addParagraph();
						XWPFRun textRun = cellParagraph.createRun();
						textRun.setText("Label for: " + productID);
						textRun.addBreak();

						try (FileInputStream imageStream = new FileInputStream(qrImageFile)){
							XWPFRun imageRun = cellParagraph.createRun();
							imageRun.addPicture(
									imageStream,
									XWPFDocument.PICTURE_TYPE_JPEG,
									qrImageFile,
									Units.toEMU(70),
									Units.toEMU(70)
							);
						}
						currentColumn++;
						if(currentColumn >= columnsPerRow){
							currentColumn= 0;
						}
					}
				}
				ByteArrayOutputStream outStream = new ByteArrayOutputStream();
				document.write(outStream);

				for(String productID : productIDs){
					new File(productID + "-qr.jpeg").delete();
				}

				ByteArrayInputStream inputStream = new ByteArrayInputStream(outStream.toByteArray());
				InputStreamResource resource = new InputStreamResource(inputStream);
				return ResponseEntity.ok()
						.header(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename=LabelsWithQR.docx")
						.contentType(MediaType.APPLICATION_OCTET_STREAM)
						.body(resource);
			} catch(Exception e){
				e.printStackTrace();
				return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
			} finally{
				try{
					document.close();
				}catch(IOException e){
					e.printStackTrace();
				}
			}
		}
		catch(Exception e){
			throw new RuntimeException(e);
		}
	}
  • @PostMapping("/generate"): Specifies that this method will handle POST requests made to /api/labels/generate
  • @RequestBody List<String> productIDs: The method expects a list of product IDs in the body of the POST request.
  • produces = MediaType.APPLICATION_OCTET_STREAM_VALUE: This tells the client that the response will be a binary stream (in this case, a Word document).
  • XWPFDocument is part of the Apache POI library used for manipulating Word documents. A new document is created here.
  • A table is created in the Word document. The first row is removed because it’s typically empty when a new table is created.
  • The document will have two columns per row for the QR code labels.
  • The loop iterates over the list of product IDs and checks if the ID is valid (not null or empty).
  • A QR code is generated for each product ID and saved as a JPEG image file.
  • If the current column is 0, a new row is created.
  • For each product, a new table cell is created or reused, and a label is added with the product ID as text.
  • The generated QR code image is read from the file system and inserted into the Word table cell.
  • The image is resized to 70x70 units using Apache POI’s Units.toEMU method, which handles the conversion of pixel sizes to the required EMU (English Metric Units) format.
  • After adding a label and its QR code to a cell, the current column counter is incremented.
  • If the column exceeds the specified number (2 in this case), it resets to 0, moving to the next row.
  • After all QR code labels are inserted, the document is written to an output stream (ByteArrayOutputStream).
  • The temporary QR code image files are deleted from the file system.
  • The Word document is returned as an attachment in the HTTP response, with the content type set to APPLICATION_OCTET_STREAM, allowing the client to download the file as LabelsWithQR.docx.
  • If any error occurs, an HTTP 500 Internal Server Error is returned.
  • The document is closed in a finally block to ensure resources are cleaned up.

8. Testing the API

  • Run the application in IntelliJ
  • Open Postman and set the request to POST
  • Type in the URL: "http://localhost:8080/api/labels/generate"
  • Add a header: Content-Type: application/json

An image of where to edit Postman to add the Content-Type and application/json within the Headers section.

  • In the body, add the raw data for a JSON array of product IDs
  • Example: ["Product-12345", "Product-67200", "Product-ABCDE","Product-234056","Product-867539","Product-199711"]
  • Send the request


A list of product IDs in raw JSON format within the Body of the Postman test

9. Download and Verify the Document

  • Save the response
  • Open the file in Word to see the QR Code labels

A highlight of where one would select to save the file from the Postman Post request test.

10. Adding the JAR as a Maven Dependency

Installing the JAR file locally ensures that Maven can access and use it during the build process, even if the JAR isn't available in a public Maven repository. This step is essential for incorporating custom or third-party libraries like the IDAutomation QR Code component into your project. Once installed, Maven treats the JAR as a local dependency, streamlining the development and deployment workflow.

  • Install the JAR locally with the following command in the terminal from within the project directory:

mvn install:install-file -Dfile="C:\Path\To\Jar\File\IDAQRCode.jar" -DgroupId="com.idautomation" -DartifactId=IDAQRCode -Dversion=1 -Dpackaging=jar

  • Include the dependency in the pom.xml file, within its' dependencies block:
<dependency>
	<groupId>com.idautomation</groupId>
	<artifactId>IDAQRCode</artifactId>
	<version>1</version>
	<scope>compile</scope>
</dependency>
  • Reload Maven, refresh Maven to complete the dependency setup
  • Test again!

By following these steps, a Spring Boot API has been created to dynamically generate QR code labels in a Word document. This application demonstrates the versatility of the IDAutomation Java Barcode Component and the integration of Apache POI with Spring Boot. This implementation highlights just a fraction of the potential for enhancing productivity in workflows.