整合了一下二维码的生成,并且带有文字提示可以加可以不加
<!-- zxing 二维码生成依赖 -->
<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.1.0</version>
</dependency>
这个类是处理一个后台访问静态文件夹的一个封装, 这个类访问静态文件可以保证就算打jar 包也可以访问的到。
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
public class ResourceRenderer {
public static InputStream resourceLoader(String fileFullPath) throws IOException {
ResourceLoader resourceLoader = new DefaultResourceLoader();
return resourceLoader.getResource(fileFullPath).getInputStream();
}
}
然后就是引入QRCode uitil 实现生成
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ResourceUtils;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
* 二维码工具类 Created by fuli.shen on 2017/3/31.
*/
public class QRCodeUtil {
private static final String CHARSET = "utf-8";
// 生成文件后缀
private static final String FORMAT_NAME = "JPG";
// 二维码尺寸
private static final int QRCODE_SIZE = 210;
// LOGO宽度
private static final int WIDTH = 40;
// LOGO高度
private static final int HEIGHT = 40;
/**
* 生成二维码的方法
*
* @param content 目标URL
* @param imgPath LOGO图片地址
* @param needCompress 是否压缩LOGO
* @return 二维码图片
* @throws Exception
*/
public static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
Hashtable hints = new Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN, 4); // 外边距
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE,
hints);
int width = bitMatrix.getWidth();
int height = bitMatrix.getHeight();
// 重新定义一个BufferedImage 网图片上添加rgb颜色
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, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}
if (imgPath == null || "".equals(imgPath)) {
return image;
}
// 插入图片
QRCodeUtil.insertImage(image, imgPath, needCompress);
return image;
}
/**
* 插入LOGO
*
* @param source 二维码图片
* @param imgPath LOGO图片地址
* @param needCompress 是否压缩
* @throws Exception
*/
private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
/*
* File file = new File(imgPath); if (!file.exists()) { System.err.println("" +
* imgPath + " 该文件不存在!"); return; }
*/
//Image src = ImageIO.read(ResourceUtils.getFile(imgPath));
Image src = ImageIO.read(ResourceRenderer.resourceLoader(imgPath));
int width = src.getWidth(null);
int height = src.getHeight(null);
if (needCompress) { // 压缩LOGO
if (width > WIDTH) {
width = WIDTH;
}
if (height > HEIGHT) {
height = HEIGHT;
}
Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 用Graphics 在 BufferedImage 上指定位置绘制
Graphics g = tag.getGraphics();
g.drawImage(image, 0, 0, null); // 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
graph.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param imgPath LOGO地址
* @param destPath 存放目录
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
mkdirs(destPath);
String file = new Random().nextInt(99999999) + ".jpg";
ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
}
/**
* 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
*
* @param destPath 存放目录
*/
public static void mkdirs(String destPath) {
File file = new File(destPath);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param imgPath LOGO地址
* @param destPath 存储地址
* @throws Exception
*/
public static void encode(String content, String imgPath, String destPath) throws Exception {
QRCodeUtil.encode(content, imgPath, destPath, false);
}
/**
* 生成二维码
*
* @param content 内容
* @param destPath 存储地址
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String destPath, boolean needCompress) throws Exception {
QRCodeUtil.encode(content, null, destPath, needCompress);
}
/**
* 生成二维码
*
* @param content 内容
* @param destPath 存储地址
* @throws Exception
*/
public static void encode(String content, String destPath) throws Exception {
QRCodeUtil.encode(content, null, destPath, false);
}
/**
* 生成二维码(内嵌LOGO)
*
* @param content 内容
* @param imgPath LOGO地址
* @param output 输出流
* @param needCompress 是否压缩LOGO
* @throws Exception
*/
public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
throws Exception {
BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
ImageIO.write(image, FORMAT_NAME, output);
}
/**
* 生成二维码
*
* @param content 内容
* @param output 输出流
* @throws Exception
*/
public static void encode(String content, OutputStream output) throws Exception {
QRCodeUtil.encode(content, null, output, false);
}
/**
* 解析二维码
*
* @param file 二维码图片
* @return
* @throws Exception
*/
public static String decode(File file) throws Exception {
BufferedImage image;
image = ImageIO.read(file);
if (image == null) {
return null;
}
BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result;
Hashtable hints = new Hashtable();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return resultStr;
}
/**
* 解析二维码
*
* @param path 二维码图片地址
* @return 不是二维码的内容返回null,是二维码直接返回识别的结果
* @throws Exception
*/
public static String decode(String path) throws Exception {
return QRCodeUtil.decode(new File(path));
}
/**
* Java拼接多张图片
*
* @param imgs 图片地址集合
* @param type 图片类型
* @param dst_pic //输出的文件:F:/test2.jpg
* @param rowCount //一行几张
* @return
*/
public static boolean merge(String[] imgs, String type, String dst_pic, int rowCount) {
// 获取需要拼接的图片长度
int len = imgs.length;
// 判断长度是否大于0
if (len < 1) {
return false;
}
File[] src = new File[len];
BufferedImage[] images = new BufferedImage[len];
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
try {
src[i] = new File(imgs[i]);
images[i] = ImageIO.read(src[i]);
} catch (Exception e) {
e.printStackTrace();
return false;
}
int width = images[i].getWidth() + 2;
int height = images[i].getHeight() + 2;
// 从图片中读取RGB 像素
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
}
int dst_height = images[0].getHeight();
int dst_width = 0;
// 合成图片像素
for (int i = 0; i < images.length; i++) {
if ((i + 1) % rowCount == 0 && i > 0 && (i + 1) != images.length) {
dst_height += images[i].getHeight();
}
}
dst_width = images.length > rowCount ? rowCount * images[0].getWidth() : images.length * images[0].getWidth();
// 合成后的图片
System.out.println("宽度:" + dst_width);
System.out.println("高度:" + dst_height);
if (dst_height < 1) {
System.out.println("dst_height < 1");
return false;
}
// 生成新图片
try {
int startX = 0;
BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
dst_width = images[0].getWidth();
int height_i = 0;
for (int i = 0; i < images.length; i++) {
ImageNew.setRGB(startX, height_i, dst_width, images[i].getHeight(), ImageArrays[i], 0, dst_width);
// height_i += images[i].getHeight();
if ((i + 1) % rowCount == 0 && i > 0) {
height_i += images[i].getHeight();
startX = 0;
} else {
startX += images[i].getWidth();
}
// System.out.println(startX+" "+height_i);
}
File outFile = new File(dst_pic);
ImageIO.write(ImageNew, type, outFile);// 写图片 ,输出到硬盘
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Java拼接多张图片
*
* @param imgs 图片地址集合
* @param type 图片类型
* @param dst_pic //输出的文件:F:/test2.jpg
* @param rowCount //一行几张
* @return
*/
public static boolean merge(BufferedImage[] imgs, String type, int rowCount, OutputStream outputStream) {
// 获取需要拼接的图片长度
int len = imgs.length;
// 判断长度是否大于0
if (len < 1) {
return false;
}
BufferedImage[] images = imgs;
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
int width = images[i].getWidth();
int height = images[i].getHeight();
// 从图片中读取RGB 像素
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
}
int dst_height = images[0].getHeight();
int dst_width = 0;
// 合成图片像素
for (int i = 0; i < images.length; i++) {
if ((i + 1) % rowCount == 0 && i > 0 && (i + 1) != images.length) {
dst_height += images[i].getHeight();
}
}
dst_width = images.length > rowCount ? rowCount * images[0].getWidth() : images.length * images[0].getWidth();
// 合成后的图片
System.out.println("宽度:" + dst_width);
System.out.println("高度:" + dst_height);
if (dst_height < 1) {
System.out.println("dst_height < 1");
return false;
}
// 生成新图片
try {
int startX = 0;
BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
dst_width = images[0].getWidth();
int height_i = 0;
for (int i = 0; i < images.length; i++) {
ImageNew.setRGB(startX, height_i, dst_width, images[i].getHeight(), ImageArrays[i], 0, dst_width);
// height_i += images[i].getHeight();
if ((i + 1) % rowCount == 0 && i > 0) {
height_i += images[i].getHeight();
startX = 0;
} else {
startX += images[i].getWidth();
}
}
ImageIO.write(ImageNew, type, outputStream);// 写图片 ,输出到输出流
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Java拼接多张图片,不足的用空格补齐
*
* @param imgs 图片地址集合
* @param type 图片类型
* @param pageSize 一张有多少张
* @param rowCount //一行几张
* @return
*/
public static BufferedImage merge(List<BufferedImage> imgss, String type, int rowCount,int pageSize, OutputStream outputStream) {
if(imgss.size() < pageSize) {
// 如果要生成的图片不足pageSize 则用空白图片补齐
for(int i = 0;i < pageSize - imgss.size();i++) {
Color color = new Color(255, 255, 255);
imgss.add(QRCodeUtil.forceFill(color.getRGB()));
}
}
// 开始接图片
BufferedImage[] imgs = new BufferedImage[imgss.size()];
// 获取需要拼接的图片长度
int len = imgs.length;
// 判断长度是否大于0
if (len < 1) {
return null;
}
BufferedImage[] images = imgs;
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
int width = images[i].getWidth();
int height = images[i].getHeight();
// 从图片中读取RGB 像素
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
}
int dst_height = images[0].getHeight();
int dst_width = 0;
// 合成图片像素
for (int i = 0; i < images.length; i++) {
if ((i + 1) % rowCount == 0 && i > 0 && (i + 1) != images.length) {
dst_height += images[i].getHeight();
}
}
dst_width = images.length > rowCount ? rowCount * images[0].getWidth() : images.length * images[0].getWidth();
// 合成后的图片
System.out.println("宽度:" + dst_width);
System.out.println("高度:" + dst_height);
if (dst_height < 1) {
System.out.println("dst_height < 1");
}
// 生成新图片
try {
int startX = 0;
BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
dst_width = images[0].getWidth();
int height_i = 0;
for (int i = 0; i < images.length; i++) {
ImageNew.setRGB(startX, height_i, dst_width, images[i].getHeight(), ImageArrays[i], 0, dst_width);
// height_i += images[i].getHeight();
if ((i + 1) % rowCount == 0 && i > 0) {
height_i += images[i].getHeight();
startX = 0;
} else {
startX += images[i].getWidth();
}
}
return ImageNew;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Java拼接多张图片
*
* @param imgs 图片地址集合
* @param type 图片类型
* @param dst_pic //输出的文件:F:/test2.jpg
* @param rowCount //一行几张
* @return
*/
public static boolean merge(BufferedImage[] imgs, String type, String dst_pic, int rowCount) {
// 获取需要拼接的图片长度
int len = imgs.length;
// 判断长度是否大于0
if (len < 1) {
return false;
}
BufferedImage[] images = imgs;
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
int width = images[i].getWidth();
int height = images[i].getHeight();
// 从图片中读取RGB 像素
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
}
int dst_height = images[0].getHeight();
int dst_width = 0;
// 合成图片像素
for (int i = 0; i < images.length; i++) {
if ((i + 1) % rowCount == 0 && i > 0 && (i + 1) != images.length) {
dst_height += images[i].getHeight();
}
}
dst_width = images.length > rowCount ? rowCount * images[0].getWidth() : images.length * images[0].getWidth();
// 合成后的图片
System.out.println("宽度:" + dst_width);
System.out.println("高度:" + dst_height);
if (dst_height < 1) {
System.out.println("dst_height < 1");
return false;
}
// 生成新图片
try {
int startX = 0;
BufferedImage ImageNew = new BufferedImage(dst_width, dst_height, BufferedImage.TYPE_INT_RGB);
dst_width = images[0].getWidth();
int height_i = 0;
for (int i = 0; i < images.length; i++) {
ImageNew.setRGB(startX, height_i, dst_width, images[i].getHeight(), ImageArrays[i], 0, dst_width);
// height_i += images[i].getHeight();
if ((i + 1) % rowCount == 0 && i > 0) {
height_i += images[i].getHeight();
startX = 0;
} else {
startX += images[i].getWidth();
}
// System.out.println(startX+" "+height_i);
}
File outFile = new File(dst_pic);
ImageIO.write(ImageNew, type, outFile);// 写图片 ,输出到硬盘
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* Java拼接多张图片
*
* @param imgs
* 图片地址集合
* @param type
* 图片类型
* @param dst_pic
* //输出的文件:F:/test2.jpg
* @param rowCount
* //一行几张
* @return
*/
public static InputStream merge(BufferedImage[] imgs, String type, int rowCount) {
// 获取需要拼接的图片长度
int len = imgs.length;
// 判断长度是否大于0
if (len < 1) {
System.out.println("要拼接的长度为零!!!!!!!!!!!!!!!!");
return null;
}
BufferedImage[] images = imgs;
int[][] ImageArrays = new int[len][];
for (int i = 0; i < len; i++) {
int width = images[i].getWidth();
int height = images[i].getHeight();
// 从图片中读取RGB 像素
ImageArrays[i] = new int[width * height];
ImageArrays[i] = images[i].getRGB(0, 0, width, height,
ImageArrays[i], 0, width);
}
int dst_height = images[0].getHeight();
int dst_width = 0;
// 合成图片像素
for (int i = 0; i < images.length; i++) {
if ((i + 1) % rowCount == 0 && i > 0 && (i + 1) != images.length) {
dst_height += images[i].getHeight();
}
}
dst_width = images.length > rowCount ? rowCount * images[0].getWidth()
: images.length * images[0].getWidth();
// 合成后的图片
System.out.println("宽度:" + dst_width);
System.out.println("高度:" + dst_height);
if (dst_height < 1) {
System.out.println("dst_height < 1");
return null;
}
// 生成新图片
try {
int startX = 0;
BufferedImage ImageNew = new BufferedImage(dst_width, dst_height,
BufferedImage.TYPE_INT_RGB);
dst_width = images[0].getWidth();
int height_i = 0;
for (int i = 0; i < images.length; i++) {
ImageNew.setRGB(startX, height_i, dst_width,
images[i].getHeight(), ImageArrays[i], 0, dst_width);
// height_i += images[i].getHeight();
if ((i + 1) % rowCount == 0 && i > 0) {
height_i += images[i].getHeight();
startX = 0;
} else {
startX += images[i].getWidth();
}
// System.out.println(startX+" "+height_i);
}
// File outFile = new File(dst_pic);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(ImageNew, "jpg", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
// ImageIO.write(ImageNew, type, outputStream);// 写图片 ,输出到zip输出流
return is;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 给二维码下方附加说明文字
* @param pressText 文字
* @param image 需要添加文字的图片
* @为图片添加文字
*/
public static void pressText(String pressText, BufferedImage image, int fontStyle, Color color, int fontSize) {
//计算文字开始的位置
//x开始的位置:(二维码-字体大小*字的个数)/2
//int startX = (QRCODE_SIZE - (fontSize * pressText.length()))/3 - 28;
int ci = (fontSize-2) * pressText.length();
int startX = (QRCODE_SIZE-ci)/2;
//y开始的位置:二维码高度 - 文字大小
int startY = QRCODE_SIZE - fontSize;
//y开始的位置:二维码高度 - 文字大小
int startY = QRCODE_SIZE - fontSize;
System.out.println("startX: " + startX);
System.out.println("startY: " + startY);
System.out.println("fontSize: " + fontSize);
System.out.println("pressText.length(): " + pressText.length());
try {
// 创建一个 Graphics
Graphics g = image.createGraphics();
// 设置 Graphics 的绘制颜色
g.setColor(color);
// 设置字体
g.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
// 开始绘制
g.drawString(pressText, startX, startY);
// 保存
g.dispose();
System.out.println("添加的pressText 为:【"+pressText+"】");
System.out.println("image press success");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
}
/**
* 生成一张纯色图片
* @param rgb
* @return
*/
public static BufferedImage forceFill( int rgb) {
BufferedImage img = new BufferedImage(QRCODE_SIZE, QRCODE_SIZE, BufferedImage.TYPE_3BYTE_BGR);
for(int x = 0; x < img.getWidth(); x++) {
for(int y = 0; y < img.getHeight(); y++) {
//img.setRGB(x, y, rgb);
img.setRGB(x, y, rgb);
}
}
return img;
}
public static void main(String[] args) throws Exception {
// 生成二维码
String text = "https://www.baidu.com/";
// String imagePath = System.getProperty("user.dir") + "/data/1.jpg";
String destPath = "C:\\Users\\admin\\Desktop\\";
List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
for (int i = 0; i < 12; i++) {
BufferedImage bufferedImage = QRCodeUtil.createImage("hello", "classpath:static/image/olt.obd_01.png",
true);
bufferedImages.add(bufferedImage);
}
// QRCodeUtil.encode(content, output);
// 验证图片是否含有二维码
/*
* String destPath1 = "C:\\Users\\admin\\Desktop\\3.jpg"; try { String result =
* decode(destPath1); System.out.println(result); }catch (Exception e){
* e.printStackTrace(); System.out.println(destPath1+"不是二维码"); }
*/
// 输入图片地址
String[] imgs = { "C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg", "C:\\Users\\admin\\Desktop\\1.jpg",
"C:\\Users\\admin\\Desktop\\2.jpg" };
BufferedImage[] bfs = new BufferedImage[bufferedImages.size()];
// 调用方法生成图片
merge(bufferedImages.toArray(bfs), "jpg", "C:\\Users\\admin\\Desktop\\test.jpg", 4);
}
}
然后就是 控制类了,在这个类里面,我控制好了,多张生成的时候会自动补齐一个a4 规格的纸张 也就是 4:6 的比例,刚好可以打印到A4 纸上。如果有需要可以修改我的生成代码,在controller 141 行。底下的ZipUtil 是一个zip 的压缩类,可以看看
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.demo.util.QRCodeUtil;
import com.example.demo.util.ResourceRenderer;
import org.springframework.util.StringUtils;
@Controller
public class QRCodeController {
private Integer fontSize = 16;
private Integer pageSize = 24; // 每张图片的二维码个数
private Integer line = 4; // 二维码每行的个数
private String imgPath = "classpath:static/image/image.jpg";
// 存放存取List 的键
private String preeText = "preeText";
private String content = "content";
@RequestMapping(value= {"/","/index"})
public String index() {
return "index";
}
@RequestMapping("/hello")
@ResponseBody
public String helloWorld() throws IOException {
return "helloWorld";
}
/**
* 开始生成二维码
*
* @param response
* @param content 二维码扫码出来的内容 ☆只在单个二维码生成中有效
* @param num 生成二维码的数量
* @param preeText 二维码上面的文字 ☆只在单个二维码生成中有效
* @throws Exception
*/
@RequestMapping("/qrcode")
public void qrcode(HttpServletResponse response, String text) throws Exception {
response.setContentType("text/html;charset=UTF-8");
response.setContentType("application/x-octet-stream");
// response.setHeader("Content-Disposition", "attachment;filename="+
// System.currentTimeMillis() + ".zip");// 下载文件的名称
response.setHeader("Content-Disposition", "attachment;");
// 开始解析数字
List<Map<String,String>> list = new ArrayList<>();
if(StringUtils.isEmpty(text)) {
System.out.println("请输入要生成的二维码");
return;
}
String[] contents = text.split("\n");
for(String str :contents) {
int index = str.indexOf(",");
if(index == -1) {
list.add(new HashMap<String, String>(){{
System.out.println(str);
put(content, str);
put(preeText, "");
}});
}else {
list.add(new HashMap<String, String>(){{
System.out.println(str);
put(content, str.substring(0,index));
put(preeText, str.substring(index+1));
}});
}
}
Integer num = list.size();
if (num != null && num == 1) {
// 生成单个二维码
response.setHeader("Content-Disposition", "attachment;filename=a.jpg");
Map<String,String> aaa = list.get(0);
BufferedImage bufferedImage = makeQRCodeImg(aaa.get(preeText), aaa.get(this.content));
// 把图片输出出去
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
} else if (num != null && num > 1) {
// 生成批量的时候
response.setHeader("Content-Disposition", "attachment;filename=a.zip");
downMoreImg(response, list);
} else {
System.out.println("请指定正确的二维码数量");
}
}
/**
* 生成压缩包图片
* @param response
* @param list
* @throws Exception
*/
@SuppressWarnings("unused")
private void downMoreImg(HttpServletResponse response,List<Map<String,String>> list) throws Exception {
// 创建一个压缩包
ZipOutputStream zip = new ZipOutputStream(response.getOutputStream());
Integer count = list.size();
Integer big = count % pageSize; // 最后一页的个数
Integer page = big == 0 ? count / pageSize : (count / pageSize) + 1; // 总页数
// 图片名 + 图片流
Map<String, InputStream> imgs = new HashMap<String, InputStream>();
for (int i = 0; i < page; i++) {
// 开始生成图片 i 表示的是当前页
//起始行下标 等于 当前页减去1 乘以 每页个数 也就是说 i*pageSize
Integer begin = i*pageSize,end = begin+pageSize;
if(end > count) end = count; // 防止下标越界
imgs.put("第("+(i+1)+")页",makeImages( list.subList(begin, end)));
System.out.println("第("+(i+1)+") 页生成成功");
}
ZipUtil.zipPut(zip, imgs, "jpg");
// 保存缓存
response.flushBuffer();
}
/**
* 生成一张二维码
* @param content
* @return
* @throws Exception
*/
private InputStream makeImages(List<Map<String,String>> content) throws Exception {
int size = content.size();
List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();
System.out.println("当前拼接二维码的个数为:" + size);
for(int i = 0; i < pageSize; i++) {
if(i >= size)
bufferedImages.add(makeWhiteImg());
else {
// 生成二维码图片
BufferedImage img = makeQRCodeImg(content.get(i).get(preeText), content.get(i).get(this.content));
bufferedImages.add(img);
}
}
BufferedImage[] images = new BufferedImage[size];
InputStream img = QRCodeUtil.merge(bufferedImages.toArray(images), "jpg", line);
return img;
}
/**
* 纯色图片
* @return
*/
private BufferedImage makeWhiteImg() {
Color color = new Color(255, 255, 255);
// System.out.println(color.getRGB());
return QRCodeUtil.forceFill(color.getRGB());
}
/**
* 生成单个二维码
* @param preeText
* @param content
* @return
* @throws Exception
*/
@SuppressWarnings("unused")
private BufferedImage makeQRCodeImg(String preeText,String content) throws Exception {
BufferedImage bufferedImage = QRCodeUtil.createImage(content, imgPath, true);
// 给图片添加文字
QRCodeUtil.pressText(preeText, bufferedImage, Font.BOLD, Color.black, fontSize);
return bufferedImage;
}
}
class ZipUtil {
/**
* 打包
* @param out
* @param fil
* @param suffix
* @return
* @throws IOException
*/
public static ZipOutputStream zipPut(ZipOutputStream out,Map<String,InputStream> fil,String suffix) throws IOException{
for(String name : fil.keySet()){
out.putNextEntry(new ZipEntry(name+"."+suffix));
byte[] buffer = new byte[1024];
int r = 0;
while ((r = fil.get(name).read(buffer)) != -1) {
out.write(buffer, 0, r);
}
fil.get(name).close();
}
out.flush();
out.close();
return out;
}
}
我写了一个html 测试使用他
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
head>
<style>
*{
margin:0px auto;
}
form{
margin-left:25%;
margin-top:10%;
}
style>
<body>
<form action="/qrcode" method="post">
<p>多个二维码请换行,提示于生成二维码的内容中间要用,隔开p>