生成二维码

第一步:导依赖包(使用的是Qrcode的方法)

<!--生成二维码,这个jar包可能不容易下载,需要手动将jar包放入maven仓库里--><dependency><groupId>Qrcode_swetake</groupId><artifactId>Qrcode_swetake</artifactId><version>1.0</version></dependency><!--base64流,应用将二维码转为base64流--><dependency><groupId>org.apache.axis</groupId><artifactId>axis</artifactId><version>1.4</version></dependency>

第二步:工具类

public class QRCodeUtil {// 生成二维码 content:二维码里面的内容 qrcodeVersion:决定着大小public static BufferedImage encoderQRCoder(String content, int qrcodeVersion) {try {  Qrcode handler = new Qrcode(); /*表示的字符串长度: 容错率(ECC) 显示编码模式(EncodeMode)及版本(Version)有关*//*二维码的纠错级别(排错率),共有四级:可选L(7%)、M(15%)、Q(25%)、H(30%)(最高H)。纠错信息同样存储在二维码中,纠错级别越高,纠错信息占用的空间越多,那么能存储的有用信息就越少,对二维码清晰度的要求越小  */handler.setQrcodeErrorCorrect('M');  //编码模式:Numeric 数字, Alphanumeric 英文字母,Binary 二进制,Kanji 汉字(第一个大写字母表示)handler.setQrcodeEncodeMode('B');  handler.setQrcodeVersion(qrcodeVersion);byte[] contentBytes = content.getBytes("UTF-8");// 67 + 12 * (v - 1);int size = 67 + 12 * (qrcodeVersion -1);BufferedImage bufImg = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);  Graphics2D gs = bufImg.createGraphics();  gs.setBackground(Color.WHITE);gs.clearRect(0, 0, size, size);  //设定图像颜色:BLACK  gs.setColor(Color.BLACK);  //设置偏移量  不设置肯能导致解析出错  int pixoff = 2;  //输出内容:二维码  if(contentBytes.length > 0 && contentBytes.length < 1024) {  boolean[][] codeOut = handler.calQrcode(contentBytes);  for(int i = 0; i < codeOut.length; i++) {  for(int j = 0; j < codeOut.length; j++) {  if(codeOut[j][i]) {  gs.fillRect(j * 3 + pixoff, i * 3 + pixoff,3, 3);  }  }  }  } else {  System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,120 ]. ");  }  gs.dispose();  bufImg.flush();//生成二维码QRCode图片return bufImg;} catch (Exception e) {  e.printStackTrace();  }return null;}
}

第三步,应用,根据我的业务来,是需要在添加机具的方法里,调用生成二维码的方法,

       //添加后this.save(machine);//移动端扫描需要的格式是这样的,所以就将这样的格式作为content放进二维码里//{"type":1,“params”:{"machineId":111,"projcetId":222,"bidSectionId":333}}Map<String,Object> map=new HashMap<>();map.put("machineId", machine.getMachineId());//新添加的机具idmap.put("projectId",machine.getProjectId());//新添加的机具所在项目map.put("bidSectionId",machine.getBidSectionId());//新添加的机具所在标段//JSONObject machineJson=new JSONObject();machineJson.put("type",1); //考虑到后面有很多模块需要做二维码功能,所以拿type做区分,机具就是type为1machineJson.put("params",map);String machineString = machineJson.toJSONString();// 生成二维码图片BufferedImage bufferedImage = QRCodeUtil.encoderQRCoder(machineString,20);String base64 = null;try {//输出流ByteArrayOutputStream stream = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "png", stream);base64 = Base64.encode(stream.toByteArray());//机具表里存的有二维码字段,因为在添加前没有机具id,所以在save方法执行后拿到机具id再进行修改操作,//此时只修二维码,之前为空字符串,所以此时的修改相当于添加了。之后将这个字段返回给前端,剩下的就是前端拿这个流去进行解析了Machine m=new Machine();m.setQrCode(String.format("%1$s%2$s","data:image/png;base64,",base64));m.setMachineId(machine.getMachineId());this.updateById(m);} catch (Exception e) {e.printStackTrace();}return true;

业务更改,不是添加的时候生成二维码,而是在查询的时候,前端传我一个机具id,点击查看二维码的时候调这个接口,将二维码和一些基本信息返回给他。

