前端vue实现给pdf添加水印

vue 纯前端预览pdf,纯前端实现pdf加水印下载文件也带水印,防止pdf下载 vue项目使用pdfh5+pdf-lib+ @pdf-lib/fontkit实现吹前端预览pdf并且实现pdf加水印下载pdf文件也带水印 阅读详情

实现效果:

实现原理:将PDF文件一页一页的渲染在画布上面,然后将水印文字也渲染在画布上面。

在网上也找了很多教程,自己试了一下,或多或少有点问题,最后结合了一下,做了些修改实现了。

 使用到的插件 pdfjs-dist,这个版本需要注意,太低或太高版本都不行。我最后选的是2.6.347,成功运行了。

package.json配置文件:

{
  "name": "pdf",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "pdfjs-dist": "^2.6.347",
    "vue": "^2.6.14"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3",
    "vue-template-compiler": "^2.6.14"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

vue代码:


<template>
  <div class="main-container">
    <input type="file" ref="fielinput" @change="uploadFile" />
    <div ref="canvasCont" class="canvas-container">
      <canvas ref="myCanvas" class="pdf-container"></canvas>
    </div>
    <div class="pagination-wrapper">
      <button @click="clickPre">上一页</button>
      <span>第{{ pageNo }} / {{ pdfPageNumber }}页</span>
      <button @click="clickNext">下一页</button>
    </div>
  </div>
</template>

<script>
const pdfJS = require("pdfjs-dist");

pdfJS.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");
export default {
  props: {
    watermark: {
      type: String,
      default: "水印文字",
    },
  },
  mounted() {},
  data() {
    return {
      pageNo: null,
      pdfPageNumber: null,
      renderingPage: false,
      pdfData: null, // PDF的base64
      scale: 1, // 缩放值
      width: "",
      height: "",
    };
  },
  methods: {
    uploadFile() {
      let inputDom = this.$refs.fielinput;
      let file = inputDom.files[0];
      let reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        let data = atob(
          reader.result.substring(reader.result.indexOf(",") + 1)
        );
        this.loadPdfData(data);
      };
    },
    loadPdfData(data) {
      // 引入pdf.js的字体
      let CMAP_URL = "https://unpkg.com/pdfjs-dist@2.0.943/cmaps/";
      //读取base64的pdf流文件
      this.pdfData = pdfJS.getDocument({
        data: data, // PDF base64编码
        cMapUrl: CMAP_URL,
        cMapPacked: true,
      });
      console.log(this.pdfData);
      this.renderPage(1);
    },

    // 根据页码渲染相应的PDF
    renderPage(num) {
      this.renderingPage = true;
      this.pdfData.promise.then((pdf) => {
        this.pdfPageNumber = pdf.numPages;

        pdf.getPage(num).then((page) => {
          // 获取DOM中为预览PDF准备好的canvasDOM对象
          let canvas = this.$refs.myCanvas;
          let ctx = canvas.getContext("2d");

          // 获取页面比率
          let ratio = this._getRatio(ctx);

          // 根据页面宽度和视口宽度的比率就是内容区的放大比率
          let dialogWidth = this.$refs["canvasCont"].offsetWidth;
          let pageWidth = page.view[2] * ratio;
          let scale = dialogWidth / pageWidth;
          let viewport = page.getViewport({ scale });

          // 记录内容区宽高,后期添加水印时需要
          this.width = viewport.width * ratio;
          this.height = viewport.height * ratio;

          canvas.width = this.width;
          canvas.height = this.height;

          // 缩放比率
          ctx.setTransform(ratio, 0, 0, ratio, 0, 0);

          let renderContext = {
            canvasContext: ctx,
            viewport: viewport,
          };
          page.render(renderContext).promise.then(() => {
            this.renderingPage = false;
            this.pageNo = num;

            // 添加水印
            this._renderWatermark();
          });
        });
      });
    },
    // 计算角度
    _getRatio(ctx) {
      let dpr = window.devicePixelRatio || 1;
      let bsr =
        ctx.webkitBackingStorePixelRatio ||
        ctx.mozBackingStorePixelRatio ||
        ctx.msBackingStorePixelRatio ||
        ctx.oBackingStorePixelRatio ||
        ctx.backingStorePixelRatio ||
        1;
      return dpr / bsr;
    },

    // 在画布上渲染水印
    _renderWatermark() {
      let canvas = this.$refs.myCanvas;
      let ctx = canvas.getContext("2d");
      // 平铺水印
      let pattern = ctx.createPattern(this._initWatermark(), "repeat");
      ctx.rect(0, 0, this.width, this.height);
      ctx.fillStyle = pattern;
      ctx.fill();
    },

    // 生成水印图片
    _initWatermark() {
      let canvas = document.createElement("canvas");
      canvas.width = 200;
      canvas.height = 200;
      let ctx = canvas.getContext("2d");
      ctx.rotate((-18 * Math.PI) / 180);
      ctx.font = "14px Vedana";
      ctx.fillStyle = "rgba(0, 0, 0, 0.8)";
      ctx.textAlign = "left";
      ctx.textBaseline = "middle";
      ctx.fillText(this.watermark, 50, 50);
      return canvas;
    },

    clickPre() {
      if (!this.renderingPage && this.pageNo && this.pageNo > 1) {
        this.renderPage(this.pageNo - 1);
      }
    },
    clickNext() {
      if (
        !this.renderingPage &&
        this.pdfPageNumber &&
        this.pageNo &&
        this.pageNo < this.pdfPageNumber
      ) {
        this.renderPage(this.pageNo + 1);
      }
    },
  },
};
</script>

