H5打印功能

1,462 阅读1分钟

前言

最近在工作中接到一个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>