<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta charset="utf-8" /> <title>PDF 预览、水印、缩放、旋转</title> <script src="https://ss.netnr.com/pdfjs-dist@3.11.174/build/pdf.min.js"></script> </head> <body> <h3 style="text-align:center">可拖拽 PDF文件打开,支持 #URL 打开链接</h3> <div class="nr-tools"> <select class="nr-size"> <option value="0.5">0.5 倍</option> <option value="0.75">0.75 倍</option> <option value="1.0" selected>缩放比例</option> <option value="1.5">1.5 倍</option> <option value="2.0">2 倍</option> <option value="4.0">4 倍</option> </select> <br/> <select class="nr-watermark"> <option value="1">开启水印</option> <option value="0">关闭水印</option> </select> <br/> <select class="nr-spin"> <option value="0">旋转角度</option> <option value="90">旋转 90</option> <option value="180">旋转 180</option> <option value="270">旋转 270</option> </select> </div> <div class="nr-pdf-viewer"></div> </body> </html>
body { color: deeppink; } .nr-tools { position: fixed; top: 10%; right: 1.5%; z-index: 1; line-height: 2em; } .nr-pdf-viewer { text-align: center; } .nr-pdf-viewer .nr-pdf-page { position: relative; display: inline-block; } .nr-pdf-viewer .nr-pdf-page canvas { max-width: 100%; margin: 10px auto; border: 1px solid #ddd; } .nr-newline { clear: both; } .nr-spin-90 .nr-pdf-page { transform: rotate(90deg); } .nr-spin-180 .nr-pdf-page { transform: rotate(180deg); } .nr-spin-270 .nr-pdf-page { transform: rotate(270deg); } .wm { position: absolute; z-index: 1; top: 50px; right: 50px; overflow: hidden; pointer-events: none; } .wm2 { opacity: 0.5; max-width: 80%; color: #ff0000; font-weight: 600; font-size: 1.2rem; font-family: "宋体"; margin: 15% 0 0 40%; letter-spacing: -2px; transform: rotate(-5deg); text-shadow: #ff0000 1px 0 0, #ff0000 0 1px 0, #ff0000 -1px 0 0, #ff0000 0 -1px 0; } @media screen and (max-width: 500px) { .wm2 { font-size: 1.1vw; } } .wm2>table { border-collapse: collapse; } .wm2>table tr td { text-align: left; position: relative; white-space: nowrap; padding: 3px 6px 0 3px; border: 5px solid #ff0000; } .wm2 .wm-icon { height: 25px; } .wm2 .wm-title { font-size: 2rem; text-align: center; } .wm2 .wm-sign { position: absolute; height: 150px; top: -50px; } .wm2 .wm-footer { text-align: left; padding-top: 10px; white-space: nowrap; letter-spacing: -2px; }
var pv = { pdfViewer: document.querySelector(".nr-pdf-viewer"), pdfDocument: null, loadUrl: function (url) { pdfjsLib.getDocument(url).promise.then(function (pdfDocument) { pv.pdfDocument = pdfDocument; pv.renderDocument(pv.pdfDocument); }).catch(function (reason) { console.error(reason); }) }, renderDocument: function (pdfDocument) { pv.pdfViewer.innerHTML = ""; //总页数 let pageCount = pdfDocument.numPages; var nrwm = document.querySelector('.nr-watermark'); //构建空页 for (var i = 0; i < pageCount; i++) { //页 let div = document.createElement("div"); div.className = "nr-pdf-page"; div.id = "nr-pdf-page-" + (i + 1); div.innerHTML = '<canvas></canvas>'; //水印 if (nrwm.value == "1") { div.appendChild(wm.two()); } //换行 let nl = document.createElement("div"); nl.className = "nr-newline"; pv.pdfViewer.appendChild(div); pv.pdfViewer.appendChild(nl); } for (let pageIndex = 1; pageIndex <= pageCount; pageIndex++) { pdfDocument.getPage(pageIndex).then(function (pdfPage) { let canvas = document.getElementById("nr-pdf-page-" + pageIndex).firstChild; const viewport = pdfPage.getViewport({ scale: document.querySelector('.nr-size').value * 1 }); canvas.width = viewport.width; canvas.height = viewport.height; const ctx = canvas.getContext("2d"); const renderTask = pdfPage.render({ canvasContext: ctx, viewport, }); return renderTask.promise; }); } }, base64ToUint8Array: function (base64) { var raw = atob(base64); var uint8Array = new Uint8Array(raw.length); for (var i = 0; i < raw.length; i++) { uint8Array[i] = raw.charCodeAt(i); } return uint8Array; }, receiveFiles: function (fn) { //拖拽 "dragleave dragenter dragover".split(' ').forEach(en => { document.addEventListener(en, function (e) { e.stopPropagation(); e.preventDefault(); }) }) document.addEventListener("drop", function (e) { e.preventDefault(); var files = (e.dataTransfer || e.originalEvent.dataTransfer).files; if (files && files.length) { fn(files); } }) } } pv.loadUrl("https://gs.zme.ink/2019/07/06/181724f50f.pdf"); pv.receiveFiles(function (files) { var file = files[0]; if (file.type == "application/pdf") { var r = new FileReader(); r.onload = function (e) { pv.loadUrl(pv.base64ToUint8Array(e.target.result.split(',').pop())); } r.readAsDataURL(file); } }); window.onhashchange = function () { var url = location.hash.substring(1); if (url.includes("://")) { pv.loadUrl(url); } } document.querySelector('.nr-size').onchange = function () { pv.renderDocument(pv.pdfDocument); } document.querySelector('.nr-watermark').onchange = function () { pv.renderDocument(pv.pdfDocument); } document.querySelector('.nr-spin').onchange = function () { console.log(this.value) pv.pdfViewer.classList.remove("nr-spin-90") pv.pdfViewer.classList.remove("nr-spin-180") pv.pdfViewer.classList.remove("nr-spin-270") if (this.value != "0") { pv.pdfViewer.classList.add('nr-spin-' + this.value); } } var wm = { two: function () { var wmbox = document.createElement('div'); wmbox.className = "wm wm2"; wmbox.innerHTML = ` <table> <tr> <td colspan="2"><img class="wm-icon" src="https://img11.360buyimg.com/ddimg/jfs/t1/172605/23/10640/69151/60a7aaa7Eb219c62e/73fcbb83d4a2db76.png" /><div class="wm-title">计量章CALIBRATION</div></td> </tr> <tr> <td>位置 LOCATION</td> <td></td> </tr> <tr> <td>计量结果 CAL RESULT</td> <td>合格PASS/不合格FAIL</td> </tr> <tr> <td>发布标签 DECAL ISSUED</td> <td>是YES/否NO</td> </tr> <tr> <td>系统更新 SYSTEM UPDATED</td> <td>是YES/否NO</td> </tr> <tr> <td>日期 DATE</td> <td></td> </tr> <tr> <td>签字 SIGNATURE</td> <td><div><img class="wm-sign" src="https://img10.360buyimg.com/ddimg/jfs/t1/196646/31/4138/28688/60a7aaa7E8a3d9042/c1f79bcc2afe5ebc.png" /></div></td> </tr> </table> <div class="wm-footer">XFQA-D001-010(23/11/2018)</div> `; return wmbox; } }