<style scoped>
.main-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.canvas-container {
  width: 600px;
  height: 700px;
  border: 1px dashed black;
  position: relative;
  display: flex;
  justify-content: center;
}
.pdf-container {
  width: 100%;
  height: 100%;
}

.pagination-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

vue使用Fabric和pdfjs完成合同签章及批注 文章摘要:本文详细介绍了合同签章及批注模块的核心难点和功能点,主要涉及PDF渲染与交互、电子签章系统、文字批注系统、文件处理、性能优化、业务逻辑复杂性及浏览器兼容性等方面。通过使用pdfjs-dist库和Fabric.js等技术,实现了PDF的多页动态渲染、电子签章的拖拽与缩放、文字批注的富文本交互等功能。文章还提到了前期准备和主要代码实现,包括引入插件、处理签章图片上传、文件下载等操作,并强调了状态验证、数据转换和内存管理等关键问题。 阅读详情

相关推荐

前端实现在线预览PDF,水印方案,真水印哦。

前端实现PDF预览,并且加水印 公司要做一个PDF预览并且加水印的功能,思考的很久,找了很久的资料,但是没有一篇文章给我完整的解决方案。一般都是用假的水印…发现了 pdf-lib 可以操作 pdf 文件,pdf.js可以预览文件。于是把两个东西组合起来实现了,在后端的帮助下,前端加水印并且预览。想把自己解决这个问题的历程写下来,帮助更多的开发者。 1.准备 实现这个功能需要两个包 PDFJS下载地址 PDF-LIB官网 2.开搞 下载PDFJS的项目目录,然后就用这个开发就好了。集成进Vue项目也是一样。

qq_38062875的博客 4988

vue3中实现给pdf加盖公章(手动拖拽公章确认位置)

开发项目时,碰到了一个这样的需求:需要前端从服务器获取到一个pdf文件,然后用户通过手动拖拽公章的方式确认公章应该加盖的位置,然后将位置信息传递给服务器。代码并不是非常完美,仅供大家参考。全部代码实现如下:(为了方便大家查看效果,pdf由用户手动上传得到)

一路走一路看,一边哭一边笑 2342

vue使用pdf.js预览pdf文件加水印,下载pdf文件

项目背景: vue-cli3脚手架 pdf.js版本为官方最新稳定版2.8.335 pdf.js下载地址:http://mozilla.github.io/pdf.js/getting_started/#download 根据自身需求去选择对应版本 开始使用 一、项目中放置pdf.js的包 在项目的public文件夹下,新建一个pdfjs文件夹,将下载下来的build和web文件夹丢进去,目录结构如下: vue-cli3下public文件夹中的内容不参与打包,打包生成的index.html直接可以访问到

- 4312

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

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

qq_37831545的博客 5827

前端vue基于html2canva jspdf 实现前端页面加水印 并导出页面PDF

view class="exportPdfBtn" @click="downKcReport()">导出PDF//如果将水印列数设置为0,或水印列数设置过大,超过页面最大宽度,则重新计算水印列数和水印x轴间隔。watermark_fontsize: '14px', //水印字体大小。watermark_y_space: 102, //水印y轴间隔。watermark_x_space: 80, //水印x轴间隔。watermark_font: '微软雅黑', //水印字体。

chenchuang0128的博客 4607

