二维码生成并在下方添加文字,打包下载
Maven依赖
<!-- 二维码生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.0</version>
</dependency>
压缩工具类
package com.ruoyi.common.utils;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author: 程鹏
* @date: 2021-08-31 10:53
* @Description:
*/
@Component
public class ZipUtil {
/**
* @param needZipPath 压缩文件夹路径
* @param out 压缩文件输出流
*/
public static void filetoZip(String needZipPath, OutputStream out)throws RuntimeException{
long start = System.currentTimeMillis();//计算压缩所需要的时间
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
File sourceFile = new File(needZipPath);//获取要压缩的文件
do_file_toZip(sourceFile,zos,"barCode");//开始压缩
long end = System.currentTimeMillis();
long useTime = end - start;//压缩耗费的时间
System.err.println("本次压缩,耗时" + useTime + "毫秒");
} catch (Exception e) {
throw new RuntimeException("压缩失败了,呵呵",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 递归压缩方法
* @param sourceFile 源文件
* @param zos zip输出流
* @param name 压缩后的名称
*/
private static void do_file_toZip(File sourceFile, ZipOutputStream zos, String name) throws Exception {
byte[] buf = new byte[1024 * 2];
if (sourceFile.isFile()) {
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if (listFiles == null || listFiles.length == 0) {
// 需要保留原来的文件结构时,需要对空文件夹进行处理
zos.putNextEntry(new ZipEntry(name + "/"));// 空文件夹的处理
zos.closeEntry();// 没有文件,不需要文件的copy
} else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
do_file_toZip(file, zos, name + "/" + file.getName());
}
}
}
}
}
二维码生成工具类
package com.ruoyi.common.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.CharacterSetECI;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.stereotype.Component;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
/**
* Author 程鹏
* Date: 2021/08/27 16:01
* Description:二维码生成工具类
*/
@Component
public class BarcodeUtils {
private static final Color QRCOLOR = Color.black; // 二维码颜色 默认是黑色
private static final Color BGWHITE = Color.white; // 背景颜色
public static final int WIDTH = 360;
public static final int HEIGHT = 512;
public static final int MARGIN = 2;
public static final int FONTSIZE = 20;
/**
* // 二维码生成
*
* @param contents 说明
* @return BufferedImage
* @throws Exception
*/
public BufferedImage drawQRImage(String pressText,String contents) throws Exception {
BufferedImage qRImage = null;
if (contents == null || "".equals(contents)) {
throw new Exception("content说明不能为空");
}
// 二维码参数设置
HashMap<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, CharacterSetECI.UTF8); // 编码设置
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 安全等级,最高h
hints.put(EncodeHintType.MARGIN, MARGIN); // 设置margin=0-10
// 二维码图片的生成
BarcodeFormat format = BarcodeFormat.QR_CODE;
// 创建矩阵容器
BitMatrix matrix = null;
try {
matrix = new MultiFormatWriter().encode(contents, format, WIDTH, HEIGHT, hints);
} catch (WriterException e) {
e.printStackTrace();
}
// 设置矩阵转为图片的参数
MatrixToImageConfig toImageConfig = new MatrixToImageConfig(QRCOLOR.getRGB(), BGWHITE.getRGB());
// 矩阵转换图像
qRImage = MatrixToImageWriter.toBufferedImage(matrix, toImageConfig);
// pressText(pressText, qRImage);
return pressText(pressText, qRImage);
}
/**
* @param pressText 二维码下方插入文字
* @param image 需要添加文字的图片
* @为图片添加文字
*/
public BufferedImage pressText(String pressText, BufferedImage image) throws Exception {
BufferedImage outImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//计算文字开始的位置
//x开始的位置:(图片宽度-字体大小*字的个数)/2
int startX = (WIDTH - (FONTSIZE * pressText.length())) / 2;
//y开始的位置:图片高度-(图片高度-图片宽度)/2
int startY = HEIGHT - (HEIGHT - WIDTH) / 2 ;
int imageW = outImage.getWidth();
int imageH = outImage.getHeight();
// BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
Graphics2D g = outImage.createGraphics();
g.drawImage(image, 0, 0, imageW, imageH, null);
g.setColor(QRCOLOR);
g.setFont(new Font("微软雅黑", Font.BOLD, FONTSIZE));
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setBackground(Color.white);
// 获取文字数量 按照字节展示
int size = pressText.getBytes("GBK").length;
// 获取一行最多能容纳多少文字 按照文字字节展示
int maxSize = (WIDTH / FONTSIZE - 2)*2;
if (size > maxSize) {
int v = size % maxSize;
for (int a = 0; a < (size / maxSize); a++) {
// g.drawString(pressText.substring(a * maxSize, (a + 1) * maxSize), (WIDTH - (FONTSIZE * maxSize)) / 2 , startY);
String s = outStringByByte(pressText, maxSize);
g.drawString(s, (WIDTH - (FONTSIZE * (WIDTH / FONTSIZE - 2))) / 2 , startY);
pressText=pressText.substring(s.length(),pressText.length());
startY = startY + 30;
}
if (v != 0) {
g.drawString(pressText, (WIDTH - (FONTSIZE * v)) / 2 , startY);
}
} else {
g.drawString(pressText, (WIDTH-((pressText.getBytes("GBK").length)/2)*FONTSIZE)/2 , startY);
}
g.dispose();
return outImage;
}
/**
* 保存二维码图片到本地
* @param contents
* @throws Exception
*/
public void createImg(String pressText,String contents,String filename,String filePath) throws Exception {
BufferedImage qRImageWithLogo = drawQRImage(pressText,contents);
// 写入返回
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(qRImageWithLogo, "jpg", baos);
//图片类型
String imageType = "jpg";
//生成二维码存放文件
File file = new File(filePath+filename+".jpg");
if(!file.exists()){
file.mkdirs();
}
ImageIO.write(qRImageWithLogo, imageType, file);
baos.close();
}
/**
* @param fileName 文件名字
* @param path 路径 具体到要下载的文件名字
* @param delete 下载完成是否删除
* @param response
* @return
*/
public String downLoadFile(String fileName, String path,boolean delete, HttpServletResponse response) {
try {
File file = new File(path);
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition",
"attachment; filename=" + new String(fileName.getBytes("UTF-8"), "ISO8859-1"));
response.setContentLength((int) file.length());
//定义输出类型
response.setContentType("application/zip");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream buff = new BufferedInputStream(fis);
//相当于我们的缓存
byte[] b = new byte[1024];
//该值用于计算当前实际下载了多少字节
long k = 0;
//从response对象中得到输出流,准备下载
OutputStream myout = response.getOutputStream();
//开始循环下载
while (k < file.length()) {
int j = buff.read(b, 0, 1024);
k += j;
myout.write(b, 0, j);
}
myout.flush();
fis.close();
buff.close();
if (delete) {
file.delete();
}
} catch (Exception e) {
System.out.println(e);
}
return null;
}
public void deleteDir(String path){
File file = new File(path);
if(!file.exists()){//判断是否待删除目录是否存在
System.err.println("The dir are not exists!");
}
String[] content = file.list();//取得当前目录下所有文件和文件夹
for(String name : content){
File temp = new File(path, name);
if(temp.isDirectory()){//判断是否是目录
deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
temp.delete();//删除空目录
}else{
if(!temp.delete()){//直接删除文件
System.err.println("Failed to delete " + name);
}
}
}
file.delete();
}
private static String outStringByByte(String str, int len) throws IOException {
byte[] btf = str.getBytes("gbk");
int count = 0;
for (int j = len - 1; j >= 0; j--) {
if (btf[j] < 0)
count++;
else
break;
}
if (count % 2 == 0)
return new String(btf, 0, len, "gbk");
else
return new String(btf, 0, len - 1, "gbk");
}
}