vue保存html为图片功能

概要

实现有滚动条内容的保存图片功能

前期准备

1.写好页面样式
2.安装html2canvas :npm install html2canvas

整体流程

1.将要保存的节点完整复制一遍;
2.修改复制好的节点样式,主要目的是去掉滚动条;
3.将复制好的节点添加到body上;
4.生成图片,模拟下载;
5.删除第三步添加到body上的节点。

完整代码

<div class="dailyBox">
    <div style="background-color: #fff; border-radius: 9px" id="posterBox">
      <div class="leftBox">
        <p class="title">实现有滚动条的内容保存为图片</p>
        <el-table
          id="tableBox"
          :data="tableData"
          :span-method="mergeCells"
          border
          class="tableClass"
          max-height="200"
        >
          <el-table-column
            v-for="item in tableConfig"
            :prop="item.prop"
            :label="item.label"
            width="141"
          />
        </el-table>
      </div>
    </div>
    <div class="rightBox">
      <div class="btn" @click="saveAs">导出图片</div>
    </div>
  </div>
import { ref } from 'vue'
import { ElLoading, ElMessage } from 'element-plus'
import html2canvas from 'html2canvas'
const tableData = ref([
	{
		name:'Jom',
		sex:'男',
		age:12,
		address:'北京市'
	},
	{
		name:'张三',
		sex:'男',
		age:23,
		address:'上海市'
	},
	{
		name:'李四',
		sex:'男',
		age:42,
		address:'北京市'
	},
	{
		name:'王五',
		sex:'男',
		age:12,
		address:'南京市'
	},
	{
		name:'小红',
		sex:'女',
		age:25,
		address:'北京市'
	},
	{
		name:'小明',
		sex:'男',
		age:59,
		address:'上海市'
	},
	{
		name:'小兰',
		sex:'女',
		age:15,
		address:'成都市'
	}
])
const tableConfig = ref([
  {
    prop: 'name',
    label: '姓名'
  },
  {
    prop: 'sex',
    label: '性别'
  },
  {
    prop: 'age',
    label: '年龄'
  },
  {
    prop: 'address',
    label: '地址'
  }
])

const dataURLtoBlob = (dataurl) => {
  let arr = dataurl.split(','),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n)
  while (n--) u8arr[n] = bstr.charCodeAt(n)
  return new Blob([u8arr], { type: mime })
}
const posterBlobData = ref({})
// BLob对象化成文件并导出到本地
const saveAs = async () => {
  let targetDom = document.getElementById('posterBox');   //原本需要截图的div
  let clonedNode = targetDom.cloneNode(true); //复制一个
  clonedNode.setAttribute("style",`width:${targetDom.clientWidth}px`);
  clonedNode.querySelectorAll('#tableBox')[0].setAttribute("style",``);
  clonedNode.querySelectorAll('#tableBox')[0].querySelectorAll('.el-table__inner-wrapper')[0].setAttribute("style",``);
  clonedNode.querySelectorAll('#tableBox')[0].querySelectorAll('.el-table__inner-wrapper')[0].querySelectorAll('.el-scrollbar__wrap.el-scrollbar__wrap--hidden-default')[0].setAttribute("style",``);
  document.body.appendChild(clonedNode); //放到body后面
  const canvas = await html2canvas(clonedNode, {
    useCORS: true
  })
  document.body.removeChild(clonedNode);//删除节点
  let url = canvas.toDataURL() //把canvas转成base64
  // 写一个隐藏的按标签,借助按标签的download属性下载图片
  posterBlobData.value = dataURLtoBlob(url)
  var link = document.createElement('a')
  link.href = window.URL.createObjectURL(posterBlobData.value)
  link.download = 'image'
  link.click();
  ElMessage({
    type: 'success',
    message: '保存成功!'
  })
  window.URL.revokeObjectURL(link.href);
}

需要注意的点

1.保存图片的实质就是将可视区域的内容保存为图片,即复制出来的节点在页面中展示什么样子保存的图片就是什么样子,所以样式要写到全局哦~不然保存的图片没有样式;
2.本文章使用的插件是html2canvas,需要先在项目中安装哦;
3.本文章使用的是vue3+element plus,可根据自己的项目进行修改;
4.本文章项目中根节点#app高度为100vh,所以将复制的节点添加到body中用户无感。可根据实际项目进行更改。

小结

找到解决问题方法时要明白其原理,每个项目不同,修改成自己可以用的,多尝试!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值