web项目引入PDF.js并添加水印禁止下载

2023-10-30

web项目引入PDF.js并添加水印禁止下载

普通SSH项目引入PDF.js实现在线预览PDF文件

1. 下载并引入PDF.js实现预览

  1. 官网下载地址:https://mozilla.github.io/pdf.js,下载完成后将压缩包解压;这里我下载的是pdfjs-2.2.228-dist
  2. 将在WebRoot/script目录下创建一个pdfjs-dist目录,将解压后的文件复制到此目录下(仅复制pdfjs-dist下的子目录即可,根目录下的文件这里未进行复制)
  3. 将pdfjs下载时自带的pdf预览文件compressed.tracemonkey-pldi-09.pdf复制到WebRoot目录下用以测试
  4. 运行web项目,在网页中预览该文件,PDF可正常显示,如提示无法加载pdf.worker.js文件,可在/web/viewer.js文件中找到如下片段进行修改:
workerSrc: {
    value: '../build/pdf.worker.js',
    kind: OptionKind.WORKER
}
改为如下内容:
workerSrc: {
    value: '/script/pdfjs-dist/build/pdf.worker.js',
    kind: OptionKind.WORKER
}
  1. 预览成功即出现以下界面在这里插入图片描述

2. 动态预览PDF文件

以上步骤只是实现了PDF文件的预览,下面开始配置动态预览项目中的PDF文件

  1. 在WebRoot目录下创建pdfView目录(PDF预览的业务目录,用作最后Struts2的跳转视图路径),将pdfjs-dist目录下的viewer.html文件复制到此目录下,将后缀改为jsp,便于后面动态预览不同的PDF文件
  2. 实现预览不同的PDF,只需要将PDF文件加载路径修改即可,在viewer.jsp的head标签内中加入如下代码:
<script type="text/javascript">
   var productFilePath = "file=${filePath}";//后台Action传入前台的pdf文件路径参数赋值给url
</script>
  1. 然后在viewer.js中找到functiion webViewerInitialized函数的位置:
var file;
var queryString = document.location.search.substring(1);//修改这行的内容
var params = (0, _ui_utils.parseQueryString)(queryString);
file = 'file' in params ? params.file : _app_options.AppOptions.get('defaultUrl');
validateFileURL(file);
这里的queryString即从url中读取file参数来设置文件路径,将这行进行修改:
var queryString = productFilePath;
  1. 重新预览,即可根据前台不同的预览链接实现不同文件的预览要求

3. 隐藏打开、下载、打印等功能

  1. 隐藏功能比较简单,仅需修改viewer.jsp中的按钮是否显示即可,如此处隐藏打开、下载、打印几个按钮

    在div#toolbarViewerRight下找到id分别为openFile、print、download等button,在class属性中添加visibleMediumView即可隐藏,效果如下:在这里插入图片描述

  2. 如需隐藏鼠标选择、查看文档信息,可在div#secondaryToolbarButtonContainer下找到id分别为cursorSelectTool、documentProperties,在class属性中添加visibleMediumView即可:

<button id="documentProperties" class="secondaryToolbarButton documentProperties visibleMediumView" title="Document Properties…" tabindex="68" data-l10n-id="document_properties">
   <span data-l10n-id="document_properties_label">Document Properties…</span>
</button>

4. 禁止键盘组合按键下载或另存为

  1. 找到键盘组合按键打印的位置:
var hasAttachEvent = !!document.attachEvent;
window.addEventListener('keydown', function (event) {
  if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {
    window.print();

    if (hasAttachEvent) {
      return;
    }

    event.preventDefault();

    if (event.stopImmediatePropagation) {
      event.stopImmediatePropagation();
    } else {
      event.stopPropagation();
    }

    return;
  }
}, true);
  1. 改为如下内容:
var hasAttachEvent = !!document.attachEvent;
window.addEventListener('keydown', function (event) {
  if ((event.keyCode === 80 || event.keyCode === 83) && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {
    //window.print();

    if (hasAttachEvent) {
      return;
    }

    event.preventDefault();

    if (event.stopImmediatePropagation) {
      event.stopImmediatePropagation();
    } else {
      event.stopPropagation();
    }

    return;
  }
}, false);

重新刷新网页,此时尝试通过Ctrrl+P打印或Ctrl+S另存已经不会起作用 原文参考

5. 禁用鼠标操作

  1. 禁用鼠标选择、鼠标右键等操作,修改viewer.jspbody标签,添加属性改为如下内容:
<body tabindex="1" class="loadingInProgress"
        tabindex="1" class="loadingInProgress"
        oncontextmenu="return false;" leftMargin="0" topMargin="0"
        oncopy="return false;" oncut="return false;"
        onselectstart="return false">

6. 添加全局水印

利用canvas添加全局水印,其实就是在viewer.js中遍历文件元素节点的同时,创建水印元素节点并插入到每一页的位置。原文参考

  1. 在viewer.js中找到如下内容,位置大概在11973行前后:
if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
   var textLayerDiv = document.createElement('div');
   textLayerDiv.className = 'textLayer';
   textLayerDiv.style.width = canvasWrapper.style.width;
   textLayerDiv.style.height = canvasWrapper.style.height;
   //---这里就是要插入水印的位置---
   if (this.annotationLayer && this.annotationLayer.div) {
      div.insertBefore(textLayerDiv, this.annotationLayer.div);
   } else {
      div.appendChild(textLayerDiv);
   }
   textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
}
  1. 插入水印代码后内容如下:
