- 1、引入生成二维码的jar包依赖
- 2、创建生成二维码工具类
- 3、导出二维码流前端进行下载
- 4、批量下载二维码并放入zip压缩包里面
- 5、前端下载
2、创建生成二维码工具类com.google.zxing core3.4.1
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class QrCodeUtil {
//0x,透明度,R,G,B
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
public BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
public void writeToFile(BufferedImage image, String format, String filePath) throws IOException {
File outputFile = new File(filePath);
if (!outputFile.exists()) {
outputFile.mkdirs();
}
if (!ImageIO.write(image, format, outputFile)) {
throw new IOException("不能转换成" + format );
}
}
public BufferedImage addBgImg(BufferedImage image, String bgFilePath, int x, int y) throws Exception {
File file = new File(bgFilePath);
if (!file.exists()) {
throw new IOException("背景图片不存在");
}
BufferedImage bgImg = ImageIO.read(file);
if(x < 0) {
x = 0;
}
if(y < 0) {
y = 0;
}
if(bgImg.getWidth() < image.getWidth() || bgImg.getHeight()
throw new Exception("背景图片小于二维码尺寸");
}
if(bgImg.getWidth() < x + image.getWidth() || bgImg.getHeight() < y + image.getHeight()) {
throw new Exception("以背景的("+x+","+y+")作为二维码左上角不能容下整个二维码");
}
Graphics2D graph = bgImg.createGraphics();
graph.drawImage(image, x, y, image.getWidth(), image.getHeight(), null);
graph.dispose();
return bgImg;
}
public BufferedImage addText(BufferedImage image, String text, int fontSize) {
int outImageWidth = image.getWidth();
int outImageHeight = image.getHeight() + fontSize + 10;
BufferedImage outImage = new BufferedImage(outImageWidth, outImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graph = outImage.createGraphics();
//填充为白色背景
graph.setColor(Color.white);
graph.fillRect(0 ,0 , outImageWidth, outImageHeight);
//将二维码画入
graph.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
//添加文本
graph.setColor(Color.black);
Font font = new Font("楷体", Font.BOLD, fontSize);//字体,字型,字号
graph.setFont(font);
//文本水平,垂直居中
FontRenderContext frc =
new FontRenderContext(null, true, true);
Rectangle2D r2D = font.getStringBounds(text, frc);
int rWidth = (int) Math.round(r2D.getWidth());
int a = (outImageWidth - rWidth) / 2;
graph.drawString(text,a, outImageHeight - 5);//x,y为左下角坐标
graph.dispose();
return outImage;
}
public BufferedImage encodeQrCode(String text, int width, int height) throws WriterException, IOException {
//设置二维码配置
Hashtable hints = new Hashtable();
// 设置QR二维码的纠错级别,指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, 0);// 白边
//创建比特矩阵(位矩阵)的QR码编码的字符串
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
//二维码图片生成
BufferedImage qrCodeImg = toBufferedImage(bitMatrix);
return qrCodeImg;
}
// 生成白色背景图
public BufferedImage pureColorPictures(int width, int height) {
//width 生成图宽度
// height 生成图高度
//创建一个width xheight ,RGB高彩图,类型可自定
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//取得图形
Graphics g = img.getGraphics();
//设置背景图颜色
g.setColor(Color.WHITE);
//填充
g.fillRect(0, 0, img.getWidth(), img.getHeight());
return img;
}
// 把二维码和背景图合在一起
public BufferedImage pureColorPicturesAddBgImg(BufferedImage image, BufferedImage pureColorPictures, int x, int y) throws Exception {
BufferedImage bgImg = pureColorPictures;
if(x < 0) {
x = 0;
}
if(y < 0) {
y = 0;
}
if(bgImg.getWidth() < image.getWidth() || bgImg.getHeight()
throw new Exception("背景图片小于二维码尺寸");
}
if(bgImg.getWidth() < x + image.getWidth() || bgImg.getHeight() < y + image.getHeight()) {
throw new Exception("以背景的("+x+","+y+")作为二维码左上角不能容下整个二维码");
}
Graphics2D graph = bgImg.createGraphics();
graph.drawImage(image, x, y, image.getWidth(), image.getHeight(), null);
graph.dispose();
return bgImg;
}
// 二维码在背景图片的位置
// 1左上,2左中,3在下
// 4中上,5正中,6中下
// 7右上,8右中,9右下
public Map calculateXY(BufferedImage bj, BufferedImage code, String type){
int bx = bj.getWidth();
int by = bj.getHeight();
int cx = code.getWidth();
int cy = code.getHeight();
int x = 0;
int y = 0;
if("2".equals(type)){
y = (by - cy) / 2;
}else if("3".equals(type)){
y = by - (by - cy);
}else if("4".equals(type)){
x = (bx - cx) / 2;
}else if("5".equals(type)){
x = (bx - cx) / 2;
y = (by - cy) / 2;
}else if("6".equals(type)){
x = bx - (bx - cx);
y = by - (by - cy);
}else if("7".equals(type)){
x = bx - cx;
}else if("8".equals(type)){
x = bx - cx;
y = (by - cy) / 2;
}else if("9".equals(type)){
x = bx - cx;
y = by - cy;
}
Map m = new HashMap();
m.put("x",x);
m.put("y",y);
return m;
}
}
3、导出二维码流前端进行下载
public class Text{
public void exportCode(String id,HttpServletResponse response) throws Exception{
// 二维码内容
// 生成二维码并指定宽高
BufferedImage generate = qrCodeUtil.encodeQrCode(id, 300,300);
// 判断背景图是否存在
if (true) {
log.info("导出有背景的二维码:"+id);
// 有标题的二维码
BufferedImage qrCodeAddText = qrCodeUtil.addText(generate, id, 30);
int x = qrCodeAddText.getWidth()-generate.getCodewidth();
int y = qrCodeAddText.getHeight()-generate.getCodeheight();
// 生成纯白色背景模板
BufferedImage bgImg = qrCodeUtil.pureColorPictures(generate.getBgwidth()+x,generate.getBgheight()+y);
Map m = qrCodeUtil.calculateXY(bgImg,qrCodeAddText,"5");
x = m.get("x");
y = m.get("y");
// 生成带背景图的二维码
BufferedImage qrCodeWithLogoWithBg = qrCodeUtil.pureColorPicturesAddBgImg(qrCodeAddText, bgImg, x,y);
response.setHeader("Content-Type", "application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + id + ".jpg");
OutputStream outputStream = response.getOutputStream();
ImageIO.write(qrCodeWithLogoWithBg, "jpg", outputStream);
outputStream.flush();
outputStream.close();
}else{
log.info("导出没有背景的二维码:"+id);
// 带标题的二维码
BufferedImage qrCodeAddText = qrCodeUtil.addText(generate, id, 30);
response.setHeader("Content-Type", "application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + id + ".jpg");
OutputStream outputStream = response.getOutputStream();
ImageIO.write(qrCodeAddText, "jpg", outputStream);
outputStream.flush();
outputStream.close();
}
}
}
4、批量下载二维码并放入zip压缩包里面
public class Text{
public void exportList(HttpServletResponse response) throws Exception {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=二维码.zip");
// 生成zip压缩包
ZipOutputStream out = new ZipOutputStream(response.getOutputStream());
byte buff[] = new byte[1024];
if(true) {
for(int i=0;i<10;i++) {
// 生成二维码并指定宽高
BufferedImage generate = qrCodeUtil.encodeQrCode("第"+i,300,300);
// 背景图存在
BufferedImage qrCodeAddText = qrCodeUtil.addText(generate,"第"+i, 30);
int x = qrCodeAddText.getWidth()-generate.getCodewidth();
int y = qrCodeAddText.getHeight()-generate.getCodeheight();
BufferedImage pureColorPicturesImg = qrCodeUtil.pureColorPictures(generate.getBgwidth()+x,generate.getBgheight()+y);
Map m = qrCodeUtil.calculateXY(pureColorPicturesImg,qrCodeAddText,"5");
x = m.get("x");
y = m.get("y");
// 生成带背景图的二维码
BufferedImage qrCodeWithLogoWithBg = qrCodeUtil.pureColorPicturesAddBgImg(qrCodeAddText, pureColorPicturesImg, x, y);
File f = new File(i+".png");
ImageIO.write(qrCodeWithLogoWithBg,"png",f);
FileInputStream fi = new FileInputStream(f);
BufferedInputStream origin = new BufferedInputStream(fi);
ZipEntry entry = new ZipEntry(f.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(buff)) != -1) {
out.write(buff, 0, count);
}
origin.close();
}
}else{
for(int i=0;i<10;i++) {
// 生成二维码并指定宽高
BufferedImage generate = qrCodeUtil.encodeQrCode("第"+i, generate.getCodewidth(), generate.getCodeheight());
// 有标题的二维码
BufferedImage qrCodeAddText = qrCodeUtil.addText(generate,"第"+i, 30);
File f = new File(i+".png");
ImageIO.write(qrCodeAddText,"png",f);
FileInputStream fi = new FileInputStream(f);
BufferedInputStream origin = new BufferedInputStream(fi);
ZipEntry entry = new ZipEntry(f.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(buff)) != -1) {
out.write(buff, 0, count);
}
origin.close();
}
}
out.closeEntry();
out.flush();
out.close();
}
}
5、前端下载
如果直接用get请求(比如:a标签)那么浏览器会自动进行下载,但如果是用ajax进行访问我们后台的话需要使用最原始的blob
$("#pldc").click(function () {
var url2 = "后端地址路径";
var url = url2;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); //
xhr.responseType = "blob"; //
xhr.onreadystatechange = function() {
if(xhr.readyState == 3) {
}
if(xhr.readyState == 4) {
}
};
xhr.onload = function() {
// 为了让所有浏览器都兼容的代码
if(this.status === 200) {
var blob = this.response;
var a = document.createElement('a');
a.download = '二维码.zip';// 自定义下载的名称及格式
a.href = window.URL.createObjectURL(blob);
$("body").append(a);
a.click();
$(a).remove();
}
};
xhr.send();
})



