SoFunction
Updated on 2025-05-15

How to implement batch printing of barcodes in Java

1. Detailed introduction to the project background

In scenarios such as warehousing management, product traceability, logistics and distribution, barcode (Barcode) is widely used as the unique identifier of the item. To improve efficiency, it is often necessary to convert a batch of data into barcodes and print them on label paper or A4 pages to meet the operation processes such as packaging and scanning, in-store and out-of-store operations.

Traditional practices may rely on proprietary tagging software, which is poorly flexible and difficult to integrate into customized systems. Using Java to develop a set of tools to batch generate and print barcodes, you can:

Flexible integration: Embed existing warehouse or ERP system to import data directly from the database or CSV;

Customized tags: Supports adjustment of barcode size, resolution, and text position;

Automated batch: one-click batch generation, paging and typography, and submitting to the printer;

Zero third-party dependencies: only open source libraries ZXing and Java come with printing API.

This project will demonstrate how to generate barcode bitmaps based on the ZXing library and use the Java Print Service (PrinterJob) to batch print them in grid-based formats to A4 label paper or label paper formats (such as 3×10 layouts).

2. Detailed introduction to project requirements

2.1 Functional Requirements

1. Batch data import

Supports reading multiple pieces of content to be encoded from text files (CSVs), databases, or memory lists;

2. Barcode generation

  • Use ZXing to generate Code128 or EAN-13 barcodes;
  • Supports specifying width, height, margin and whether to display text;

3. Pagination and layout

  • Automatically type on A4 paper or label paper in specified rows (such as 2 columns × 5 rows);
  • Supports header footer or batch number printing;

4. Print preview (optional)

The print dialog box pops up to preview the page and printer settings;

5. Submit Print

Through the PrinterJob interface, it supports selection of printer and printing range;

6. Error handling and logging

Capture generation failure, printing failure, log log and skip to continue;

2.2 Non-functional requirements

Ease of use: one line of command or simple GUI can be completed;

Configuration: Page size, number of rows, and barcode style are managed through configuration files;

Cross-platform: Relying on Java SE and ZXing only, it can run on Windows, Linux, and macOS;

Extensible: it can support QR Code and other formats in the future;

3. Detailed introduction to related technologies

()

  • Mainstream open source barcode/QR code generation and analysis library;
  • Supports multiple code systems: Code128, EAN13, QR_CODE, etc.;

2.Java2D (.Graphics2D)

Draw a barcode bitmap on a BufferedImage;

()

  • Standard printing API: PrinterJob, PageFormat, Printable;
  • Support page settings and printing dialog boxes;

4. Configuration Management

Load the tag layout using or Spring @ConfigurationProperties;

5. Log Framework

SLF4J + Logback record the running status;

4. Detailed introduction to the implementation ideas

1. Load configuration and data

  • Read from: page width, height, number of rows, columns, barcode size, margins, etc.;
  • Load the list of encoded strings to be printed from a CSV or database;

2. Generate barcode images

  • Call ZXing's () for each content to generate BitMatrix;
  • Convert BitMatrix to BufferedImage and add text tags at the bottom (optional);

3. Pagination and layout

Implement Printable interface:

  • In print(Graphics g, PageFormat pf, int pageIndex), calculate the data sublist of the current page according to pageIndex;
  • Draw the corresponding barcode image for each row and column, using ();
  • If there is a text batch number or barcode text, use ();
  • Returns PAGE_EXISTS or NO_SUCH_PAGE;

4. Print Submit

PrinterJob job = (); (printable, pageFormat); if(()) ();

5. Logs and exceptions

When a barcode generates or prints an exception, captures and records, skips the current code or tries again;

5. Complete implementation of the code

import .*;
import ;
import .Code128Writer;
import ;
import .*;
import ;
import .*;
import .*;
import .*;
import org.;
import org.;
 
public class BatchBarcodePrinter implements Printable {
    private static final Logger logger = ();
 
    private List<String> codes;         // Content to be printed    private Properties config;          // Layout and barcode configuration    private List<BufferedImage> images; // Generated barcode image list    private int cols, rows;             // Number of columns and rows per page    private int imgWidth, imgHeight;    // Barcode image size    private int marginX, marginY;       // Page margin    private int gapX, gapY;             // Image interval 
    public BatchBarcodePrinter(List<String> codes, Properties cfg) throws Exception {
         = codes;
         = cfg;
        loadConfig();
        generateImages();
    }
 
