0


前端使用vue-pdf、pdf-lib、canvas 给PDF文件添加水印,并预览与下载

前端使用vue-pdf、pdf-lib 给pdf添加水印,并预览与下载

效果预览

在这里插入图片描述

使用第三方插件

安装依赖插件

npm i vue-pdf --save
npm i pdf-lib --save
npm install --save @pdf-lib/fontkit  //为 pdf-lib 加载自定义字体的工具

import 导入依赖

import pdf from"vue-pdf";import{ degrees, PDFDocument, rgb, StandardFonts }from"pdf-lib";import fontkit from"@pdf-lib/fontkit";

预览添加水印的pdf

setWatermarkContent(){let ele = document.createElement("canvas");
  ele.width =250;
  ele.height =200;let objmsg ={canvas: ele,fontText:"张三-2023-01-01",fontSize:20,fontFamily:"microsoft yahei",fontcolor:"#dadbdc",//字体颜色   默认 #dadbdcrotate:25,//旋转角度   数字类型textAlign:"left",//水印文字居中方式:left center right  默认 left};this.createWaterMark(objmsg);this.drawWaterMark(ele);},// 创建canvas水印图片createWaterMark({ canvas, fontText, fontFamily ="microsoft yahei", fontSize =30, fontcolor ="#dadbdc", rotate =30, textAlign ="left"}){let ctx = canvas.getContext("2d");
  ctx.font =`${fontSize}px ${fontFamily}`;
  ctx.rotate((-rotate * Math.PI)/180);
  ctx.fillStyle = fontcolor;
  ctx.textAlign = textAlign;
  ctx.textBaseline ="Middle";
  ctx.fillText(fontText, canvas.width /6, canvas.height /2);},// 给pdf增加水印遮罩层drawWaterMark(ele){let div = document.createElement("div");
  div.style.pointerEvents ="none";
  div.style.top ="0";
  div.style.left ="0px";
  div.style.position ="absolute";
  div.style.background ="url("+ ele.toDataURL("image/png")+") left top repeat";let width = document.getElementById("pdfBox").clientWidth ||700;let height = document.getElementById("pdfBox").clientHeight ||700;
  div.style.width = width +"px";
  div.style.height = height +"px";
  document.getElementById("myIframe").appendChild(div);},

下载添加水印的pdf

原理就是给显示pdf 的容器增加一层水印遮罩层

