前言
该需求是提供一个接口
[
{
"name":"张三",
"url":"https://www.baidu.com"
},
{
"name":"李四",
"url":"https://www.baidu.com"
}
]
传入如上数据结构,返回一个以name为图片名的二维码(需要扫描二维码会自动跳转)的一个压缩包。
@PostMapping("/zip")
public Map gzip(@RequestBody java.util.ArrayList<Map> maps) {
Map<String, Object> result = new HashMap<>();
if (CollectionUtil.isEmpty(maps)) {
result.put("code", 0);
result.put("msg", "请选择导出的目标");
result.put("data", null);
return result;
}
System.out.println("本次共导出=====================>"+maps.size()+"条");
String property = System.getProperty("os.name");
String filepath;
if (property.contains("Windows")) {
filepath = System.getProperty("user.dir") + "\\file\\";
} else {
filepath = System.getProperty("user.dir") + "/file/";
}
File ditu = null;
FileUtil.mkdir(filepath);
//底图
try {
ditu = ResourceUtils.getFile("classpath:ditu.jpg");
} catch (FileNotFoundException e) {
result.put("code", 0);
result.put("msg", "找不到底图");
result.put("data", null);
return result;
}
//文件转化为图片
//1.遍历maps,将每个元素生成二维码
List<List<Map>> lists = splitList(maps, 40);//根据每个线程的处理数量平均切割
CountDownLatch latch = new CountDownLatch(lists.size());
// 创建一个固定大小的线程池
ExecutorService executorService = Executors.newFixedThreadPool(lists.size());
for (int i = 0; i < lists.size(); i++) {
executorService.execute(new GenerateQrCodeTask(lists.get(i), filepath, ditu, latch));
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
// executorService.shutdown();
// maps.forEach(e-> generate(e,filepath, finalDitu));
//2.压缩
File zip = ZipUtil.zip(new File(filepath), Charset.forName("utf-8"));
//3.上传返回url
URL url = uploadUtils.uploadFileStream(FileUtil.getInputStream(zip), zip.getName(), 0);
FileUtil.clean(filepath);
result.put("code", 20000);
result.put("msg", failCounts.get()==0?"SUCCESS":failCounts.get()+"条数据没有URL和店名");
result.put("data", String.valueOf(url));
failCounts = new AtomicInteger(0);
return result;
}
/**
* 根据用户名和URL生成二维码,扫码后进行跳转
* 1.将底图等比画到一张图中
* 2.生成二维码
* 3.二维码定位
* 4.定位文字
* @param map
* @param targetFile
* @param ditu
*/
private void generate(Map map,String targetFile,File ditu) {
String userName = (String) map.get("name");
String url = (String) map.get("url");
File file = new File(targetFile + userName + ".png");
if (StringUtils.isNullOrEmpty(userName) && StringUtils.isNullOrEmpty(url)) {
failCounts.incrementAndGet();
return;
}
if (StringUtils.isNullOrEmpty(url)) {
url = " ";
}
Image srcImg = null;
try {
srcImg = ImageIO.read(ditu);
} catch (IOException e) {
e.printStackTrace();
}
//获取图片的宽
int srcImgWidth = srcImg.getWidth(null);
//获取图片的高
int srcImgHeight = srcImg.getHeight(null);
// 加水印
BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = bufImg.createGraphics();
g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
BufferedImage image = getQR_CODEBufferedImage(url, BarcodeFormat.QR_CODE, 200, 200, getDecodeHintType());
// BufferedImage qr = QrCodeUtil.generate(url,new QrConfig().setWidth(200).setHeight(200).setMargin(0).setCharset(Charset.forName("utf-8")));
//新的图片,把带logo的二维码下面加上文字
BufferedImage outImage = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_4BYTE_ABGR);
try {
//画二维码到新的面板
g.drawImage(image, srcImgWidth/5, srcImgHeight / 5, 200, 200, null);
if (!StringUtils.isNullOrEmpty(userName)) {
//画文字到新的面板
g.setColor(Color.BLACK);
//字体、字型、字号
g.setFont(new Font("粗体", Font.PLAIN, 18));
int strWidth = g.getFontMetrics().stringWidth(userName);
if (strWidth > srcImgWidth) {
//长度过长就换行,换两行
String font1 = "";
String font2 = "";
if (userName.length() > srcImgWidth/(strWidth / userName.length())){
//每行最多多少个字进行截取
font1 = userName.substring(0,srcImgWidth/(strWidth / userName.length())-1);
font2 = userName.substring(srcImgWidth/(strWidth / userName.length()));
}
//画第一行
g.drawString(font1, (srcImgWidth - g.getFontMetrics().stringWidth(font1)) / 2, srcImgHeight / 6 *5);
//画第二行,比第一行偏移20
g.drawString(font2, (srcImgWidth - g.getFontMetrics().stringWidth(font2)) / 2, srcImgHeight / 6 *5 +20);
} else {
g.drawString(userName, (srcImgWidth - strWidth) / 2, srcImgHeight / 6 *5);
}
g.dispose();
}
outImage.flush();
image = outImage;
g.setColor(Color.BLACK);
g.dispose();
bufImg.flush();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.flush();
baos.flush();
image = bufImg;
ImageIO.write(image, "png", baos);
ImageIO.write(image, "png", file);
} catch (IOException e1) {
e1.printStackTrace();
}
}