最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java如何實(shí)現(xiàn)批量打印條形碼

 更新時(shí)間:2025年05月15日 09:01:52   作者:Katie。  
這篇文章主要為大家詳細(xì)介紹了如何基于?ZXing?庫(kù)生成條形碼位圖,并利用?Java?打印服務(wù)(PrinterJob)將它們以網(wǎng)格方式批量打印到?A4?標(biāo)簽紙或標(biāo)簽紙格式,需要的小伙伴可以參考一下

一、項(xiàng)目背景詳細(xì)介紹

在倉(cāng)儲(chǔ)管理、商品追溯、物流配送等場(chǎng)景中,條形碼(Barcode)作為物品唯一標(biāo)識(shí)被廣泛使用。為提高效率,經(jīng)常需要將一批數(shù)據(jù)轉(zhuǎn)為條形碼并打印在標(biāo)簽紙或 A4 頁(yè)面上,滿足打包掃描、入庫(kù)出庫(kù)等作業(yè)流程。

傳統(tǒng)做法可能依賴專有打標(biāo)簽軟件,靈活性差且難以集成到定制化系統(tǒng)。使用 Java 開(kāi)發(fā)一套 批量生成并打印條形碼 的工具,可以:

靈活集成:嵌入現(xiàn)有倉(cāng)儲(chǔ)或 ERP 系統(tǒng),直接從數(shù)據(jù)庫(kù)或 CSV 導(dǎo)入數(shù)據(jù);

定制標(biāo)簽:支持調(diào)整條形碼大小、分辨率、文字位置;

自動(dòng)化批量:一鍵批量生成、分頁(yè)排版、提交給打印機(jī);

零第三方依賴:僅需開(kāi)源庫(kù) ZXing 和 Java 自帶打印 API。

本項(xiàng)目將演示如何基于 ZXing 庫(kù)生成條形碼位圖,利用 Java 打印服務(wù)(PrinterJob)將它們以網(wǎng)格方式批量打印到 A4 標(biāo)簽紙或標(biāo)簽紙格式(如 3×10 布局)。

二、項(xiàng)目需求詳細(xì)介紹

2.1 功能需求

1.批量數(shù)據(jù)導(dǎo)入

支持從文本文件(CSV)、數(shù)據(jù)庫(kù)或內(nèi)存列表讀取多條待編碼內(nèi)容;

2.條形碼生成

  • 使用 ZXing 生成 Code128 或 EAN-13 條形碼;
  • 支持指定寬度、高度、邊距及是否顯示文本;

3.分頁(yè)排版

  • 在 A4 紙或標(biāo)簽紙上按指定行列(如 2 列×5 行)自動(dòng)排版;
  • 支持頁(yè)眉頁(yè)腳或批次號(hào)打?。?/li>

4.打印預(yù)覽(可選)

彈出打印對(duì)話框預(yù)覽分頁(yè)及打印機(jī)設(shè)置;

5.提交打印

通過(guò) PrinterJob 接口,支持選擇打印機(jī)及打印范圍;

6.錯(cuò)誤處理與日志

捕獲生成失敗、打印失敗,記錄日志并跳過(guò)繼續(xù);

2.2 非功能需求

易用性:一行命令或簡(jiǎn)單 GUI 即可完成;

配置化:頁(yè)面尺寸、行列數(shù)、條碼樣式通過(guò)配置文件管理;

跨平臺(tái):僅依賴 Java SE 與 ZXing,可在 Windows、Linux、macOS 上運(yùn)行;

可擴(kuò)展:后續(xù)可支持二維碼(QR Code)等多種格式;

三、相關(guān)技術(shù)詳細(xì)介紹

1.ZXing (com.google.zxing)

  • 主流開(kāi)源條碼/二維碼生成與解析庫(kù);
  • 支持多種碼制:Code128, EAN13, QR_CODE 等;

2.Java2D (java.awt.Graphics2D)

在 BufferedImage 上繪制條碼位圖;

3.PrinterJob (java.awt.print)

  • 標(biāo)準(zhǔn)打印 API:PrinterJob、PageFormat、Printable;
  • 支持頁(yè)面設(shè)置與打印對(duì)話框;

4.配置管理

使用 java.util.Properties 或 Spring @ConfigurationProperties 加載標(biāo)簽布局;

5.日志框架

SLF4J + Logback 記錄運(yùn)行狀態(tài);

四、實(shí)現(xiàn)思路詳細(xì)介紹

1.加載配置與數(shù)據(jù)

  • 從 config.properties 讀取:頁(yè)面寬度、高度、行數(shù)、列數(shù)、條形碼尺寸、邊距等;
  • 從 CSV 或數(shù)據(jù)庫(kù)加載待打印的編碼字符串列表;