if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
    var textLayerDiv = document.createElement('div');
    textLayerDiv.className = 'textLayer';
    textLayerDiv.style.width = canvasWrapper.style.width;
    textLayerDiv.style.height = canvasWrapper.style.height;
    //---------------------水印开始---------------------
    var cover = document.createElement('div');
    cover.className = "cover";
    cover.innerText = "内容保密,请勿复制或下载"; //这里就是水印内容,如果要按照不同的文件显示不同的水印,可参考pdf文件路径的传值方式,在viewer.jsp中head部位接收后台传值并在这里使用
    if (this.annotationLayer) {
        // annotationLayer needs to stay on top
        div.insertBefore(textLayerDiv, this.annotationLayer.div);
        div.appendChild(cover);
    } else {
        div.appendChild(textLayerDiv);
        div.appendChild(cover);
    }
    var coverEle = document.getElementsByClassName('cover'),size = 0,
        nowWidth = +canvasWrapper.style.width.split("p")[0],
        //714为100%时,每页的宽度。对比当前的宽度可以计算出页面变化后字体的数值
        size = 50 * nowWidth / 714 + "px";
    for(var i=0, len=coverEle.length; i<len; i++){
        coverEle[i].style.fontSize = size;
        coverEle[i].style.width = canvasWrapper.style.width;
        coverEle[i].style.height = canvasWrapper.style.height / 10;
    }
    //---------------------水印结束---------------------
    if (this.annotationLayer && this.annotationLayer.div) {
        div.insertBefore(textLayerDiv, this.annotationLayer.div);
    } else {
        div.appendChild(textLayerDiv);
    }

    textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
}
  1. 最后在viewer.css文件开始位置添加水印的css样式完成水印显示:
/* 水印遮罩层 */
.cover{
  z-index: 100;
  position: absolute;
  top: 41%;
  left: 1%;
  transform: rotate(330deg);
  text-align: center;
  font-size: 310%;
  padding-left: 30px;
  letter-spacing: 18px;
  color:rgba(162, 162, 162, 0.4);
}

6. PDF文件预览效果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

web项目引入PDF.js并添加水印禁止下载 的相关文章