// 处理PDFasyncdownFile(){/*2.获取pdf文件的arrarybuffer文件流
  可请求后台接口返回的base64文件流,然后转成arrayBuffer类型
  可访问前端项目中的本地文件,不能直接访问服务器链接文件,会有跨域问题*/try{// 1.通过url获取pdf文件的arrarybuffer文件流const existingPdfBytes =awaitfetch(this.fileUrl).then((res)=> res.arrayBuffer());// 2.将arraybuffer数据转成pdf文档const pdfDoc =await PDFDocument.load(existingPdfBytes);// 3.1  内置字体(不支持中文), 如果水印中不包含中文可直接用内置字体(不支持中文)// const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);// 3.2 自定义字体,如不需要使用自定义字体可以将这一段全部注释掉,也不用下载自定义字体文件和自定义字体工具fontkit// 将自己下载好的.ttf文件放置项目中,然后访问文件路径(不支持访问本地文件)const fontBytes =awaitfetch("/fonts/SourceHanSansCN-Normal.ttf").then((res)=> res.arrayBuffer());
    pdfDoc.registerFontkit(fontkit);// 自定义字体挂载、fontkit为自定义字体注册工具const fontkitFile =await pdfDoc.embedFont(fontBytes);//  4. 为每页pdf添加文字水印const pages = pdfDoc.getPages();for(let i =0; i < pages.length; i++){const noPage = pages[i];const{ width, height }= noPage.getSize();for(let i =0; i <10; i++){for(let j =0; j <3; j++){
          noPage.drawText("张三-2023-01-01",{x:230* j,y:(height /4)* i,size:20,font: fontkitFile,//字体(内置/自定义)color:rgb(0.46,0.53,0.6),rotate:degrees(45),opacity:0.3,});}}}//5. 保存pdf文件的unit64Arrary文件流const pdfBytes =await pdfDoc.save();this.saveByteArray(this.waterFile.fileName +".pdf", pdfBytes);}catch(error){this.$message.warning("文件下载失败!");}},// 下载文件saveByteArray(reportName, byte){var blob =newBlob([byte],{type:"application/pdf"});var link = document.createElement("a");
  link.href = window.URL.createObjectURL(blob);var fileName = reportName;
  link.download = fileName;
  link.click();},

预览及下载总结

下载:

  1. 通过url获取pdf文件的arrarybuffer文件流
  2. 将arraybuffer数据转成pdf文档
  3. 添加水印字体(内置/自定义)
  4. 为每页pdf添加文字水印
  5. 保存pdf文件的unit64Arrary文件流

预览:

  1. 创建canvas容器(用于显示水印文字)
  2. 创建水印canvas
  3. 将水印canvas遮罩层定位到pdf容器中

完整代码

<template><div><div class="content"><div id="myIframe" style="max-width: 700px; min-height: 550px; position: relative; margin: 0 auto"><pdf id="pdfBox":page="pageNum":src="fileUrl" @progress="loadedRatio = $event" @num-pages="totalPages = $event"></pdf></div><el-button v-if="false" type="primary" @click="downFile" plain style="width: 300px">保存并下载pdf</el-button></div><span slot="footer"class="dialog-footer"><div class="btnGroup" v-if="totalPages"><div class="pageNum">{{ pageNum }}/{{ totalPages }}</div><el-button-group><el-button round plain type="primary" icon="el-icon-arrow-left" size="mini" @click="prePage">上一页</el-button><el-button round plain type="primary" size="mini" @click="nextPage">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button></el-button-group></div></span></div></template><script>/* npm i vue-pdf --save
npm install --save @pdf-lib/fontkit
npm i pdf-lib --save
*/import pdf from"vue-pdf";import{ degrees, PDFDocument, rgb, StandardFonts }from"pdf-lib";import fontkit from"@pdf-lib/fontkit";//为 pdf-lib 加载自定义字体的工具exportdefault{components:{
    pdf,},data(){return{pageNum:1,//显示第一页loadedRatio:0,// 当前页面的加载进度,范围是0-1 ,等于1的时候代表当前页已经完全加载完成了totalPages:0,//pdf总页数fileUrl:"XXXXX.pdf",};},mounted(){this.getPageNum();},methods:{// 获取PDF总页数getPageNum(){let loadingTask = pdf.createLoadingTask(this.fileUrl);
      loadingTask.promise
        .then((pdf)=>{this.totalPages = pdf.numPages;this.$nextTick(()=>{this.setWatermarkContent();});}).catch((err)=>{this.$message.warning("pdf加载失败");});},// 上一页prePage(){let page =this.pageNum;
      page = page >1? page -1:this.totalPages;this.pageNum = page;
      window.scrollTo(0,0);},// 下一页nextPage(){let page =this.pageNum;
      page = page <this.totalPages ? page +1:1;this.pageNum = page;
      window.scrollTo(0,0);},setWatermarkContent(){// 1.创建canvas容器(用于显示水印文字)let ele = document.createElement("canvas");
      ele.width =250;
      ele.height =200;let objmsg ={canvas: ele,fontText:"张三-2023-01-01",// StringfontSize:20,fontFamily:"microsoft yahei",fontcolor:"#dadbdc",//字体颜色   默认 #dadbdcrotate:25,//旋转角度   数字类型textAlign:"left",//水印文字居中方式:left center right  默认 left};// 2.创建水印canvasthis.createWaterMark(objmsg);// 2.将水印canvas遮罩层定位到pdf容器中this.drawWaterMark(ele);},// 创建canvas水印图片createWaterMark({ canvas, fontText, fontFamily ="microsoft yahei", fontSize =30, fontcolor ="#dadbdc", rotate =30, textAlign ="left"}){let ctx = canvas.getContext("2d");
      ctx.font =`${fontSize}px ${fontFamily}`;
      ctx.rotate((-rotate * Math.PI)/180);
      ctx.fillStyle = fontcolor;
      ctx.textAlign = textAlign;
      ctx.textBaseline ="Middle";
      ctx.fillText(fontText, canvas.width /6, canvas.height /2);},// 给pdf增加水印遮罩层drawWaterMark(ele){let div = document.createElement("div");
      div.style.pointerEvents ="none";
      div.style.top ="0";
      div.style.left ="0px";
      div.style.position ="absolute";
      div.style.background ="url("+ ele.toDataURL("image/png")+") left top repeat";let width = document.getElementById("pdfBox").clientWidth ||700;let height = document.getElementById("pdfBox").clientHeight ||700;
      div.style.width = width +"px";
      div.style.height = height +"px";
      document.getElementById("myIframe").appendChild(div);},// PDF 下载asyncdownFile(){/*2.获取pdf文件的arrarybuffer文件流
       可请求后台接口返回的base64文件流,然后转成arrayBuffer类型
       可访问前端项目中的本地文件,不能直接访问服务器链接文件,会有跨域问题*/try{// 1.通过url获取pdf文件的arrarybuffer文件流const existingPdfBytes =awaitfetch(this.fileUrl).then((res)=> res.arrayBuffer());// 2.将arraybuffer数据转成pdf文档const pdfDoc =await PDFDocument.load(existingPdfBytes);// 3.1  内置字体(不支持中文), 如果水印中不包含中文可直接用内置字体(不支持中文)// const fontkitFile = await pdfDoc.embedFont(StandardFonts.Helvetica);// 3.2 自定义字体,如不需要使用自定义字体可以将这一段全部注释掉,也不用下载自定义字体文件和自定义字体工具fontkit// 将自己下载好的.ttf文件放置项目中,然后访问文件路径(不支持访问本地文件)const fontBytes =awaitfetch("/fonts/SourceHanSansCN-Normal.ttf").then((res)=> res.arrayBuffer());
        pdfDoc.registerFontkit(fontkit);// 自定义字体挂载、fontkit为自定义字体注册工具const fontkitFile =await pdfDoc.embedFont(fontBytes);//  4. 为每页pdf添加文字水印const pages = pdfDoc.getPages();for(let i =0; i < pages.length; i++){const noPage = pages[i];const{ width, height }= noPage.getSize();for(let i =0; i <10; i++){for(let j =0; j <3; j++){
              noPage.drawText('张三-2023-01-01',{x:230* j,y:(height /4)* i,size:20,font: fontkitFile,//字体(内置/自定义)color:rgb(0.46,0.53,0.6),rotate:degrees(45),opacity:0.3,});}}}//5. 保存pdf文件的unit64Arrary文件流const pdfBytes =await pdfDoc.save();this.saveByteArray("水印PDF.pdf", pdfBytes);}catch(error){this.$message.warning("文件下载失败!");}},// 下载文件saveByteArray(fileName, byte){var blob =newBlob([byte],{type:"application/pdf"});var link = document.createElement("a");
      link.href = window.URL.createObjectURL(blob);var fileName = reportName;
      link.download = fileName;
      link.click();},},};</script>
标签: 前端 vue.js pdf

本文转载自: https://blog.csdn.net/qq_37831545/article/details/128865029
版权归原作者 一朵野花压海棠 所有, 如有侵权,请联系我们删除。

“前端使用vue-pdf、pdf-lib、canvas 给PDF文件添加水印,并预览与下载”的评论:

还没有评论