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写代码
在处理最外层虚线点边框时,遇到了一些问题,然后把可能用到的整理如下:
- Graphics2D drawString 画 字符串
- Graphics2D setBackground(Color.WHITE) + clearRect(0, 0, 120, 60) --> 画背景图(大小充满整张图片)
- Graphics2D setStroke 设定画笔的粗细以及颜色,线条的特征,比如实线、虚线
- 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