2.生成條形碼圖像

  • 對(duì)每條內(nèi)容調(diào)用 ZXing 的 MultiFormatWriter.encode(),生成 BitMatrix;
  • 將 BitMatrix 轉(zhuǎn)換為 BufferedImage,并在底部添加文本標(biāo)簽(可選);

3.分頁(yè)排版

實(shí)現(xiàn) Printable 接口:

  • 在 print(Graphics g, PageFormat pf, int pageIndex) 中,根據(jù) pageIndex 計(jì)算當(dāng)前頁(yè)的數(shù)據(jù)子列表;
  • 對(duì)每行每列繪制對(duì)應(yīng)條碼圖像,使用 g.drawImage();
  • 如有文字批次號(hào)或條碼文本,使用 Graphics2D.drawString();
  • 返回 PAGE_EXISTS 或 NO_SUCH_PAGE;

4.打印提交

PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(printable, pageFormat); if(job.printDialog()) job.print();

5.日志與異常

條碼生成或打印異常時(shí),捕獲并記錄,跳過(guò)當(dāng)前碼或重試;

五、完整實(shí)現(xiàn)代碼

import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.print.*;
import java.io.*;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class BatchBarcodePrinter implements Printable {
    private static final Logger logger = LoggerFactory.getLogger(BatchBarcodePrinter.class);
 
    private List<String> codes;         // 待打印內(nèi)容
    private Properties config;          // 布局及條碼配置
    private List<BufferedImage> images; // 生成的條碼圖像列表
    private int cols, rows;             // 每頁(yè)列數(shù)和行數(shù)
    private int imgWidth, imgHeight;    // 條碼圖像尺寸
    private int marginX, marginY;       // 頁(yè)面邊距
    private int gapX, gapY;             // 圖像間隔
 
    public BatchBarcodePrinter(List<String> codes, Properties cfg) throws Exception {
        this.codes = codes;
        this.config = cfg;
        loadConfig();
        generateImages();
    }
 
    // 讀取配置
    private void loadConfig() {
        cols       = Integer.parseInt(config.getProperty("page.cols", "2"));
        rows       = Integer.parseInt(config.getProperty("page.rows", "5"));
        imgWidth   = Integer.parseInt(config.getProperty("barcode.width", "200"));
        imgHeight  = Integer.parseInt(config.getProperty("barcode.height", "80"));
        marginX    = Integer.parseInt(config.getProperty("page.marginX", "50"));
        marginY    = Integer.parseInt(config.getProperty("page.marginY", "50"));
        gapX       = Integer.parseInt(config.getProperty("page.gapX", "20"));
        gapY       = Integer.parseInt(config.getProperty("page.gapY", "30"));
    }
 
    // 生成所有條碼圖像
    private void generateImages() {
        images = new ArrayList<>();
        Code128Writer writer = new Code128Writer();
        for (String code : codes) {
            try {
                BitMatrix bm = writer.encode(code, BarcodeFormat.CODE_128, imgWidth, imgHeight);
                BufferedImage img = new BufferedImage(imgWidth, imgHeight + 20, BufferedImage.TYPE_INT_RGB);
                Graphics2D g = img.createGraphics();
                g.setColor(Color.WHITE);
                g.fillRect(0, 0, img.getWidth(), img.getHeight());
                // 繪制條碼
                for (int x = 0; x < imgWidth; x++) {
                    for (int y = 0; y < imgHeight; y++) {
                        g.setColor(bm.get(x, y) ? Color.BLACK : Color.WHITE);
                        g.fillRect(x, y, 1, 1);
                    }
                }
                // 繪制文本
                g.setColor(Color.BLACK);
                g.setFont(new Font("Monospaced", Font.PLAIN, 14));
                FontMetrics fm = g.getFontMetrics();
                int tx = (imgWidth - fm.stringWidth(code)) / 2;
                g.drawString(code, tx, imgHeight + fm.getAscent());
                g.dispose();
                images.add(img);
            } catch (Exception e) {
                logger.error("生成條碼失敗: {}", code, e);
            }
        }
    }
 
    @Override
    public int print(Graphics graphics, PageFormat pf, int pageIndex) {
        int perPage = cols * rows;
        int start = pageIndex * perPage;
        if (start >= images.size()) return NO_SUCH_PAGE;
        Graphics2D g = (Graphics2D) graphics;
        g.translate(pf.getImageableX(), pf.getImageableY());
        int x0 = marginX, y0 = marginY;
        // 繪制本頁(yè)條碼
        for (int i = 0; i < perPage; i++) {
            int idx = start + i;
            if (idx >= images.size()) break;
            int row = i / cols, col = i % cols;
            int x = x0 + col * (imgWidth + gapX);
            int y = y0 + row * (imgHeight + gapY + 20);
            g.drawImage(images.get(idx), x, y, null);
        }
        return PAGE_EXISTS;
    }
 
    // 啟動(dòng)打印
    public void printAll() throws PrinterException {
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPrintable(this);
        if (job.printDialog()) {
            job.print();
        }
    }
 
    public static void main(String[] args) throws Exception {
        // 1. 加載待打印數(shù)據(jù)
        List<String> codes = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader("codes.csv"))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (!line.trim().isEmpty()) codes.add(line.trim());
            }
        }
        // 2. 加載配置
        Properties cfg = new Properties();
        try (InputStream in = new FileInputStream("config.properties")) {
            cfg.load(in);
        }
        // 3. 批量打印
        BatchBarcodePrinter printer = new BatchBarcodePrinter(codes, cfg);
        printer.printAll();
    }
}

