栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Vue+Java】前后端联动生成下载二维码

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Vue+Java】前后端联动生成下载二维码

目录指引
    • 背景
    • 运用场景
    • 环境
    • 丑话说在前
    • 前端部分
      • 通过axios请求传参
        • 二次封装axios.create方法
        • 定义download方法,通过axios进行传参
      • 前端vue页面方法
        • HTML部分按键定义
        • js部分调用方法
    • 后端部分
      • 依赖导入
      • 控制层
      • 服务层
      • 服务实现类
      • 生成二维码工具类
    • 小结

背景

本人,去年毕业的Java后端蒟蒻,目前就职于一个没有正经前端开发的公司。

前段时间公司项目中需要在页面上实现一个二维码下载的按钮,之前从没接触过前端,从零开始熟悉,磕磕绊绊实现了功能,为了以后方便复用,因此作一个记录。

运用场景

在前端展示一个按钮,动态获取地址并生成对应地址的二维码,用户点击下载二维码图片到用户电脑本地。

环境
  • Vue 2.6.11
  • axios 0.18.1
  • JDK 1.8.0_321
  • Maven 3.8.4
丑话说在前

本文最终实现方法是在部署服务器上先生成一个二维码图片,再拉取到用户电脑上,因此最好需要在部署服务器中创建一个文件夹来存放二维码图片并定期处理。

应该是可以通过直接传输流的方式避免这个问题,但当时实现的时候并没有成功,有机会再优化。

前端部分 通过axios请求传参 二次封装axios.create方法

这边api基础地址写的是本地,可以改成部署服务器地址

import axios from 'axios'

const service = axios.create({
  baseURL: "http://localhost:8080", //api基础地址
  timeout: 9000 //请求超时时间
})
定义download方法,通过axios进行传参

这边import指向的是前面封装axios方法的js文件

import { axios } from '@/utils/request' 

export function downFile(url,parameter){
  return axios({
    url: url, 
    params: parameter, 
    method:'get' ,
    responseType: 'blob'
  })
}
前端vue页面方法 HTML部分按键定义

定义一个a标签,添加onclick事件,指向下面js部分的下载二维码方法

下载二维码
js部分调用方法

这边import指向的是前面传参部分定义js方法的文件

import {downFile} from "@api/manage"; 

在data中定义生成二维码的api地址

url: {
  generateQRcode: "example/generateQRcode",
}

在methods中定义下载二维码方法

这边是从后端接收文件流,转换为blob对象后进行输出下载

generateQRcode(QRCodeUrl){
  downFile(this.url.generateQRcode,{QRCodeUrl: QRCodeUrl}).then((data)=>{
    if (!data) {
      this.$message.warning("文件下载失败")
      return
    }
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(new Blob([data],{type: 'image/jpeg'}), QRCode+'.jpg')
    }else{
      let url = window.URL.createObjectURL(new Blob([data],{type: 'image/jpeg'}))
      let link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', 'QRCode.jpg')
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link); //下载完成移除元素
      window.URL.revokeObjectURL(url); //释放掉blob对象
    }
  })
},
后端部分 依赖导入

    com.google.zxing
    core
    3.3.1


    com.google.zxing
    javase
    3.3.1

控制层

这边要生成二维码的网址就是前端传过来的参数,可以通过各种方法进行传参动态修改

@RequestMapping("/example")
public class ExampleController {
   @RequestMapping(value = "/generateQRcode", method = RequestMethod.GET)
   public void generateQRcode(@RequestParam(name = "QRCodeUrl", required = true) String QRCodeUrl, HttpServletRequest request,HttpServletResponse response) throws IOException {
      ExampleService.generateQRcode(QRCodeUrl, request, response);
}
服务层
public interface ExampleService {
	void generateQRcode(String QRCodeUrl, HttpServletRequest request, HttpServletResponse response) throws IOException;
}
服务实现类
@Service
public class ExampleServiceImpl implements ExampleService {
   @Override
   public void generateQRcode(String QRCodeUrl, HttpServletRequest request, HttpServletResponse response) throws IOException {
      //生成二维码
      //指定生成路径
      String fileName = "QRcode";
      //保存在服务器上的路径
      String path = FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "QRCode" + File.separator;
      //生成二维码
      QRCodeUtils.createCode(QRCodeUrl, path, fileName + ".jpg");
      //下载二维码
      QRCodeUtils.downFile(path, fileName + ".jpg", request , response);
   }
}
生成二维码工具类
public class QRCodeUtils {
   
   public static void createCode(String url, String path, String fileName) throws IOException {
      //其他参数,如字符集编码
      Map hints = new HashMap();
      hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
      //容错级别为H
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
      //白边的宽度,可取0~4
      hints.put(EncodeHintType.MARGIN, 0);
      BitMatrix bitMatrix = null;
      try {
         bitMatrix = new MultiFormatWriter().encode(url,
               BarcodeFormat.QR_CODE, 256, 256, hints); //解码url,设置二维码宽高256px
         File file = new File(path, fileName); //设置二维码路径&名字
         writeToFile(bitMatrix, "jpg", file); //下载二维码,格式jpg
      } catch (WriterException e) {
         e.printStackTrace();
      }
   }

   
   public static void downFile(String url, String fileName,HttpServletRequest request, HttpServletResponse response) {
      try {
         //1.定义ContentType为("multipart/form-data")让浏览器自己解析文件格式
         response.setContentType("multipart/form-data");
         //2.中文名转码
         //response.setHeader("Content-disposition", "attachment; filename=""+encodeChineseDownloadFileName(request, fileName+".xlsx") +""");
         response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
         //获得文件
         File file = new File(url+fileName);
         FileInputStream in = new FileInputStream(file);
         //3.将文件写入缓冲区OutputStream(out)
         OutputStream out = new BufferedOutputStream(response.getOutputStream());
         int b = 0;
         byte[] buffer = new byte[2048];
         while ((b=in.read(buffer)) != -1){
            //4.将缓冲区文件输出到客户端(out)
            out.write(buffer,0,b);
         }
         in.close();
         out.flush();
         out.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
    
    
	static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		if (!ImageIO.write(image, format, file)) {
			throw new IOException("Could not write an image of format " + format + " to " + file);
		}
	}
}
小结

至此,当用户点击网页中下载二维码按钮,一张名为QRCode.jpg的图片将下载到用户本地。

不需要下载到服务器的方法已经*// TODO*了,有时间再优化(doge)。

也欢迎各位路过的大犇指正问题~

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016649.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号