前几天接到的新需求,需要能在web端展示保密的pdf,常规手段(如鼠标右键、ctrl+P、ctrl+P)无法保存,同时添加水印。
方案
因为之前接触过pdf.js,所以在仔细查询资料和体验后,决定使用pdf.js来实现。
为了保密需要,自然是不能直接丢文件路径给页面渲染的。pdf.js支持base64编码格式的文件数据渲染,然后就按照其他人的使用方式,发现很多坑,好在都一一解决了,下面上代码吧。
编写后台将文件转为base64的方法
1 FileInfo file = new FileInfo(fullFileName);//路径 2 using (FileStream fileStream = file.Open(FileMode.Open)) 3 { 4 5 byte[] bt = new byte[fileStream.Length]; 6 fileStream.Read(bt, 0, bt.Length); 7 base64String = Convert.ToBase64String(bt); 8 }
首先,到http://mozilla.github.io/pdf.js/下载稳定版本,里面含有demo
将文件解压后得到的下面两个文件夹,添加的项目中
添加结果
新建pdf_show页面,将web目录下的viewer.html内容复制进去
注意,下图中圈住的内容要换成在你项目中的路径
打开viewer.js,定位到907行
这里也要改为你项目中的对应位置
回到pdf_show页面
在viewer.js前加入如下javascript代码
1 <script type="text/javascript"> 2 var BASE64_MARKER = ';base64,'; 3 //这里保存下要展示的base64编码数据,记得要先处理为pdf.js能识别的格式,就是调用下面的convertDataURIToBinary方法 4 var set_defaultUrl = convertDataURIToBinary('<%=base64String%>'); 5 function convertDataURIToBinary(dataURI) { 6 var raw = window.atob(dataURI); 7 var rawLength = raw.length; 8 var array = new Uint8Array(new ArrayBuffer(rawLength)); 9 for (i = 0; i < rawLength; i++) { 10 array[i] = raw.charCodeAt(i); 11 } 12 return array; 13 } 14 //禁止右键 15 document.oncontextmenu = function (ev) { 16 alert("禁止复制!"); 17 return false; 18 } 19 //禁止ctrl+s,实测无效,后面使用修改viewer.js禁止 20 document.onkeydown = function () { 21 if ((event.ctrlKey) && (window.event.keycode == 67)) { 22 event.returnValue = false; 23 alert("请勿复制~传播BP内容!"); 24 } 25 } 26 //禁止右键 27 document.onmousedown = function () { 28 if (event.button == 2) { 29 event.returnValue = false; 30 alert("请勿复制~传播BP内容!"); 31 } 32 } 33 34 </script>
再回到viewer.js中,搜索DEFAULT_URL,将它的值替换为我们在页面js中定义的全局变量
好了,到这里,base64编码数据展示已经初步可以了,上图
上面的js脚本已经初步禁止了右键的功能,但是这个页面上还有下载和打印的功能,我们也要禁止掉
继续在viewer.js中定位到1077行,将其赋值修改为null
在1966行,将赋值修改为true
在3854行,将其修改为false
在1287行,将值修改为null
这样就解决了页面上直接ctrl+s和ctrl+p还能保存pdf的需求
最后就是水印了,上一个自己拼凑的样式,大家可以自己改改
1 <style type="text/css"> 2 .pdfViewer .canvasWrapper:before { 3 content: "……在 线 版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 \A…… 版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 \A……版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 \A……版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 \A…… 版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 \A…… 版 权 所 有 ,禁 止 任 何 形 式 的 复 制 和 传 播 "; 4 font-size: 35pt; 5 position: absolute; 6 width: 150%; 7 line-height: 150px; 8 top: -77%; 9 left: -24%; 10 margin-left: 0; 11 background-color: rgba(59, 164, 16, 0); 12 color: rgba(38, 144, 120, 0.3803921568627451); 13 -webkit-transform: rotate(-35deg); 14 } 15 16 .pdfViewer .page:before { 17 content: ""; 18 position: absolute; 19 bottom: 0; 20 left: 0px; 21 right: 0px; 22 background: rgba(0, 0, 0, 0.6); 23 height: 100%; 24 z-index: -1; 25 } 26 27 #outerContainer { 28 margin-top: -25px; 29 } 30 </style>
最后再上个效果图
第一次写博客,希望大家能够指出不足。有疑问的地方,欢迎留言,我会尽可能及时回复。