六、代碼詳細(xì)解讀

1.配置加載

從 config.properties 中讀?。簆age.cols, page.rows(每頁(yè)行列數(shù))、barcode.width, barcode.height(條碼圖像尺寸)、頁(yè)邊距與間隔等,便于靈活調(diào)整布局。

2.條碼生成

使用 ZXing 的 Code128Writer 生成 BitMatrix,逐像素渲染到 BufferedImage,并在下方繪制文本。

3.實(shí)現(xiàn) Printable

print(...) 根據(jù) pageIndex 計(jì)算本頁(yè)起始索引,并按行列遍歷繪制對(duì)應(yīng)條碼圖像,返回 PAGE_EXISTS 或 NO_SUCH_PAGE 控制分頁(yè)。

4.打印提交

PrinterJob 彈出打印對(duì)話框,用戶可選擇打印機(jī)與份數(shù),調(diào)用 print() 發(fā)起。

5.主方法流程

  • 從 codes.csv 讀取待打印條碼列表;
  • 從 config.properties 加載布局與尺寸;
  • 構(gòu)造 BatchBarcodePrinter 并調(diào)用 printAll()。

七、項(xiàng)目詳細(xì)總結(jié)

本項(xiàng)目展示了如何用 Java + ZXing + PrinterJob 實(shí)現(xiàn) 批量打印條形碼:

數(shù)據(jù)靈活:支持從文件或數(shù)據(jù)庫(kù)導(dǎo)入任意數(shù)量的編碼字符串;

配置驅(qū)動(dòng):行列數(shù)、圖像大小、頁(yè)邊距等通過(guò)外部配置調(diào)整;

圖形生成:ZXing 可靠生成高質(zhì)量 Code128 條碼,并可擴(kuò)展到 QR Code;

分頁(yè)打?。簶?biāo)準(zhǔn) Java 打印 API 自動(dòng)分頁(yè),兼容任意打印機(jī);

零商業(yè)依賴:僅用開(kāi)源組件即可完成企業(yè)級(jí)標(biāo)簽打印需求。

適合物流、倉(cāng)儲(chǔ)、制造業(yè)等需要批量生產(chǎn)標(biāo)簽的場(chǎng)景,也可作為 Java 圖形與打印 API 教學(xué)案例。

八、項(xiàng)目常見(jiàn)問(wèn)題及解答

Q1:條碼圖像模糊或尺寸不符?

A:確認(rèn) imgWidth/imgHeight 與實(shí)際打印機(jī) DPI 配合,必要時(shí)增加分辨率或調(diào)整頁(yè)面縮放。

Q2:打印出現(xiàn)空白頁(yè)?

A:檢查 print() 返回值邏輯,確保當(dāng) start >= images.size() 時(shí)返回 NO_SUCH_PAGE,否則會(huì)多打印空頁(yè)。

Q3:條碼下方文字不居中?

A:文本繪制使用 FontMetrics 計(jì)算字符串寬度,確保 x = (imgWidth - textWidth)/2。

Q4:需要打印二維碼?

A:將 Code128Writer 換為 QRCodeWriter,并設(shè)置 BitMatrix 尺寸,文本可放到旁邊或不顯示。

九、擴(kuò)展方向與性能優(yōu)化

大批量流式生成:對(duì)超萬(wàn)條數(shù)據(jù),分批生成圖像并實(shí)時(shí)打印,避免一次性占用大量?jī)?nèi)存;

自定義標(biāo)簽紙尺寸:支持常見(jiàn)標(biāo)簽紙(如 4×8 標(biāo)簽)模板配置,精確匹配打印機(jī)紙張;

并發(fā)打印:多線程調(diào)用不同 PrinterJob 實(shí)例同時(shí)發(fā)送到多臺(tái)打印機(jī);

