记录一次java生成条形码并调用打印机打印

生成条形码需要ja坐标:

        <!--生成条形码-->
        <dependency>
            <groupId>net.sf.barcode4j</groupId>
            <artifactId>barcode4j-light</artifactId>
            <version>2.0</version>
        </dependency>

调用打印机java使用自身带有的print就可以做到

我们先生成条形码:generateFile方法传入需要条形码包含的信息和生成的路径就可以

package com.hongseng.app.config.barcode;

import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;

import java.awt.image.BufferedImage;
import java.io.*;

/**
 *
 * @program: fire
 * @description:
 * @author: fbl
 * @create: 2021-08-11 10:24
 **/
public class BarcodeUtil {
    /**
     * 生成文件s
     *
     * @param msg
     * @param path
     * @return
     */
    public static File generateFile(String msg, String path) {
        File file = new File(path);
        try {
            generate(msg, new FileOutputStream(file));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
        return file;
    }

    /**
     * 生成字节
     *
     * @param msg
     * @return
     */
    public static byte[] generate(String msg) {
        ByteArrayOutputStream ous = new ByteArrayOutputStream();
        generate(msg, ous);
        return ous.toByteArray();
    }

    /**
     * 生成到流
     *
     * @param msg
     * @param ous
     */
    public static void generate(String msg, OutputStream ous) {
        if (msg == null || msg.equals("") || ous == null) {
            return;
        }
        Code39Bean bean = new Code39Bean();
        // 精细度
        final int dpi = 150;
        // module宽度
        final double moduleWidth = UnitConv.in2mm(1.0f / dpi);

        // 配置对象
        bean.setModuleWidth(moduleWidth);
        bean.setWideFactor(3);
        bean.doQuietZone(false);

        String format = "image/png";
        try {
            // 输出到流
            BitmapCanvasProvider canvas = new BitmapCanvasProvider(ous, format, dpi,
                    BufferedImage.TYPE_BYTE_BINARY, false, 0);
            // 生成条形码
            bean.generateBarcode(canvas, msg);
            // 结束绘制
            canvas.finish();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

在指定路径生产条形码之后,将路径作为参数调用接口打印

第一个参数是路径,其余四个参数是纸张和图片的尺寸

package com.hongseng.app.config.barcode;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.print.*;
import java.io.IOException;
import java.net.URL;

import static java.awt.print.Printable.PAGE_EXISTS;

/**
 * @program: fire
 * @description:
 * @author: fbl
 * @create: 2021-08-11 10:03
 **/
public  class PrintDemo {
    public static void qrCodePrint(String path, int pageWidth, int pageHeight, int showWidth, int showHeight) {
        // 通俗理解就是书、文档
        Book book = new Book();
        // 设置成竖打
        PageFormat pf = new PageFormat();
        pf.setOrientation(PageFormat.PORTRAIT);
        // 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
        Paper p = new Paper();
        //纸张大小
        p.setSize(pageWidth, pageHeight);
        p.setImageableArea(0, 0, pageWidth, pageHeight);
        pf.setPaper(p);
        // 把 PageFormat 和 Printable 添加到书中,组成一个页面
        book.append((graphics, pageFormat, pageIndex) -> {
            try {
                URL url = new URL(path);//也可以通过file构建一个本地图片File对象传递给ImageIO.read()方法
                Image image = ImageIO.read(url);
                //将图片绘制到graphics对象中(为什么把需要打印的内容drawImage就可以实现打印自己取看值传递一引用传递的区别)
                graphics.drawImage(image, 0, 0, showWidth, showHeight, null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return PAGE_EXISTS;//返回0(PAGE_EXISTS)则执行打印,返回1(NO_SUCH_PAGE)则不执行打印
        }, pf);
        // 获取打印服务对象
        PrinterJob job = PrinterJob.getPrinterJob();
        // 设置打印类
        job.setPageable(book);
        try {
            //可以用printDialog显示打印对话框,在用户确认后打印;也可以直接打印
            job.print();
        } catch (PrinterException e) {
            e.printStackTrace();
        }
    }
}

我的service层将两个工具类协同调用

package com.hongseng.app.service.barcode;

import com.hongseng.app.config.barcode.BarcodeUtil;
import com.hongseng.app.config.barcode.PrintDemo;
import model.dto.barcode.BarCodeDto;
import model.dto.barcode.PicturePrintDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import result.Result;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.UUID;

/**
 * @program: fire_control
 * @description:
 * @author: fbl
 * @create: 2021-04-01 09:55
 **/
@Service
public class BarCodeService {

    @Value("${spring.servlet.multipart.location}")
    private String picturePath;

    @Value("${server.port}")
    private String port;

    public void prodCode(BarCodeDto barCodeDto) {
        String codeName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
        String path = picturePath + codeName;
        // 生成条形码图片
        BarcodeUtil.generateFile(barCodeDto.getId() + "", path);

        InetAddress localHost = null;
        try {
            localHost = Inet4Address.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String ip = localHost.getHostAddress();
        // 上传图片
        String finalPath =  "http://" + ip + ":" + port + "/file/" + codeName;

        // 打印图片
        // 打印
        PrintDemo.qrCodePrint(finalPath, barCodeDto.getPageWidth(), barCodeDto.getPageHeight(), barCodeDto.getShowWidth(), barCodeDto.getShowHeight());
    }
 
}


BarCodeDto 类参数:

package model.dto.barcode;

import lombok.Data;

import javax.validation.constraints.NotNull;

/**
 * @program: temperature-statistics
 * @description:
 * @author: fbl
 * @create: 2021-08-12 08:19
 **/
@Data
public class BarCodeDto {
    @NotNull
    private Integer id;

    @NotNull
    private Integer pageWidth;

    @NotNull
    private Integer pageHeight;

    @NotNull
    private Integer showWidth;

    @NotNull
    private Integer showHeight;
}

controller层调用就不写了

### Java 远程调用打印机打印条形码 为了实现Java程序远程调用打印机进行条形码打印,可以采用多种方式。以下是基于POS命令、TSCLIB以及JAVA类库的具体方案。 #### 使用POS命令方式进行条形码打印 POS命令是一种常见的用于控制热敏打印机的方法。这种方式适用于支持ESC/POS指令集的打印机设备。通过发送特定的二进制序列给打印机来完成各种操作,包括打印条形码。 ```java import java.io.OutputStream; import gnu.io.CommPortIdentifier; import gnu.io.SerialPort; import gnu.io.SerialPortEvent; import gnu.io.SerialPortEventListener; import java.util.Enumeration; public class PosPrinter { public static void main(String[] args) throws Exception { String portName = "COM1"; // 替换成实际串口号 CommPortIdentifier portId = null; Enumeration portEnum = CommPortIdentifier.getPortIdentifiers(); while (portEnum.hasMoreElements()) { CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement(); if (currPortId.getName().equals(portName)) { portId = currPortId; break; } } if (portId == null) { System.out.println("Could not find COM port."); return; } SerialPort serialPort = (SerialPort) portId.open(PosPrinter.class.getName(), 2000); OutputStream out = serialPort.getOutputStream(); byte[] barcodeCommand = {0x1D, 0x6B, 0x49, 0x18}; // 设置条形码宽度为7像素高,长度为24字符宽 out.write(barcodeCommand); byte[] dataToSend = "12345678".getBytes(); // 要打印的数据 out.write(dataToSend); byte[] printAndFeedLines = new byte[]{0x0A}; out.write(printAndFeedLines); out.flush(); Thread.sleep(200L); serialPort.close(); } } ``` 此代码片段展示了如何利用POS命令向指定端口发送条形码打印请求[^1]。 #### 利用TSCLIB库实现条形码打印 对于某些型号的TSC品牌打印机来说,可以直接使用其官方提供的TSCLIB库来进行更复杂的打印任务设置。这通常涉及到加载动态链接库(DLL),通过JNI接口与之交互。 ```java // 加载本地DLL文件 System.loadLibrary("tscdll"); // 初始化打印机对象配置参数 TSC Printer printer = TSC.Printer.getInstance(); printer.connect("localhost", 9100); // IP地址和端口号需根据实际情况调整 printer.setup(80, "", ""); // 宽度单位毫米;速度留空默认最快;浓度留空自动适配最佳值 // 开始文档定义区域 printer.sendCommand("SIZE 80 mm"); printer.sendCommand("GAP 2 mm"); printer.sendCommand("REFERENCE 0 0"); printer.sendCommand("CLS"); // 添加条形码元素至页面布局中 String barcodeData = "HELLO WORLD"; printer.printBarcode(50, 50, 128, 100, 'N', barcodeData.toCharArray()); // 结束当前作业将内容提交给硬件执行 printer.formfeed(); printer.disconnect(); ``` 上述例子说明了怎样借助于第三方工具包简化开发流程的同时也提高了灵活性[^3]。 #### 应用Javax Print API进行网络打印 如果目标打印机位于局域网内,则还可以考虑运用标准API——`javax.print`服务提供商接口(SPIs)来构建应用程序逻辑部分。这种方法的优势在于它不需要额外安装任何驱动程序或依赖项,且兼容大多数现代操作系统平台上的绝大多数类型的打印机产品线。 ```java import javax.print.*; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.standard.MediaSizeName; import javax.print.attribute.standard.OrientationRequested; import javax.print.attribute.standard.Sides; import java.awt.print.PageFormat; import java.awt.print.Paper; import java.awt.print.Printable; import java.awt.print.PrinterException; import java.awt.Graphics; import java.awt.Font; import java.awt.image.BufferedImage; import com.google.zxing.BarcodeFormat; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.qrcode.QRCodeWriter; class BarcodePage implements Printable { private final BitMatrix matrix; public BarcodePage(BitMatrix m){ this.matrix=m; } @Override public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { if(pageIndex>0){return NO_SUCH_PAGE;} Graphics2D g2d=(Graphics2D)graphics; Paper paper=new Paper(); double margin=10; paper.setImageableArea(margin,margin,paper.getWidth()-2*margin, paper.getHeight()-2*margin); pageFormat.setPaper(paper); try{ BufferedImage image= MatrixToImageWriter.toBufferedImage(matrix); g2d.drawImage(image,(int)(pageFormat.getImageableX()), (int)(pageFormat.getImageableY()),null); }catch(Exception e){} return PAGE_EXISTS; } } public class RemotePrintingExample { public static void main(String []args)throws WriterException, InterruptedException{ DocFlavor flavor=DocFlavor.BYTE_ARRAY.AUTOSENSE; PrintService service=PrintServiceLookup.lookupDefaultPrintService(); DocPrintJob job=service.createPrintJob(); HashPrintRequestAttributeSet attributeset= new HashPrintRequestAttributeSet(); attributeset.add(new MediaSizeName(MediaSize.ISO.A4)); attributeset.add(OrientationRequested.PORTRAIT); attributeset.add(Sides.ONE_SIDED); QRCodeWriter writer =new QRCodeWriter (); BitMatrix bitMatrix=writer.encode ("https://example.com/", BarcodeFormat.CODE_128 ,400,400); Doc doc=new SimpleDoc((new BarcodePage(bitMatrix)).print(null,null,-1),flavor,null); job.print(doc,attributeset); } } ``` 这段源码示范了创建自定义可打印组件的过程,该组件负责渲染ZXing生成的位图形式的条形码图像到纸张上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值