vue3 - 实现将当前页面作为pdf进行导出效果功能,把整个页面导出为pdf文件并点击自动下载,支持vue3前端页面局部转pdf及打印加分页防止内容截断(超详细示例源码,一键复制开箱即用)

vue3 pdf,vue3导出pdf,vue3把整个页面导出为pdf,vue3如何将页面生成pdf导出,vue3局部页面转PDF文件,vue3怎么用jspdf仅将页面的部分转为pdf,vue3 jspdf防截断处理教程,vue3将页面进行打印插件组件,vue3 当前页面导出pdf,vue3 如何将页面生成 pdf 导出,vue3 页面导出为pdf,vue3.x网页导出pdf,vue3局部页面导出pdf,vue3项目把某个div盒子或当前页面生成pdf文件并下载,vue3将页面作为pdf进行导出,vue3如何

✅ 精选推荐文章 1万+

vue前端预览pdf并加水印、ofd文件,控制打印、下载、另存,vue-pdf的使用方法以及在开发中所踩过的坑合集

根据公司的实际项目需求,要求实现对pdf和ofd文件的预览,并且需要限制用户是否可以下载、打印、另存pdf、ofd文件,如果该用户可以打印、下载需要控制每个用户的下载次数以及可打印的次数。正常的预览pdf很简单,直接调用浏览器的预览就可以而且功能也比较全,但是一涉及到禁止用户打印、另存的话就不可以用浏览器自带的预览方式了。那就只能寻找插件来模拟了,之前在eletron-vue项目中使用过pdfjs以及vue-pdf插件,效果不是特别好

zhangzuying的博客 2万+

Vue使用pdf-lib为文件流添加水印并预览

这次项目中又要预览pdf了,要求还要加水印,做的时候又发现了一种预览pdf的方式,这种方式我觉的更好一些,并且还有个要求就是添加水印,当然水印后端也是可以加的,但是后端说了一堆...反正就是要让前端做,在我看来就是借口、不想做,最近也不忙,那我就给他搞出来好了。下面来介绍一下。

专注于技术,分享实战经验,探索技术边界,用代码构建更美的数字世界。 5534

java使用itext7实现html转pdf

使用itext7html转pdf

陌子曦的专栏 3240

vue实现上传pdf文件盖章与签名,盖章文件下载

我们使用了

weixin_45291798的博客 7131

vue-pdf-show:前端PDF显示和盖章(vue)

npm install npm运行开发 输入

vue3 如何将页面生成 pdf 导出

导出PDF

weixin_42125732的博客 2204

【Cadence】Virtuoso@LayoutXL 差分电路版图同步修改

对于差分电路,器件和部分走线通常是对称的,只需要画一半,另一半通过镜像操作完成。因此,需要对差分电路进行同步的修改,保证电路的差分对称性和正确的连接关系。然而,通常版图会经过多次修改,修改的部分可能在镜像的时候被遗漏。左边画了金属块,右边也出现了同步出现了金属块。进入group会有同步复制的提示。

乾巽的博客 3051

在Vue中使用jsPDF,为每一页添加固定信息

在Vue项目中使用jsPDF生成PDF,其中可能会有这样的需求——为每一页添加固定信息或者按照特定规律添加信息。这时候可以使用jsPDF的pdf.internal.getNumberOfPages()以及pdf.setPage()搭配使用来实现需求,具体如下: import jsPDF from 'jspdf' const pdf = new jsPDF() /** * ....... 进行了相应的PDF生成操作 */ // 在最后进行每页插入数据的操作 const totalPages = pdf.in

weixin_43130844的博客 1917

移远EC20模块USB模式切换的底层逻辑与驱动适配探秘

本文深入探讨了移远EC20模块USB模式切换的底层逻辑与驱动适配机制,详细解析了AT命令控制下的USB0与WWAN0模式差异。通过分析USB协议栈、内核驱动框架及网络子系统的交互,提供了模式切换的完整操作流程和常见问题解决方案,助力开发者优化4G通信模块在嵌入式设备中的稳定连接。

cc789的博客 845

软件测试 | 手把手教你如何使用 Charles 抓包工具(电脑+手机端)

软件测试 | 手把手教你如何使用 Charles 抓包工具(电脑+手机端)一、Charles简介二、Charles下载与安装三、Charles配置(1)Charles-PC端的配置如下:(2)过滤网络请求:(3)Charles抓取HTTPS请求包前置条件:(4)Charles抓取HTTPS双向认证包:关注我,免费领取学习资料 嘿。大家好,我是4U: 做过 APP 测试的同学都会接触抓包工具,通过抓包工具可以获取到客户端与服务端接口的交互数据,在实际测试APP的过程中,我们往往会发现服务端返回 的参数字段错