網(wǎng)絡(luò)打印集成:支持通過(guò) IPP 協(xié)議或打印服務(wù)器推送打印作業(yè);

RTF/Word 導(dǎo)出:在 Word 文檔或 RTF 中嵌入條碼圖像,擴(kuò)展報(bào)表輸出;

GUI 預(yù)覽與編輯:用 Swing 或 JavaFX 提供可視化布局工具,讓用戶拖拽調(diào)整標(biāo)簽位置。

到此這篇關(guān)于Java如何實(shí)現(xiàn)批量打印條形碼的文章就介紹到這了,更多相關(guān)Java打印條形碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在Eclipse中運(yùn)行Solr 基礎(chǔ)知識(shí)

    在Eclipse中運(yùn)行Solr 基礎(chǔ)知識(shí)

    Solr我還是個(gè)菜鳥(niǎo),寫(xiě)這一些文章只是記錄一下最近一段時(shí)間學(xué)習(xí)Solr的心得,望各位同仁不要見(jiàn)笑,還希望多多指點(diǎn)
    2012-11-11
  • spring?jpa?審計(jì)功能自定義填充字段方式

    spring?jpa?審計(jì)功能自定義填充字段方式

    這篇文章主要介紹了spring?jpa審計(jì)功能自定義填充字段方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中注解@JsonFormat與@DateTimeFormat的使用

    Java中注解@JsonFormat與@DateTimeFormat的使用

    從數(shù)據(jù)庫(kù)獲取時(shí)間傳到前端進(jìn)行展示的時(shí)候,我們有時(shí)候可能無(wú)法得到一個(gè)滿意的時(shí)間格式的時(shí)間日期,本文主要介紹了Java中注解@JsonFormat與@DateTimeFormat的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Spring Boot WebSocket 兩種集成方式詳解

    Spring Boot WebSocket 兩種集成方式詳解

    WebSocket 是實(shí)現(xiàn)服務(wù)器主動(dòng)推送、實(shí)時(shí)通信的利器,常見(jiàn)于聊天室、消息通知、實(shí)時(shí)監(jiān)控大屏等場(chǎng)景,本文詳細(xì)介紹了SpringBoot集成WebSocket的兩種方式,感興趣的朋友跟隨小編一起看看吧
    2026-05-05
  • Springboot2.3.x整合Canal的示例代碼

    Springboot2.3.x整合Canal的示例代碼

    canal是阿里開(kāi)源mysql?binlog?數(shù)據(jù)組件,canal-server?才是canal的核心我們前邊所講的canal的功能,實(shí)際上講述的就是canal-server的功能,本文給大家介紹Springboot2.3.x整合Canal的示例代碼,需要的朋友可以參考下
    2022-02-02
  • Java中常用的設(shè)計(jì)模式之責(zé)任鏈模式詳解

    Java中常用的設(shè)計(jì)模式之責(zé)任鏈模式詳解

    這篇文章主要為大家詳細(xì)介紹了Java中常用的設(shè)計(jì)模式之責(zé)任鏈模式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • Java 深入探討設(shè)計(jì)模式之原型模式篇

    Java 深入探討設(shè)計(jì)模式之原型模式篇

    設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性
    2021-10-10
  • Java中id,pid格式數(shù)據(jù)轉(zhuǎn)樹(shù)和森林結(jié)構(gòu)工具類實(shí)現(xiàn)

    Java中id,pid格式數(shù)據(jù)轉(zhuǎn)樹(shù)和森林結(jié)構(gòu)工具類實(shí)現(xiàn)

    本文主要介紹了Java中id,pid格式數(shù)據(jù)轉(zhuǎn)樹(shù)和森林結(jié)構(gòu)工具類實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 深入理解Java高級(jí)特性——注解

    深入理解Java高級(jí)特性——注解

    這篇文章主要介紹了Java高級(jí)特性——注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java catch與throw同時(shí)使用的操作

    Java catch與throw同時(shí)使用的操作

    這篇文章主要介紹了Java catch與throw同時(shí)使用的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02

最新評(píng)論

郑州市| 荆州市| 龙里县| 灵宝市| 彝良县| 棋牌| 富锦市| 宝应县| 沐川县| 宝鸡市| 临汾市| 尚志市| 周宁县| 和政县| 哈巴河县| 新民市| 民和| 外汇| 江源县| 交口县| 陇川县| 德江县| 紫阳县| 宜川县| 遂平县| 托里县| 琼海市| 讷河市| 淳化县| 南岸区| 杨浦区| 罗定市| 且末县| 宜章县| 襄垣县| 合江县| 维西| 桂东县| 龙里县| 巴楚县| 乡宁县|