美文网首页
html2canvas+post请求文件流

html2canvas+post请求文件流

作者: hui_he | 来源:发表于2018-07-09 19:54 被阅读0次

功能描述:

react项目中,需要做一个功能:点击下载按钮,将包含echarts图表和表格的报告以word形式下载。

解决方案:

前端将报告切割成图片,这里切割成两张,图片以base64形式 post传给服务端,服务端转化为图片写入word并返回

用到的技术:

html2canvas

具体方法:

1.首先安装引入html2canvas

    npm install html2canvas

    import html2canvas from 'html2canvas'

具体使用方法参照官方文档 http://html2canvas.hertzen.com/getting-started

2.html部分

 <Button type="primary" onClick={this.download}>下载</Button>

3.点击事件

convertCanvasToImage = (canvas, flag) => {
    let image = new Image();
    image.src = canvas.toDataURL("image/png");
    image.className = (flag === 'report') ? 'img report' : 'img ks'
    let pic = (flag === 'report') ? document.getElementsByClassName('report') : 
      document.getElementsByClassName('ks')
    if(pic.length > 0) {
      return
    }
    document.body.appendChild(image)
    return image
  }

 download = () => {
    const {dispatch} = this.props
    var cntElem = $("#chartReport")[0]
    var shareContent = cntElem;//需要截图的包裹的(原生的)DOM 对象
    var opts = {
        // scale: scale, // 添加的scale 参数
        // canvas: canvas, //自定义 canvas
        // // logging: true, //日志开关,便于查看html2canvas的内部执行流程
        // width: width, //dom 原始宽度
        // height: height,
        // useCORS: true // 【重要】开启跨域配置
    };
    const that = this
    const chartReport = html2canvas(shareContent, opts).then(function(canvas) {
      //var context = canvas.getContext('2d');
      //关闭抗锯齿
      //context.mozImageSmoothingEnabled = false;
      //context.webkitImageSmoothingEnabled = false;
      //context.msImageSmoothingEnabled = false;
      //context.imageSmoothingEnabled = false;
      that.convertCanvasToImage(canvas, 'report')
    });
    const chartKs = html2canvas($("#chartKs")[0]).then(function(canvas) {
      that.convertCanvasToImage(canvas, 'ks')
    });
    Promise.all([chartReport, chartKs])
    .then(result => {
      let src = []
      $('.img').each(function(e, i) {
        let $src = $(this).attr('src')
        src.push($src)
      })
      const param = {
        base64_pie: src[0],
        base64_bar:src[1],
      }
      dispatch({
        type: 'message/exportReport',
        payload: param
      })
    })
    .catch(e => console.log(e))
  }

4.设置post请求,服务端header设置Content-Type: application/msword,
常用对照表:http://tool.oschina.net/commons/

export async function exportReport(params) {
  return request('/webservice/dashboard/exportReport', {
    method: 'POST',
    responseType: 'blob', //设置type
    body: params,
  });
}

request.js,注意:fetch返回的response正常情况下调用json()生成json数据。但是在这里,我们需要用到blob对象,因此要调用blob()或者arrayBuffer()。

return fetch(url, newOptions)
    .then(checkStatus)
    .then(response => {
      /*if (newOptions.method === 'DELETE' || response.status === 204) {
        return response.text();
      }*/
      if(newOptions.responseType === 'blob') {
        return response.blob()
      }
      return response.json().then(res => {
        if(res.httpCode == '401') { //未登录
          window.location.href = res.url
        }
        return res
      })
    })

models

* exportReport ({payload}, {call, put, select}) {
      const {title} = yield select(_ => _.message)
      const data = yield call(exportReport, payload) 
      if(data instanceof Blob) {
        let fileName = 'aaa.doc'
        if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(data, fileName);
        } else {
          var link = document.createElement('a');
            link.href = window.URL.createObjectURL(data);
            link.download = title
            document.body.appendChild(link);
            var evt = document.createEvent("MouseEvents");
            evt.initEvent("click", false, false);
            link.dispatchEvent(evt);
            document.body.removeChild(link);
          //使用window.open(url)时,不知为何获取不到服务端传回的fileName 
          // const url = window.URL.createObjectURL(data);
          // window.open(url)
        }    
      }
    },

相关文章

网友评论

      本文标题:html2canvas+post请求文件流

      本文链接:https://www.haomeiwen.com/subject/nhrtpftx.html