echarts图表在浏览器上打印出现裁剪的问题
环境
vue3
浏览器,如Chrome
打印方法,使用window.print()函数,win10快捷键Ctrl+P。
js前端打印pdf
https://user-images.githubusercontent.com/50699824/211144671-53e3744a-9e36-4c87-8c61-e1c07c677b83.png
原因就是在打印时,通过@media print应用的css样式,到这一步没问题。
但是如果你在打印媒体中有改变元素或容器的宽度,同时你又使用了如echarts图表这类具有交互的canvas插件。
那么就会在打印时,出现元素或画面裁切等情况,因为chart图表这类渲染出来的尺寸并没有适应改变后的新的宽度。
我使用了beforeprint事件的方式,但是依旧不行,如下
window.addEventListener('beforeprint', ()=>{
console.log("beforeprint")
nextTick(()=>{
chartInstance.resize();
})
// 或
chartInstance.resize();
});
window.addEventListener('afterprint', () => {
console.log("afterprint")
});
结论不行。
下面说个最终可以的结论,
就是改变宽度的css样式不要写在@media print中,
写到普通的class类里,当真正要打印的时候,再在根节点上应用这一块的样式,
.login-container {
// 这里写普通的样式
}
.login-container--print {
// 这里写打印是要使用的样式,在这里写会改变元素宽度的样式
}
@media print {
// 这里写不会影响宽度的样式,如隐藏一块元素,或改变颜色等等。
}
<script setup>
const printMode = ref(false);
window.addEventListener('beforeprint', ()=>{
console.log("beforeprint")
printMode.value = true;
nextTick(()=>{
// 在这里可以应用图表的方法,适应新的尺寸。
// 唯一的缺点就是会影响页面展示的布局,如果没被`window.print()`函数的打印弹窗遮挡住,你会看到变化。
chartInstance.resize();
})
});
window.addEventListener('afterprint', () => {
console.log("afterprint")
// 这里是反操作,以恢复打印前原先的布局展示。
printMode.value = false;
nextTick(()=>{
// 在这里可以应用图表的方法,适应新的尺寸。
chartInstance.resize();
})
});
</script>
<template>
<div class="login-container" :class="{'login-container--print': printMode}">
...
</div>
</template>
唯一的缺点就是会影响页面展示的布局,如果没被window.print()函数的打印弹窗遮挡住,你会看到变化。
Playwright生成pdf的方式
由于我使用的是Java后端连接Playwright服务生成pdf的需求,
那么该如何确保不会出现裁剪呢?
...
// 1. 先导航到指定页面
page.navigate(url);
...
// 2. 模拟打印媒体
page.emulateMedia(new Page.EmulateMediaOptions().setMedia(Media.PRINT));
...
// 3. 打印pdf,参数根据需求自行更改就行,不是核心逻辑。
page.pdf(pdfOptions);
对,这样就OK了,不会出现裁剪的情况,可以把无头模式设置为false,这样就会在开发环境
弹出浏览器观察了。
你会说打印样式该如何控制?
直接在@media print{}中书写样式就行。如
@media print {
.cls1 {
width: 600px;
color: #000;
...
}
...
}
又如果你想网网页注入js脚本或者想执行网页定义的函数?
那么你一定要看看playwright evaluating文档的用法。
到此完结。
复制请注明出处,在世界中挣扎的灰太狼

浙公网安备 33010602011771号