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

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

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

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

下载并引入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
}

5.改为如下内容:

workerSrc: {
    value: '/script/pdfjs-dist/build/pdf.worker.js',
    kind: OptionKind.WORKER
}

6.预览成功即出现以下界面


image.png
  1. 动态预览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>

3.然后在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;

4.重新预览,即可根据前台不同的预览链接实现不同文件的预览要求

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);

2.改为如下内容:

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.jsp的body标签,添加属性改为如下内容:

<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);
}

2.插入水印代码后内容如下:

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);
}

3.最后在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文件预览效果


在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270