当前位置: 首页 > news >正文

java 使用zxing生成条形码(可自定义文字位置、边框样式)

最新工作中遇到生成条形码的需求,经过一番摸索之后找到了zxing这个工具类,实现效果如下:

在这里插入图片描述

首先引入依赖:
<!--    条形码生成器    --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.0.0</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.0.0</version></dependency>
1234567891011AI写代码
工具类实现
public class GoogleBarCodeUtils {/*** 条形码宽度*/private static final int WIDTH = 440;/*** 条形码高度*/private static final int HEIGHT = 100;/*** 加文字 条形码*/private static final int WORDHEIGHT = 240;/*** 右上角文字*/private static final String RIGHT_UP_WORDS = "营销服务中心";/*** 条形码右下角第一段文字*/private static final String RIGHT_DOWN_FIRST_WORDS = "所属单位: xxxxx公司";private static final String RIGHT_DOWN_SECOND_WORDS = "生产厂家: xxxxxxxx有限公司";/*** 条形码左下角第一段文字*/private static final String LEFT_DOWN_FIRST_WORDS = "设备类型: xxxxxx";private static final String LEFT_DOWN_SECOND_WORDS = "准确度等级: xxxxx";/*** 设置 条形码参数*/private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>() {private static final long serialVersionUID = 1L;{// 设置编码方式put(EncodeHintType.CHARACTER_SET, "utf-8");//容错级别 这里选用最高级H级别put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);put(EncodeHintType.MARGIN, 0);}};/*** 生成 图片缓冲** @param vaNumber VA 码* @return 返回BufferedImage* @author myc*/public static BufferedImage getBarCode(String vaNumber) {try {Code128Writer writer = new Code128Writer();// 编码内容, 编码类型, 宽度, 高度, 设置参数BitMatrix bitMatrix = writer.encode(vaNumber, BarcodeFormat.CODE_128, WIDTH, HEIGHT, hints);return MatrixToImageWriter.toBufferedImage(bitMatrix);} catch (WriterException e) {e.printStackTrace();}return null;}/*** 把带logo的二维码下面加上文字** @param image   条形码图片* @param equipNo 设备编号* @return 返回BufferedImage* @author myc*/public static BufferedImage insertWords(BufferedImage image,String equipNo) {// 新的图片,把带logo的二维码下面加上文字if (StringUtils.isNotEmpty(equipNo)) {BufferedImage outImage = new BufferedImage(WIDTH, WORDHEIGHT, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = outImage.createGraphics();// 抗锯齿setGraphics2D(g2d);// 设置白色setColorWhite(g2d);//设置边框setDrawRect(g2d);// 设置虚线边框setDrawRectDottedLine(g2d);// 画条形码到新的面板g2d.drawImage(image, 10, 40, image.getWidth() - 20, image.getHeight(), null);// 画文字到新的面板Color color = new Color(0, 0, 0);g2d.setColor(color);// 字体、字型、字号g2d.setFont(new Font("微软雅黑", Font.PLAIN, 12));//文字长度String str = equipNo.replace("", "  ").trim();int strWidth = g2d.getFontMetrics().stringWidth(str);//总长度减去文字长度的一半  (居中显示)
//            int wordStartX=(WIDTH - strWidth) / 2;int wordStartX = (WIDTH - strWidth) / 2;//height + (outImage.getHeight() - height) / 2 + 12int wordStartY = HEIGHT + 20;//右上角文字长度int rightUpWordsWidth = WIDTH - g2d.getFontMetrics().stringWidth(RIGHT_UP_WORDS);//左上角文字长度String printDate = "打印日期 " + DateUtil.getCurrentTime("yyyy-MM-dd");int leftUpWordsWidth = WIDTH - g2d.getFontMetrics().stringWidth(printDate);//左下角第一 文字长度int leftDownFirstWordsWidth = WIDTH - 20 - g2d.getFontMetrics().stringWidth(LEFT_DOWN_FIRST_WORDS);// 画文字-上部分g2d.drawString(RIGHT_UP_WORDS, 20, 30);g2d.drawString(printDate, leftUpWordsWidth - 20, 30);//文字-下部分g2d.drawString(str, wordStartX, wordStartY + 38);g2d.drawString(RIGHT_DOWN_FIRST_WORDS, 20, wordStartY + 56);g2d.drawString(RIGHT_DOWN_SECOND_WORDS, 20, wordStartY + 76);g2d.drawString(LEFT_DOWN_FIRST_WORDS, leftDownFirstWordsWidth, wordStartY + 56);g2d.drawString(LEFT_DOWN_SECOND_WORDS, leftDownFirstWordsWidth, wordStartY + 76);g2d.dispose();outImage.flush();return outImage;}return null;}/*** 设置 Graphics2D 属性  (抗锯齿)** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setGraphics2D(Graphics2D g2d) {g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);g2d.setStroke(s);}/*** 设置背景为白色** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setColorWhite(Graphics2D g2d) {g2d.setColor(Color.WHITE);//填充整个屏幕g2d.fillRect(0, 0, 600, 600);//设置笔刷g2d.setColor(Color.BLACK);}/*** 设置边框** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setDrawRect(Graphics2D g2d) {//设置笔刷g2d.setColor(Color.DARK_GRAY);g2d.drawRect(5, 5, 425, 220);}/*** 设置边框虚线点** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setDrawRectDottedLine(Graphics2D g2d) {//设置笔刷g2d.setColor(Color.BLUE);BasicStroke stroke = new BasicStroke(0.5f, BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND, 0.5f, new float[]{1, 4}, 0.5f);g2d.setStroke(stroke);g2d.drawRect(0, 0, 435, 230);}
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182AI写代码
在处理最外层虚线点边框时,遇到了一些问题,然后把可能用到的整理如下:
  1. Graphics2D drawString 画 字符串
  2. Graphics2D setBackground(Color.WHITE) + clearRect(0, 0, 120, 60) --> 画背景图(大小充满整张图片)
  3. Graphics2D setStroke 设定画笔的粗细以及颜色,线条的特征,比如实线、虚线
  4. Graphics2D drawRect 画 矩形,以整张图片的大小为数据
设置虚线我们用到的是 setStroke 和 drawRect 方法函数,主要我们要了解stroke的设置,每个属性的含义:

BasicStroke(float width, int cap, int join, float miterlimit,float dash[], float dash_phase)

width: 线条的宽度;
cap:线条充满的幅度  CAP_BUTT, CAP_ROUND or CAP_SQUARE;
jion:线端交接的形状:比如圆角  JOIN_ROUND、三角  JOIN_MITER、平滑  JOIN_BEVEL ;
miterlimit: 配合JOIN_MITER使用,防止三角边的长度过长;
dash[]: 虚线的定义:“线+缺口+线+缺口+线+缺口… 比如: new float[] { 1, 4};
dash_phase 线条的偏移:与虚线有关,按照api定义,比如虚线 { 1, 4 }, 第一根线长 1,如何dash_phase为4,那么,整条虚线向后迁移;
123456AI写代码

main 方法测试:

public static void main(String[] args) throws IOException {BufferedImage image = insertWords(getBarCode("34101020100000112340"), "34101020100000112340");ImageIO.write(image, "jpg", new File("E:/barcode.png"));}
1234AI写代码

结果如图:
在这里插入图片描述

webController接口: 后端生成文件流传给前端处理