    // Read configuration    private void loadConfig() {
        cols       = (("", "2"));
        rows       = (("", "5"));
        imgWidth   = (("", "200"));
        imgHeight  = (("", "80"));
        marginX    = (("", "50"));
        marginY    = (("", "50"));
        gapX       = (("", "20"));
        gapY       = (("", "30"));
    }
 
    // Generate all barcode images    private void generateImages() {
        images = new ArrayList<>();
        Code128Writer writer = new Code128Writer();
        for (String code : codes) {
            try {
                BitMatrix bm = (code, BarcodeFormat.CODE_128, imgWidth, imgHeight);
                BufferedImage img = new BufferedImage(imgWidth, imgHeight + 20, BufferedImage.TYPE_INT_RGB);
                Graphics2D g = ();
                ();
                (0, 0, (), ());
                // Draw barcode                for (int x = 0; x < imgWidth; x++) {
                    for (int y = 0; y < imgHeight; y++) {
                        ((x, y) ?  : );
                        (x, y, 1, 1);
                    }
                }
                // Draw text                ();
                (new Font("Monospaced", , 14));
                FontMetrics fm = ();
                int tx = (imgWidth - (code)) / 2;
                (code, tx, imgHeight + ());
                ();
                (img);
            } catch (Exception e) {
                ("Failed to generate barcode: {}", code, e);
            }
        }
    }
 
    @Override
    public int print(Graphics graphics, PageFormat pf, int pageIndex) {
        int perPage = cols * rows;
        int start = pageIndex * perPage;
        if (start >= ()) return NO_SUCH_PAGE;
        Graphics2D g = (Graphics2D) graphics;
        ((), ());
        int x0 = marginX, y0 = marginY;
        // Draw the barcode on this page        for (int i = 0; i < perPage; i++) {
            int idx = start + i;
            if (idx >= ()) break;
            int row = i / cols, col = i % cols;
            int x = x0 + col * (imgWidth + gapX);
            int y = y0 + row * (imgHeight + gapY + 20);
            ((idx), x, y, null);
        }
        return PAGE_EXISTS;
    }
 
    // Start printing    public void printAll() throws PrinterException {
        PrinterJob job = ();
        (this);
        if (()) {
            ();
        }
    }
 
    public static void main(String[] args) throws Exception {
        // 1. Load the data to be printed        List<String> codes = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader(""))) {
            String line;
            while ((line = ()) != null) {
                if (!().isEmpty()) (());
            }
        }
        // 2. Load configuration        Properties cfg = new Properties();
        try (InputStream in = new FileInputStream("")) {
            (in);
        }
        // 3. Batch printing        BatchBarcodePrinter printer = new BatchBarcodePrinter(codes, cfg);
        ();
    }
}

6. Detailed interpretation of the code

1.Configuration loading

Read from:, (number of rows and columns per page), (barcode image size), page margins and intervals, etc., to facilitate flexible layout adjustment.

2. Barcode generation

Use ZXing's Code128Writer to generate BitMatrix, render pixel by pixel to BufferedImage, and draw text below.

3. Implement Printable

print(...) Calculate the starting index of this page according to pageIndex, and draw the corresponding barcode image according to row and column traversal, returning to the PAGE_EXISTS or NO_SUCH_PAGE control page.

4. Print Submit

PrinterJob pops up the print dialog box, the user can select the printer and the number of copies and call print() to initiate it.

5. Main method process

  • Read the list of barcodes to be printed from;
  • Loading layout and dimensions from
  • Construct BatchBarcodePrinter and call printAll().

7. Detailed project summary

This project shows how to implement batch printing of barcodes using Java + ZXing + PrinterJob:

Data flexibility: supports importing any number of encoded strings from files or databases;

Configuration driver: the number of rows, image size, page margins, etc. are adjusted through external configuration;

Graphic Generation: ZXing reliably generates high-quality Code128 barcodes and can be expanded to QR Code;

Pagination printing: Standard Java printing API automatically paginates, compatible with any printer;

Zero business dependency: Only open source components can complete enterprise-level label printing requirements.

Suitable for scenarios such as logistics, warehousing, manufacturing, etc. that require mass production labels, it can also be used as a teaching case for Java graphics and printing API.

8. Project FAQs and answers

Q1: Is the barcode image blurry or the size does not match?

A: Confirm that imgWidth/imgHeight cooperates with the actual printer DPI, increase the resolution or adjust the page zoom if necessary.

Q2: Blank page appears when printing?

A: Check the print() return value logic to ensure that NO_SUCH_PAGE is returned when start >= (), otherwise more empty pages will be printed.

Q3: The text below the barcode is not centered?

A: Text drawing uses FontMetrics to calculate the string width, ensuring x = (imgWidth - textWidth)/2.

Q4: Do you need to print a QR code?

A: Change Code128Writer to QRCodeWriter and set the BitMatrix size, and the text can be placed next to it or not displayed.

9. Expansion direction and performance optimization

Large-scale streaming generation: For more than 10,000 pieces of data, images are generated in batches and printed in real time to avoid consuming a large amount of memory at one time;

Custom label paper size: Supports template configuration of common label paper (such as 4×8 labels) to accurately match printer paper;

Concurrent printing: Multi-threaded calls to different PrinterJob instances are sent to multiple printers at the same time;

Network printing integration: supports pushing print jobs through IPP protocol or print server;

RTF/Word export: embed barcode images in Word documents or RTF to extend report output;

GUI preview and editing: Use Swing or JavaFX to provide visual layout tools, allowing users to drag and drop to adjust the label position.

This is the end of this article about how Java can print barcodes in batches. For more related content on Java printing barcodes, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!