前幾天接到的新需求,需要能在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>
最后再上個效果圖
第一次寫博客,希望大家能夠指出不足。有疑問的地方,歡迎留言,我會盡可能及時回復。