@ResponseBody
@RequestMapping(value = {"/createQrCode"}, method = RequestMethod.GET)
public JSONObject createQrCode(@RequestParam(value = "machineId")String machineId){Machine machine = machineService.getById(machineId);String format="";if (machine.getEnterDate()!=null){Timestamp enterDate = machine.getEnterDate();SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");format = dateFormat.format(enterDate);}else{format ="/";}// 返回的信息JSONObject jsonObject=new JSONObject();jsonObject.put("machineName",machine.getMachineName());jsonObject.put("machineNo",machine.getMachineNo());jsonObject.put("specificationType",machine.getSpecificationType());jsonObject.put("enterDate",format);//二维码的内容JSONObject qrCodeJson=new JSONObject();qrCodeJson.put("type",1);qrCodeJson.put("mId",machine.getMachineId());qrCodeJson.put("pId",machine.getProjectId());qrCodeJson.put("bId",machine.getBidSectionId());String qrCodeString = qrCodeJson.toJSONString();//二维码流String base64Image = createImage(qrCodeString);jsonObject.put("qrCode",String.format("%1$s%2$s","data:image/png;base64,",base64Image));return  ReturnUtil.success(jsonObject);}// 创建二维码并生成流
public static String createImage(String content) {// 生成二维码图片BufferedImage bufferedImage = QRCodeUtil.encoderQRCoder(content,5);String base64 = null;try {//输出流ByteArrayOutputStream stream = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "png", stream);base64 = Base64.encode(stream.toByteArray());} catch (Exception e) {e.printStackTrace();}return base64;
}

ps :bufferedImage和base64的互转
https://www.2loveyou.com/articles/2020/01/19/1579401149903.html

批量导出二维码并生成压缩文件

/*** 批量导出二维码* @param machineIds* @param response*/
@ResponseBody
@RequestMapping(value = {"/importQrCode"}, method = RequestMethod.GET)
public void importQrCode(String machineIds, HttpServletResponse response) {String path = "D://";String pathName = "images";// 先删除// 先创建临时文件夹File filePath = new File(path + pathName);path = path + pathName;// path D://images//如果文件夹存在 ,删除文件夹以及下面所有文件if(filePath.exists()){CompressUtil.deleteDir(path);}filePath.mkdir();//否则创建文件夹// 压缩格式 这个需要在配置文件写String format = "zip";path = path +  "/" ; // path D://images/Map<String,String> map1 = new HashMap<>();try {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String fileName = sdf.format(new Date());// 先创建临时文件夹File file = new File(path + fileName);if(!file.exists()){//如果文件夹不存在file.mkdir();//创建文件夹}// 根据拿到的ids从数据库查出集合QueryWrapper<Machine> wrapper = Wrappers.query();//前台传来字符串转“,”分隔的数组presentStatus:"1,2"转[1,2]if (!StringUtil.isNullOrEmpty(machineIds)) {wrapper.in("machineId",machineIds);}List<Map<String, Object>> machineList = machineService.listMaps(wrapper);path = path + fileName; // D://images/2020-10-19for (int i = 0; i < machineList.size(); i++) {// 在machineList里生成文件BASE64Decoder decoder =new BASE64Decoder();//解码过程,即将base64字符串转换成二进制流byte[] imageByte=decoder.decodeBuffer(machineList.get(i).get("qrCode") + "");//生成图片路径和文件名String imagePath = path + "/"  + machineList.get(i).get("machineName") + ".jpg";   // D://images/2020-10-19/1.jpgmap1.put(machineList.get(i).get("machineName") + ".jpg",imagePath);OutputStream out =new FileOutputStream(imagePath);out.write(imageByte);/** 使用流时,都会有一个缓冲区,按一种它认为比较高效的方法来发数据:* 把要发的数据先放到缓冲区,缓冲区放满以后再一次性发过去,而不是分开一次一次地发.* 而flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.* 所以如果在用流的时候,没有用flush()这个方法,很多情况下会出* 现流的另一边读不到数据的问题,特别是在数据特别小的情况下.*/out.flush();out.close();}// 压缩且下载CompressUtil.MultiFileZipDownload(response,(fileName + "." + format),map1);} catch (Exception e) {e.printStackTrace();}
}

所需工具类:

/*** 生成压缩文件 (zip,rar 格式)*/
public class CompressUtil {/*** 多文件zip压缩下载 (说明:读取文件流到zip流中,之后下载)* @param response* @param downloadName  下载后的压缩包名,带后缀* @param map  存放文件信息的map ,key为该文件压缩后的目录层级路径如:/xxx/xxx/xxx.jpg,为文件名时则在压缩包的顶层*             如:xxx.jpg。 value为下载文件所在的路径*/public static void MultiFileZipDownload(HttpServletResponse response, String downloadName, Map<String,String> map) {OutputStream outputStream = null;try {outputStream = response.getOutputStream();} catch (IOException e) {e.printStackTrace();}ZipOutputStream zos=new ZipOutputStream(outputStream);try {response.setContentType("multipart/form-data");response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(downloadName, "UTF-8"));map.forEach((name,path)->{InputStream is = null;BufferedInputStream in = null;byte[] buffer = new byte[1024];int len;//创建zip实体(一个文件对应一个ZipEntry)//name --->压缩包的层级路径ZipEntry entry = new ZipEntry(name);try {//获取需要下载的文件流File file=new File(path);is = new FileInputStream(file);in = new BufferedInputStream(is);zos.putNextEntry(entry);//文件流循环写入ZipOutputStreamwhile ((len = in.read(buffer)) != -1 ) {zos.write(buffer, 0, len);}} catch (Exception e) {e.printStackTrace();}finally {if(entry != null) {try {zos.closeEntry();} catch (Exception e) {e.printStackTrace();}}if(in != null) {try {in.close();} catch (Exception e) {e.printStackTrace();}}if(is != null) {try {is.close();}catch (Exception e) {e.printStackTrace();}}}});} catch (IOException e) {e.printStackTrace();}finally {if(zos != null) {try {zos.close();} catch (Exception e2) {e2.printStackTrace();}}if(outputStream != null) {try {outputStream.close();} catch (Exception e2) {e2.printStackTrace();}}}}/*** @param path   要压缩的文件路径* @param format 生成的格式(zip、rar)d*/public static void generateFile(String path, String format) throws Exception {File file = new File(path);// 压缩文件的路径不存在if (!file.exists()) {throw new Exception("路径 " + path + " 不存在文件,无法进行压缩...");}// 用于存放压缩文件的文件夹String generateFile = file.getParent();File compress = new File(generateFile);// 如果文件夹不存在,进行创建if( !compress.exists() ){compress.mkdirs();}// 目的压缩文件String generateFileName = compress.getAbsolutePath() + File.separator +  file.getName() + "." + format;// 输入流 表示从一个源读取数据// 输出流 表示向一个目标写入数据// 输出流FileOutputStream outputStream = new FileOutputStream(generateFileName);// 压缩输出流ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(outputStream));generateFile(zipOutputStream,file,"");System.out.println("源文件位置:" + file.getAbsolutePath() + ",目的压缩文件生成位置:" + generateFileName);// 关闭 输出流zipOutputStream.close();}/*** @param out  输出流* @param file 目标文件* @param dir  文件夹* @throws Exception*/private static void generateFile(ZipOutputStream out, File file, String dir) throws Exception {// 当前的是文件夹,则进行一步处理if (file.isDirectory()) {//得到文件列表信息File[] files = file.listFiles();//将文件夹添加到下一级打包目录out.putNextEntry(new ZipEntry(dir + "/"));dir = dir.length() == 0 ? "" : dir + "/";//循环将文件夹中的文件打包for (int i = 0; i < files.length; i++) {generateFile(out, files[i], dir + files[i].getName());}} else { // 当前是文件// 输入流FileInputStream inputStream = new FileInputStream(file);// 标记要打包的条目out.putNextEntry(new ZipEntry(dir));// 进行写操作int len = 0;byte[] bytes = new byte[1024];while ((len = inputStream.read(bytes)) > 0) {out.write(bytes, 0, len);}// 关闭输入流inputStream.close();}}/*** 迭代删除文件夹* @param dirPath 文件夹路径*/public static void deleteDir(String dirPath){File file = new File(dirPath);if(file.isFile()){file.delete();}else{File[] files = file.listFiles();if(files == null){file.delete();}else{for (int i = 0; i < files.length; i++){deleteDir(files[i].getAbsolutePath());}file.delete();}}}}

批量导出二维码并生成压缩文件相关推荐

  1. Java:Java编程实现导出二维码

    Java:Java编程实现导出二维码 目录 输出结果 代码设计 输出结果 更新-- 代码设计 public class QRCodeUtil {private static final String ...

  2. 怎样批量制作二维码标签?

    使用二维码管理大批量物品时,通常需要批量制作二维码标签,每个标签都带有不同的二维码和文字信息,例如在设备管理中,不同的设备,贴有不同的二维码标签. 我们可利用免费的第三方软件,设计.打印二维码标签,例 ...

  3. Deli条码打印机如何批量打印二维码

    如题,今天小编就和大家说说Deli条码打印机如何批量打印二维码,除了必须的Deli条码打印机外,还需要条码打印软件,用来生成二维码,话不多活,接下来我们就看先是如何实现的. 把Deli条码打印机和电脑 ...

  4. Excel竟然可以批量解锁二维码内容的操作

    今天小编要分享的操作是,Excel可以批量解锁二维码内容的操作,如下图所示,某销售公司为了保密销量信息呢,将其中的销量信息生成二维码,希望能通过扫码来获得对应的销量.那现在呢,为了统一做汇报工作,需要 ...

  5. NodeJs+VueJs +前端实现批量打印二维码

     第一步 :html 设置DIV,用于存放批量生成的二维码  <div class="x_panel" style="margin:0 auto;display:n ...

  6. Java 生成二维码 zxing生成二维码 条形码 服务端生成二维码 Java生成条形码

    Java 生成二维码 zxing生成二维码 条形码 服务端生成二维码 Java生成条形码 一.关于ZXing 1.ZXing是谷歌开源的支持二维码.条形码 等图形的生成类库:支持生成.和解码功能. G ...

  7. 喷墨打印机如何批量制作二维码标签

    喷墨打印机是现在办公或者印刷行业用的比较普遍的一种打印机,一般来说大多会用来打印A4纸文件,但是现在的标签纸的排版大小不再仅限于卷纸,而是出现了很多使用A4纸排版小标签纸的方式来排版,下面我们就看一下 ...

  8. 二维码制作并压缩下载

    需求:制作出多张二维码,并且压缩后下载.下载下来的压缩包解压后二维码能正常扫码 引入二维码制作的jar包 <dependency><groupId>com.google.zxi ...

  9. java利用core 工具实现二维码的生成与解析

    java利用core 工具实现二维码的生成与解析 简单介绍下二维码:二维码其实就是一种编码技术,只是这种编码技术是用在图片上了,将给定的一些文字,数字转换为一张经过特定编码的图片,而解析二维码则相反, ...

  10. 微信、支付宝,收款二维码实时生成,自定义金额 备注生成

    <font size='6px'>微信 支付宝 个人收款二维码实时生成</font> 微信 支付宝-二维码生成,监控系统 软件实现流程: app通过实现,对外提供web接口,访 ...

最新文章

  1. Ubuntu 18.04 更改静态IP
  2. 用7*7的卷积核分类9*9的图片到底应该用几个卷积核?55个
  3. [Windows子系统] Ubuntu18.04安装及换源
  4. 修改生产订单的BAPI!
  5. Pandas对象的层次化索引——【from_tuples()、from_arrays()、from_product()、swaplevel()、sort_index()、sort_values()】
  6. 年轻人还有机会征服这个世界吗?
  7. python编程快速上手第四章_《Python编程快速上手——让繁琐的工作自动化》读书笔记 第四章 列表...
  8. centos5安装mysql 5.6.19 mysql-devel_Centos5.8 安装 MySQL5.6.19
  9. Helm 3 完整教程(十九):Helm 流控制结构(3)range 语句
  10. AR.js专题-图片匹配
  11. python x 0b1011_python基础语法和进制
  12. Finalize、dispose、dispose(bool disposing)
  13. linux创建sudo用户组,如何将用户添加到sudo组
  14. hgroup元素与figcaption元素的结合使用
  15. 免费壁纸背景高清图片素材网站
  16. 16大类31种好看的可视化图表,图表控们快收藏!
  17. 蚂蚁金服上市估值2k亿美金!会开发到底有多吃香?
  18. [导入]转帖------牛逼顿
  19. 易语言如何调用c dll文件,易语言调用C++写的DLL
  20. 前端工程师说明(仅以自勉)

热门文章

  1. 暴力破解带有密码的压缩文件
  2. Python第五天的学习分享
  3. 阿里巴巴淘宝网电子商务模式调查分析
  4. Unicode中文和特殊字符的编码范围 及部分正则
  5. AAC 音频格式详解
  6. 字节跳动薪资_【字节跳动】到手薪资46K,工作轻松,福利超好的视频审核岗来啦!...
  7. Windform c# pictureBox 更换背景图片
  8. 储存卡怎么格式化为fat32_64g内存卡怎么格式化成fat32格式化
  9. machine learning measurements
  10. 激荡三十年——互联网的崛起