需求
需要打印表格
,UI组件库的表格(arco、element plus 等组件库的表格都会这问题,应该是样式太复杂
)如果用原生的打印会出现样式显示不全
的问题。边框也会不见
。
网上找到个方法 使用html2canvas把表格转成长图然后使用print-js打印
。
虽然html2canvas官网文档写的支持高度16384px。
但是实际使用过程中html2canvas
对于比较长的内容(超过1500px)生成的canvas显示不全
(画布高度可以渲染,但是内容渲染不出来)。
Chrome
Maximum height/width: 32,767 pixels Maximum area: 268,435,456 pixels (e.g., 16,384 x 16,384)
最后用html-to-image
替换。10000+px高度(10多页A4纸,1MB+的图片)的元素也能轻松渲染成图片。
在vue3
使用
安装 html-to-image 和 print-js
yarn add html-to-image
yarn add print-js
SFC
页面引入
<template>
<button @click="print">打印</button>
<div ref="printArea" class="printArea">
<div data-ignore>不打印这个元素</div>
<div v-for="(item,index) in 10000">测试{{index}}</div>
</div>
</template>
<script setup>
import { ref, computed, h, nextTick } from 'vue'
import printJS from 'print-js'
import {toPng} from "html-to-image"
const printArea = ref()
// 打印
const print = () => {
loading.value = true
nextTick(() => {
toPng(printArea.value, {
// 过滤有data-ignore 属性的元素
filter: (node) => {
if (node.dataset && node.dataset.hasOwnProperty("ignore")) {
return false
}
return true
},})
.then((dataUrl) => {
// 下载图片
downBase64ByBlob(dataUrl)
// 根据图片打印
printJS({
printable: dataUrl,
type: 'image',
documentTitle: `打印标题`,
style: 'body {margin-top: 0; background-color: #fff}',
})
})
.finally(() => {
loading.value = false
})
})
}
// 通过blob的方式下载base64,不会出现太大无法下载的情况
const downBase64ByBlob = (dataUrl,fileName='download',fileExtension ="png") => {
// 将 base64 字符串转换为 Blob 对象
const byteCharacters = atob(dataUrl.split(',')[1])
const byteArrays = []
for (let offset = 0; offset < byteCharacters.length; offset += 10240) {
const slice = byteCharacters.slice(offset, offset + 10240)
const byteNumbers = new Array(slice.length)
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
const byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
const blob = new Blob(byteArrays, { type: 'application/octet-stream' })
const blobUrl = URL.createObjectURL(blob)
const creatDom = document.createElement('a')
document.body.appendChild(creatDom)
creatDom.href = blobUrl
creatDom.download = `${fileName}.${fileExtension}`;
creatDom.click()
document.body.removeChild(creatDom)
URL.revokeObjectURL(blobUrl)
}
</script>
<style scoped lang="less">
.printArea {
max-width: 1300px; // 限制最大宽度适应A4宽度打印
}
</style>