html2canvas截图上传至后端并下载文件

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:47   1766   0

前言:

主要是来源于一个需求,我需要将页面生成pdf然后下载,鉴于此页面的特殊性,最后决定的方案是我对后端难以生成的部分进行html截图上传到后端,然后后端将图片以及一些其它的部分根据itext生成pdf,然后返回给我。页面的实现效果是我点击按钮,然后pdf被下载。

参考:

第一章 在前端截图下载

值得注意的是html2canvas要用document.querySelector()来获取元素,如果使用$("#xxx")或者document.getElementById()我这里会提示Element is not attached to a Document(后面再次测试时发现只是$("#xxx")不行,document.getElementById()又可以了)

function downloadStudentData(){
 console.log("下载学生数据")
 //打印雷达图
 html2canvas(document.querySelector("#screenDiv"),{
  width: 1000,
  height:1000,
 }).then(canvas => {
     document.body.appendChild(canvas)
     var dataUrl = canvas.toDataURL("image/png");
  console.log(dataUrl);
  let aLink = document.createElement('a');
        //取出图片中的base64数据
  var bstr = atob(dataUrl.split(',')[1])
  var n = bstr.length
  var u8arr = new Uint8Array(n) 
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n) 
  }
  var blob = new Blob([u8arr])
  let evt = document.createEvent("HTMLEvents");
        evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
        aLink.download = "test.png";
        aLink.href = URL.createObjectURL(blob);
        aLink.click()

 });
 
 
}

第二章 将截图传至后端并下载文件

当然图片前端下载就好,这里本人要上传到后端主要是想测试下图片在后端能不能用。

之前想的是用ajax上传并下载文件,但是试了一下发现ajax不能下载文件,从网上找了个不严谨的说法:浏览器中js不能操作磁盘,不然会引起安全问题,要想操作磁盘需要调用浏览器的一些其它的api。

这里采用的是模拟表单提交,值得注意的是,在后端转化图片时要把base64图片的图片头去掉即把data:image/png;base64,去掉,只保留base64图片的数据。

前端:

function downloadStudentData(){
 //打印雷达图
 html2canvas(document.querySelector("#screenDiv"),{
  width: 1000,
  height:1000,
 }).then(canvas => {
//      document.body.appendChild(canvas)
     var dataUrl = canvas.toDataURL("image/png");
  var form = $("<form></form>").attr("action", url).attr("method", "post");
  form.append($("<input></input>").attr("type", "hidden").attr("name", "canvasPhotoBase64Data").attr("value", dataUrl));
  form.appendTo('body').submit().remove();
 });
}

后端:

@RequestMapping("/test")
@RestController
public class TestUpload {
    @RequestMapping("/testUploadPhoto")
    public void testUploadPhoto(String canvasPhotoBase64Data, HttpServletResponse response){
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
        System.out.println("begin");
        System.out.println(canvasPhotoBase64Data);
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            FileOutputStream write = new FileOutputStream(new File("testPhoto"));
            byte[] decoderBytes = decoder.decodeBuffer(canvasPhotoBase64Data.split(",")[1]);
            response.setHeader("content-disposition", "attachment;filename=" + "test.png");
            response.setContentType("multipart/form-data");
            response.getOutputStream().write((decoderBytes));
            response.getOutputStream().flush();
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP