在上一章实现了使用html2canvas导出图片,并下载到本地,接下来实现如果div内容区域很长,需要滑动时,怎么导出滑动区域内的完整内容。
思路:点击报表导出的按钮,改变css样式来实现导出滑动区域内的完整内容:1.在要导出时将高度设置为可滚动,2.转为图片之后再将图片的高度设置回来
我需要导出的年度报表分为左中右三栏,左侧内容区域比较长,有滑动。left 对应左面的面板,middle 对应中间的面板,right对应右面的面板
详细代码如下:
- 父页面代码
<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>