前言
最近在工作中接到一个H5打印PDF功能的需求,要求对页面中的一个弹框内容进行打印,搜到了很多姿势,在此记录一下。
实现
window.print()
1、window.print() 会打开打印对话框打印当前文档。简单也很简陋。
<!DOCTYPE html>
<html>
<body>
<div class="m-96">
<label for="my-modal" class="btn">open modal</label>
<input id="my-modal" type="checkbox" class="modal-toggle" />
<div id="modal" class="modal">
<div class="modal-box">
<h3 class="text-lg font-bold">Congratulations random Internet user!</h3>
<p class="py-4">
You've been selected for a chance to get one year of subscription to
use Wikipedia for free!
</p>
<div class="modal-action">
<label for="my-modal" class="btn">print!</label>
</div>
</div>
</div>
</div>
<script>
const bodyEl = document.querySelector('body')
const printEl = document.querySelector('.modal-box')
const printBtnEl = document.querySelector('.modal-action')
printBtnEl.addEventListener('click', () => {
// 不打印的内容隐藏掉
printBtnEl.style.display = 'none'
// 暂存body和待打印元素的内容
const bodyContent = bodyEl.innerHTML
const printContent = printEl.innerHTML
// 将body原有的内容替换为待打印元素的内容
bodyEl.innerHTML = printContent
// 打印替换后的内容
window.print()
// 将body原本的内容替换回来
bodyEl.innerHTML = bodyContent
// 不起作用
printBtnEl.style.display = 'block'
// 刷新页面,不刷新的话之前绑定的事件会丢失,之前隐藏掉的元素也恢复不了
window.location.reload()
})
</script>
</body>
</html>
html2canvas 和jspdf
1、利用html2canvas 将html转换为canvas;
2、再通过canvas.toDataURL生成图片;
3、最后用jspdf转换图片为pdf。
<!DOCTYPE html>
<html>
<body>
<div class="m-96">
<label for="my-modal" class="btn">open modal</label>
<input id="my-modal" type="checkbox" class="modal-toggle" />
<div id="modal" class="modal">
<div class="modal-box">
<h3 class="text-lg font-bold">Congratulations random Internet user!</h3>
<p class="py-4">
You've been selected for a chance to get one year of subscription to
use Wikipedia for free!
</p>
<div class="modal-action">
<label for="my-modal" class="btn">print!</label>
</div>
</div>
</div>
</div>
<script src="html2canvas.js"></script>
<script src="jspdf.js"></script>
<script>
const { jsPDF } = jspdf
const printEl = document.querySelector('.modal-box')
const printBtnEl = document.querySelector('.modal-action')
printBtnEl.addEventListener('click', () => {
html2canvas(printEl, {
background: "#ffffff",
useCORS: true,
}).then(function (canvas) {
document.body.appendChild(canvas);
let imageWidth = printEl.width;
let imageHeight = printEl.height;
let image = canvas.toDataURL('image/jpeg', 1.0);
let pdf = new jsPDF('', 'pt', 'a4');
pdf.addImage(image, 'JPEG', 0, 0, imageWidth, imageHeight)
pdf.save('demo.pdf');
})
})
</script>
</body>
</html>
vue3-print-nb
<template>
<div id="printMe" class="p-8">
<h3 class="text-lg font-bold">Congratulations random Internet user!</h3>
<p class="py-4">
You've been selected for a chance to get one year of subscription to use
Wikipedia for free!
</p>
<div class="modal-action">
<label v-print="data.printObj" for="my-modal" class="btn">print!</label>
</div>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import print from 'vue3-print-nb'
const vPrint = print
const data = reactive({
printObj: {
id: 'printMe',
popTitle: 'good print',
extraCss:
'https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css',
extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
beforeOpenCallback() {
console.log('打开之前')
},
openCallback() {
console.log('执行了打印')
},
closeCallback() {
console.log('关闭了打印工具')
},
},
})
</script>