leboxy的博客 4154

上传文件通过字节流保存至数据库,并从读取通过字节流输出到界面。如果是pdf可以生成水印

1.前端界面(我使用的是ant design vue) <a-upload name="file" //接收文件类型为 accept=".pdf" //文件上传的请求地址 :action="uploadAction" //请求头信息,一般上传token使用 :headers="headers"

代码的味道博客 1987

华三R4900 G5服务器实战:用PMC P460-B4阵列卡配置RAID1+RAID6,并搞定CentOS 7.9安装(含热备盘设置)

本文详细解析了在华三R4900 G5服务器上使用PMC P460-B4阵列卡配置RAID1+RAID6混合阵列的全过程,包括热备盘设置和CentOS 7.9系统安装。通过实战步骤和性能优化建议,帮助企业IT人员高效部署高可用存储方案,特别适合需要数据冗余和系统稳定性的企业级应用场景。

weixin_29248653的博客 358

前端操作pdf文件实现添加水印效果

在 Vue 中集成pdf-lib ,实现给 PDF文件 添加水印

李三岁的博客 3265

Silvaco TCAD | 从极化效应到高频开关:GaN HEMT仿真设计与性能验证

本文深入探讨了使用Silvaco TCAD进行GaN HEMT仿真设计与性能验证的关键技术。从极化效应到高频开关特性,详细解析了2DEG形成机制、器件结构设计优化及高频特性仿真技巧,帮助工程师提升GaN HEMT的性能与可靠性。通过实战案例展示了如何通过仿真优化击穿电压和导通电阻,实现开关品质因数的显著提升。

weixin_30872337的博客 484

【安全设备篇】HVV面试专题

还有就是这个可能是被访问的这个内网系统,本身业务系统存在业务逻辑问题,因为内网所布置的很多业务系统往往不会考虑一些安全性问题,比如在正常的业务逻辑请求中直接带了sql语句,就会触发设备规则产生告警,这一类是属于误报,然后会将此告警上报给研判人员,需要研判组专家和甲方客户确认下是否是该系统存在此业务逻辑问题,并且需要确认告警的源ip在此告警的时间段附近有没有进行操作过。天眼日志分析主要基于系统和应用程序的日志数据来识别安全威胁,而威胁感知则通过收集和分析多种来源的情报信息。理解威胁的性质和威胁背后的原理。

大河之犬的博客 7924

pdf添加水印

文章目录一、vue-pdf二、pdfh5 一、vue-pdf 在项目开发过程中,如果我们只需要展示pdf,那么我们可以选择vue-pdf,可以查看我之前的一篇 但是现在的需求是需要显示带水印的pdf出来,这就存在一个问题,vue-pdf会屏蔽签名图层,导致显示不出来水印。 解决方案一: 我在issues上看到有人提出了这个问题。issues地址 解决方案是直接修改pdf.work.js的源码,全局搜索AnnotationFlag.HIDDEN: // if (data.fieldType === 'Sig'

qq_38143787的博客 1490

华为OD机试双机位C卷-AI面板识别(Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 AI面板识别,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解以及在线OJ模拟做题。华为OD机试 - AI面板识别。

qq_45776114的博客 1343

vue通过html2canvas+jspdf生成PDF问题全解(水印,分页,截断,多页,黑屏,空白,附源码)

刚接触这个需求的时候,lz想的是能实现将当前网页内容导出PDF下载即可。因为这也符合常规业务需求逻辑,也没有考虑其他的,因此参考了几篇网上的博文,很快就选定了vue项目中利用html2canvas+jspdf来实现导出PDF。 所以,很快就实现了。在此基础上,还满足了可以动态进行PDF分页dom节点的划分 ,并且觉得就这?就这?蜜汁自信(不自量力)的lz还马上写了一篇博客,下面附上博客地址,内附源码。vue2利用html2canvas+jspdf动态生成多页PDF_html2pdf 多页-CS

qq_34761385的博客 7047

如何成为一名高级数字 IC 设计工程师(6-7)数字 IC 验证篇:DEBUG 技巧

不懂验证的设计不是好的设计;UVM 验证思维是指导缜密的芯片设计的导师;推荐书籍《芯片验证漫游指南》。

新芯设计的博客 1606

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: 解决vue中axios使用AbortController取消的请求无法重新启动
下一篇: centos7 安装photoprism部署私人相册
马上风
博客等级 码龄10年 37粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值