| package com.dy.pmsGlobal.util; | 
|   | 
| import cn.hutool.core.codec.Base64; | 
| import com.alibaba.excel.EasyExcel; | 
| import com.alibaba.excel.converters.Converter; | 
| import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | 
| import com.dy.common.util.QrCodeGenerator; | 
| import com.google.zxing.WriterException; | 
| import jakarta.servlet.http.HttpServletResponse; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.core.io.ClassPathResource; | 
|   | 
| import java.awt.image.BufferedImage; | 
| import java.io.*; | 
| import java.net.URLEncoder; | 
| import java.util.List; | 
| import java.util.concurrent.ConcurrentHashMap; | 
| @Slf4j | 
| public class QrCodeUtil { | 
|     private static final ConcurrentHashMap<String, File> logoCache = new ConcurrentHashMap<>(); | 
|     private static final String LOGO_PATH = "/images/logo.png"; | 
|   | 
|   | 
|     /** | 
|      * 生成带Logo的二维码图片字节数组。 | 
|      * @param code 二维码内容 | 
|      * @return 二维码图片的字节数组 | 
|      * @throws IOException IO异常 | 
|      * @throws WriterException 二维码生成异常 | 
|      */ | 
|     public static byte[] genQrCode(String code) throws IOException, WriterException { | 
|         File logoFile = logoCache.computeIfAbsent(LOGO_PATH, key -> { | 
|             try { | 
|                 // 使用ClassPathResource获取资源的输入流 | 
|                 ClassPathResource resource = new ClassPathResource(key); | 
|                 // 创建一个临时文件来保存资源内容(避免处理嵌套jar文件时找不到文件) | 
|                 File tempFile = File.createTempFile("logo", ".png"); | 
|                 try (InputStream in = resource.getInputStream(); | 
|                      OutputStream out = new FileOutputStream(tempFile)) { | 
|                     // 从输入流复制到临时文件 | 
|                     byte[] buffer = new byte[1024]; | 
|                     int bytesRead; | 
|                     while ((bytesRead = in.read(buffer)) != -1) { | 
|                         out.write(buffer, 0, bytesRead); | 
|                     } | 
|                     // 返回临时文件 | 
|                     tempFile.deleteOnExit(); // 自动删除临时文件(当JVM退出时) | 
|                     return tempFile; | 
|                 } | 
|             } catch (IOException e) { | 
|                 throw new RuntimeException("加载Logo图片失败", e); | 
|             } | 
|         }); | 
|   | 
|         BufferedImage qrCodeImage = QrCodeGenerator.toBufferedImage(QrCodeGenerator.createBitMatrix(code, QrCodeConstant.MarkQrCodeWidth, QrCodeConstant.MarkQrCodeHeight)); | 
|         if (logoFile != null) { | 
|             qrCodeImage = QrCodeGenerator.addQrCodeLogo(qrCodeImage, logoFile); | 
|         } | 
|         return QrCodeGenerator.bufferedImageToByteArray(qrCodeImage, "JPEG"); | 
|     } | 
|   | 
|     public static String genQrCodeString(String code){ | 
|         try { | 
|             byte[] codes = QrCodeUtil.genQrCode(code); | 
|             return "data:image/jpeg;base64," + Base64.encode(codes); | 
|         } catch (IOException e) { | 
|             e.printStackTrace(); | 
|         } catch (WriterException e) { | 
|             e.printStackTrace(); | 
|         } | 
|         return ""; | 
|     } | 
|   | 
|     public static void downloadExcel(HttpServletResponse response, String fileName, String sheetName, List<Converter> list){ | 
|         if(CollectionUtils.isEmpty(list)){ | 
|             return; | 
|         } | 
|         try{ | 
|             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); | 
|             response.setCharacterEncoding("utf-8"); | 
|             fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20"); | 
|             response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); | 
|             EasyExcel.write(response.getOutputStream(), list.get(0).getClass()).sheet(sheetName).doWrite(list); | 
|         }catch (Exception e){ | 
|             log.error("导出产品信息异常", e); | 
|         } | 
|     } | 
| } |