最新工作中遇到生成条形码的需求,经过一番摸索之后找到了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 + 12
int 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