打印的场景为使用 element-plus 的 drawer 组件中的内容,类似于
<template>
<el-button type="primary" style="margin-left: 16px" @click="drawer = true">
open
</el-button>
<el-drawer
v-model="drawer"
title="I am the title"
:before-close="handleClose"
:size="'80%'"
>
<span>Hi, there!</span>
</el-drawer>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const drawer = ref(false)
const handleClose = (done: () => void) => {
drawer.value = false
}
</script>
干前端的,相信大家都知道 html2canvas 中插件。起先是使用这个插件的,但是这个插件在项目中的表现确实很差劲,会出现错位,打印不全等等各种问题。
最终决定尝试原生的 window.print() 方法
大体的思路即是
1、创建一个新的 div
2、将本来在 drawer 中的 dom 添加到新创建的 div 中
3、调用打印函数之后,再将样式进行还原。
export const exportPdf = async (el: HTMLElement, option: any) => {
const printDiv = document.createElement('div')
printDiv.innerHTML = el!.innerHTML
printDiv.className = el.className
document.body.appendChild(printDiv)
// 设置样式
window.document.title = `XXXXX`
window.app.style.display = 'none'
// 延时打印
await window.delay(20)
// 打印
window.print()
// 还原样式
window.app.style.display = 'block'
window.document.title = 'XXXXX'
// 删除节点
document.body.removeChild(printDiv)
return true
}
调用
<template>
<div ref="detailRef">
// ....
<el-button @click="handleClickExportPDF">导出PDF</el-button>
</div>
</template>
<script setup lang="ts">
import { exportPdf } from '@/utils'
const detailRef = ref()
const handleClickExportPDF = async () => {
await exportPdf(detailRef.value, 'title')
}
</script>