首页 > 建站教程 > JS、jQ、TS >  pdfjs+canvas,实现给pdf添加水印并打印出来正文

pdfjs+canvas,实现给pdf添加水印并打印出来

pdfjs+canvas,实现给pdf添加水印并打印出来,原理就是利用pdfjs读取pdf文件,并且绘制到canvas中,同时,将canvas绘制上水印,效果如下:

pdfjs+canvas,实现给pdf添加水印并打印出来


代码如下,注意点我已经写到代码的注释当中去了:

<template>

  <button v-show="!isPrinting" @click="print">打印</button>

  <div id="printArea"></div>

</template>

<script setup>

import { ref, reactive, onMounted } from 'vue'

import * as PdfJs from 'pdfjs-dist'

const scale = 1.5

let pageSize = 0

const isPrinting = ref(false)

const init = () => {

  // 这个workerSrc必须设置,否则会报错

  // npm install pdfjs-dist 后,我将 node_modules/pdfjs-dist/build/pdf.worker.mjs 文件拷贝到了public目录,然后直接指定这个路径

  PdfJs.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';

  // 加载pdf

  var loadingTask = PdfJs.getDocument('/1.pdf');

  loadingTask.promise.then((pdf) => {

    // 读取pdf页码

    pageSize = pdf.numPages

    // 根据页码,创建出相应数量的canvas

    for(let i=1; i<=pageSize; i++) {

      const canvas = document.createElement('canvas')

      canvas.id = 'canvas'+i

      document.querySelector('#printArea').appendChild(canvas)

    }

    // 将pdf内容渲染到canvas

    for(let i=1; i<=pageSize; i++) {

      pdf.getPage(i).then((page) => {

        var viewport = page.getViewport({scale: scale}); // 设置缩放比例

        var canvas = document.getElementById('canvas'+i);

        const ctx = canvas.getContext('2d')

        const dpr = window.devicePixelRatio || 1

        const bsr = ctx.webkitBackingStorePixelRatio ||

                ctx.mozBackingStorePixelRatio ||

                ctx.msBackingStorePixelRatio ||

                ctx.oBackingStorePixelRatio ||

                ctx.backingStorePixelRatio ||

                1

        const ratio = dpr / bsr

        canvas.width = viewport.width * ratio

        canvas.height = viewport.height * ratio

        canvas.style.width = viewport.width + 'px'

        canvas.style.height = viewport.height + 'px'

        ctx.setTransform(ratio, 0, 0, ratio, 0, 0) // 设置当pdf文件处于缩小或放大状态时,可以拖动

        canvas.height = viewport.height; // 设置canvas高度为第一页的高度

        page.render({canvasContext: ctx, viewport: viewport});

        // 这里是添加水印,等读取完pdf再写入,偷懒,没有查文档,按理说应该写入render回调里,我试了下then,报错了,所以直接定时器解决了

        setTimeout(() => {

          drawWatermark(canvas, '我爱模板网')

        }, 300*i)

      })

    }

  });

}

const drawWatermark = (canvas, watermarkText) => {

  const ctx = canvas.getContext('2d');

  ctx.font = '20px bold  Arial';

  ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';

  ctx.textAlign = 'center';

  ctx.textBaseline = 'middle';

  const margin = 100; // 水印文字间距

  // 获取水印的宽高

  const textWidth = ctx.measureText(watermarkText).width;

  const textHeight = parseInt('watermarkFont'); // 获取字体的高度

  // 水印平铺

  for (let x = 0; x < canvas.width; x += textWidth + margin) {

    for (let y = 0; y < canvas.height; y += margin) {

      ctx.save();

      ctx.translate(x, y);

      ctx.rotate(-30 * Math.PI / 180); // 设置水印倾斜角度

      ctx.fillText(watermarkText, 0, 0);

      ctx.restore();

    }

  }

};

function print() {

  isPrinting.value = true

  setTimeout(() => {

    window.print()

    isPrinting.value = false

  }, 1000)

}

onMounted(() => {

  init()

})

</script>

<style>

#printArea canvas{

  display: block;

}

</style>