    @RequestMapping("/getBarCode")@ApiOperation(value = "生成条形码")public void getBarCode(@RequestParam("equipNo") Long equipId,HttpServletResponse response) throws IOException {// 设置响应流信息response.setContentType("image/jpg");response.setHeader("Pragma", "no-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);OutputStream stream = response.getOutputStream();BufferedImage image = GoogleBarCodeUtils.insertWords(            GoogleBarCodeUtils.getBarCode(String.valueOf(equipNo)),equipNo);        ImageIO.write(image, "jpg", stream);}
1234567891011AI写代码
前端Vue调用后端接口:
 // 点击打印条形码handlePrintOne(row) {log('row',row)this.barCodeRow = row;let equipNo = row.equipNo;axios.request({url: Global.BASE_API_URL + '/file/getBarCode',responseType: 'blob',method: 'post',params:{equipNo}}).then(res => {let blob = new Blob([res.data],{type: "image/png"});let url = window.URL.createObjectURL(blob);this.barCodeUrl=url;this.dialogImgVisible = true}), (error) => {this.$message({type: 'warning',message: '系统错误,请联系管理员!'});}},
12345678910111213141516171819202122AI写代码

效果如图:
在这里插入图片描述

点击下载按钮进行条形码的本地下载
handleDownload(){// 生成一个a元素let a = document.createElement("a");// 创建一个单击事件let event = new MouseEvent("click");// 设置图片名称a.download = this.barCodeRow.equipNo || "条形码";// 将生成的URL设置为a.href属性a.href = this.barCodeUrl;// 触发a的单击事件a.dispatchEvent(event);this.dialogImgVisible = false;},
12345678910111213AI写代码

在这里插入图片描述

到这里就是我对zxing生成条形码操作的简单理解和实现,欢迎随时进行交流和补充。

转至:https://blog.csdn.net/qq_40230848/article/details/121520931

相关文章:

  • Pageassist安装(ollama+deepseek-r1)
  • Fura Red AM,Cell Permeant钙离子探针使用说明
  • 消息队列与Kafka基础:从概念到集群部署
  • 顶层设计-IM系统架构
  • 57页PPT|数字化工艺系统建设方案工艺数字化转型传统工艺数字化转型解决方案
  • 深入浅出横向联邦学习、纵向联邦学习、联邦迁移学习
  • C# 面向对象 构造函数带参无参细节解析
  • 【软件推荐——pdf2docx】
  • 解决将其他盘可用空间,移植到C盘
  • 10G 集成 4 口网口连接器的核心优势
  • 构建稳定的金字塔模式生态:从自然法则到系统工程
  • 【mysql】并发 Insert 的死锁问题 第二弹
  • 2025第三届盘古初赛(计算机部分)
  • 信息安全基础知识
  • Houdini POP入门学习01
  • 什么是实景VR?实景VR应用场景
  • Ai Agent革命:不是流程驱动,而是模型为魂
  • 【LeetCode 热题 100】搜索插入位置 / 搜索旋转排序数组 / 寻找旋转排序数组中的最小值
  • Redis数据结构详解:应用场景与使用指南
  • AUTOSAR图解==>AUTOSAR_SWS_ICUDriver_AUTOSAR_SWS_ICUDriver
  • 新版城市规划体检评估解读:把城市安全韧性摆在更加突出位置
  • 马上评|中学生被操场地面烫伤,谁的“大课间”?
  • 六连板成飞集成:航空零部件业务收入占比为1.74%,市场环境没有重大调整
  • 泽连斯基:正在等待俄方确认参加会谈的代表团组成
  • 国际能源署:全球电动汽车市场强劲增长,中国市场继续领跑
  • 《蛮好的人生》:为啥人人都爱这个不完美的“大女主”