vue3 使用html2canvas导出图片,解决当div内容区域很长时,怎么导出滑动区域内的完整内容

2023-12-13 12:40:42

在上一章实现了使用html2canvas导出图片,并下载到本地,接下来实现如果div内容区域很长,需要滑动时,怎么导出滑动区域内的完整内容。
思路:点击报表导出的按钮,改变css样式来实现导出滑动区域内的完整内容:1.在要导出时将高度设置为可滚动,2.转为图片之后再将图片的高度设置回来

我需要导出的年度报表分为左中右三栏,左侧内容区域比较长,有滑动。left 对应左面的面板,middle 对应中间的面板,right对应右面的面板

详细代码如下:

  1. 父页面代码
<template>
  <div class="container">
    <div class="mContent" id="exportAll">
      <left :exportBool="exportBool" @exportAction="exportAction"></left>
      <middle></middle>
      <right></right>
    </div>
  </div>
</template>

id = "exportAll"是导出区域dom,exportBool是我定义的参数,判断是否开始导出,exportAction是子组件内的方法

<script setup>
import { ref, onMounted } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { getBackgroundTreeList, getLoginList } from "@/api/cockpit.js";
import left from "./left/index.vue";
import middle from "./middle/index.vue";
import right from "./right/index.vue";
import html2canvas from "html2canvas";
import event from "@/utils/events.js";

const store = useStore();
const router = useRouter();
const exportBool = ref(false);
onMounted(() => {});

// 这是我用来接收是否触发年度报表导出的方法,如果页面的导出按钮在同一页面,可直接使用button的click方法
event.on("exportExcel", (e) => {
  if (e) {
  // 在要导出时将高度设置为可滚动,exportBool为true
    exportBool.value = true;
  }
});
// 子页面方法
const exportAction = () =>{
  setTimeout(() => {
      download();
    }, 500);
}
// 导出下载
const download = () => {
  let targetDom = document.getElementById("exportAll"); //原本需要截图的div
  console.log("🚀 ~ file: index.vue:33 ~ download ~ targetDom:", targetDom.clientWidth)
  let clonedNode = targetDom.cloneNode(true); //复制一个
  clonedNode.setAttribute(
    "style",
    `width: ${targetDom.clientHeight};height: ${targetDom.clientWidth};`
  );
  document.body.appendChild(clonedNode); //放到body后面
  // 转换成canvas
  html2canvas(targetDom, {
    allowTaint: true,
    taintTest: false,
  }).then(function (canvas) {
    var pageData = canvas.toDataURL("image/png", 1.0);
    saveFile(
      pageData.replace("image/png", "image/octet-stream"),
      new Date().getTime() + ".png"
    );
    document.body.removeChild(clonedNode);
  });
};
// 保存路径下载
function saveFile(data, filename) {
  var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
  save_link.href = data;
  save_link.download = filename;
  document.body.appendChild(save_link);
  save_link.click();
  save_link.remove();
// 导出图片后,需要将图片的高度设置回来,exportBool设置成false
  exportBool.value = false;
}

关键代码是设置导出区域的高度height:22rem;

<style lang="scss" scoped>
.container {
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: flex;
  #exportAll {
  // 导出图片的背景色
    background-color: rgb(1, 5, 16);
  }
  .mContent {
    width: 100%;
    // height: 100%;
    height:22rem; // 关键代码,这里设置了最大的滑动区域的高度,我这里写死了,也可以动态获取滑动区域的高度
    display: flex;
    pointer-events: auto;
    top: 1rem;
    position: fixed;
    z-index: 12;
  }
}
</style>

2.滑动区域的子页面left页面代码

<template>
  <div class="assets-left">
   <div :class="exportBool ? 'assets-info1' : 'assets-info'">
    // 这里是很多个echarts图表
  </div>
  </div>
</template>
const props = defineProps({
  exportBool: {
    type: Boolean,
    default: false,
  },
});
const emits = defineEmits(["exportAction"]);
watch(
  () => props.exportBool,
  (val) => {
    if (val) {
      emits("exportAction", true);
    }
  },
  { immediate: true }
);

注意:导出前exportBool=false设置样式.assets-info,设置滑动区域,导出时exportBool=true,更换样式.assets-info1

<style lang="scss" scoped>
.assets-info {
  max-height: 7.2rem; // 导出前设置滑动区域
  overflow-y: auto;
}
.assets-info,
.assets-info1 {
  margin-top: 0.1rem;
  left: 0.18rem;
  pointer-events: auto;
  ...
  }
 </style>

文章来源:https://blog.csdn.net/qq_34736893/article/details/134940540
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。