随机推荐

  • 小米3c路由器拆机_Redmi 9通过FCC认证;小米手环5曝光;小米路由器AX1800发布

    早在5月9日 就有人在小米海外官网上发现了Redmi 9 并且该机已经获得无线射频认证 型号为M2004J19G 而在今天 Redmi 9通过了FCC认证 从FCC文档上我们可以发现 Redmi 9配备了5000mAh大容量电池 结合此前卢
  • spring boot(四):thymeleaf使用详解

    在上篇文章springboot 二 web综合开发中简单介绍了一下thymeleaf 这篇文章将更加全面详细的介绍thymeleaf的使用 thymeleaf 是新一代的模板引擎 在spring4 0中推荐使用thymeleaf来做前端模版
  • IPV6学习笔记之IPV6地址结构

    IPV6 地址介绍 IPV6地址结构为 前缀 接口标识 前缀相当于IPV4中的网络ID 接口标识相当于主机ID IPv6地址共128 bit 分为8个16bit的块 中间用冒号隔开 例如 2001 0DB8 0000 0000 02AA F
  • 字符串处理专题

    codeup习题 文章目录 codeup习题 Problem A 字符串连接 Problem B 首字母大写 Problem C 字符串的查找删除 Problem D 单词替换 Problem E 字符串去特定字符 Problem F 数组
  • 巴比特

    摘要 据钛媒体报道 8月4日 华为在开发者大会上发布了HarmonyOS 4系统 通过盘古大模型的加持 智慧助手小艺将具备AI大模型能力 就在华为发布HarmonyOS 4系统一周后 小米大模型也浮出水面 其开发的大规模预训练语言模型MiL
  • JSP相关学习——JavaScript事件处理

    JavaScript事件处理 一 什么是事件处理程序 JavaScript可以以事件驱动的方式直接对客户端的输入作出响应 无须经过服务器端程序 也就是说 JavaScript是事件驱动的 二 事件类型 三 事件处理程序的调用 方式一 将事件
  • 一文带你实现刷新页面数据不丢失(操作状态保留)效果

    页面刷新后对数据的操作状态进行保留 也就是页面刷新数据不丢失效果 是我们对前端项目开发中一个算是比较基本的效果了 其实实现的话也是很简单的 今天就来带你一文彻底弄懂此效果的实现 其实总结起来有以下三个比较重要的点 1 监听要保留状态的数据
  • 【文献管理】Zotero基础操作

    文献管理 Zotero基础操作 文章目录 文献管理 Zotero基础操作 一 安装 注册 二 文献导入 1 新建文件夹 2 导入方式 三 文献管理 1 添加标签 2 添加笔记 3 添加插件 四 数据管理与同步 1 数据存放位置 2 数据备份
  • 操作系统模拟页面调度算法(OPT、FIFO、LRU)演示(vc6.0调试通过)

    PageSwitch cpp Defines the entry point for the console application include stdafx h 请分别用FIFO OPT算法实现 页面置换 的模拟 模拟程序的要求如下
  • python数据解析——xpath爬取文字和图片

    xpath解析 最常用且最便捷高效的一种解析方式 通用性 xpath解析原理 1 实例化一个etree的对象 且需要将被解析的页面源码数据加载到该对象中 2 调用etree对象中的xpath方法结合着xpath表达式实现标签的定位和内容的捕
  • 基于redis实现延时队列(二)

    背景 上篇文章中使用了redis的zset 定时器实现延时任务 虽然定时器设置为30秒执行一次 但是还是有时间上的差异化 现更换一种方式实现 可以避免时间上的差异 redis的key过期回调事件 也能达到延迟队列效果 配置修改 redis的
  • QT—3D绘图

    OpenGL是一个跨平台的 用来渲染3D图形的标准API Qt对OpenGL提供了强大的支持 Qt4时代的QtOpenGL模块在Qt5中已经不再建议使用 OpenGL相关的类被移到了Qt GUI模块 Qt Widgets模块中的QOpenG
  • csharp(CS0051)

    net6 定义了一个类 里面有一个枚举 报csharp CS0051 enum Sex Male Female public class Student string name int age Sex sex public Student
  • torch.quantile or np.quantile的计算

    torch的文档详细说明了quantile的计算方法 主要是将q的范围 0 1 转成输入index的范围 0 n 也就是说 将q 乘 n 然后插值计算 quantile位置不是整数 a torch tensor 0 0 1 1 2 1 3
  • 【已解决】5.24 代码问题——TensorFlow==1.14.0版本安装

    安装TensorFlow1 14 0总是显示 ERROR Could not find a version that satisfies the requirement tensorflow1 14 from versions 2 5 0
  • 百度商业大规模微服务分布式监控系统-凤睛

    导读 作为凤睛早期的接入方 后期的核心成员 笔者经历了整个项目前后四年的变迁 看过项目的艰难开端 中期的默默积累以及后期的蓬勃发展 每一次架构的变迁都带着技术浪潮的烙印 也看到项目成员利用有限资源来解决实际问题而持续不断的创新 凤睛是百度商
  • 关于Mac下appid登录提示‘This action could not be completed.’

    情景 打开xcode 运行工程时 xcode提示输入公司开发者账号密码 惊讶 之前没出现过的 按照要求输入密码 但又提示账号过期或密码可能被修改等 于是立马用账号去登陆开发者中心 确保正常登陆后 才放下心来 百度了下 把xcode偏好设置里
  • MySQL-SQL存储过程/触发器详解(下)

    作者 小刘在C站 个人主页 小刘主页 努力不一定有回报 但一定会有收获加油 一起努力 共赴美好人生 学习两年总结出的运维经验 以及思科模拟器全套网络实验教程 专栏 云计算技术 小刘私信可以随便问 只要会绝不吝啬 感谢CSDN让你我相遇 前言
  • 人工智能课程实践-A* 算法编程实践(python实现)

    本次实验的代码由python编写完成 代码在附录中 需要请自取 1 实验目的 1 熟悉启发式搜索算法 A搜索算法的理论 实现方法 2 掌握A 搜索算法的核心算法实现过程 3 理解A 搜索算法如何解决现实工程问题 学会分析现实问题蕴含的搜索求
  • web项目引入PDF.js并添加水印禁止下载

    目录 web项目引入PDF js并添加水印禁止下载 1 下载并引入PDF js实现预览 2 动态预览PDF文件 3 隐藏打开 下载 打印等功能 4 禁止键盘组合按键下载或另存为 5 禁用鼠标操作 6 添加全局水印 6 PDF文件预览效果 w