使用pdf-lib.js實現(xiàn)pdf添加自定義水印功能
項目介紹
pdf-lib是一個強大的JavaScript庫,允許在任何JavaScript環(huán)境中創(chuàng)建和修改PDF文檔。無論是前端瀏覽器環(huán)境還是Node.js服務(wù)器端,它都能提供全面的功能來滿足你的需求。
快速啟動
要開始使用pdf-lib,首先確保你已經(jīng)安裝了相應(yīng)的npm包。在命令行中運行以下命令:
npm install --save pdf-lib
或者如果你是yarn的使用者:
yarn add pdf-lib
實現(xiàn)代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>PDF Watermark Example</title> <script src="https://cdn.bootcdn.net/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script> </head> <body> <input type="file" id="pdfFile" accept="application/pdf"> <button onclick="addWatermark()">添加水印</button> <a id="downloadLink" style="display:none;">下載PDF</a> <script> async function addWatermark() { const fileInput = document.getElementById('pdfFile'); const file = fileInput.files[0]; if (!file) { alert('請選擇一個PDF文件'); return; } const arrayBuffer = await file.arrayBuffer(); const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer); const pages = pdfDoc.getPages(); // 獲取當前時間并格式化 const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hour = String(now.getHours()).padStart(2, '0'); const minute = String(now.getMinutes()).padStart(2, '0'); // 創(chuàng)建水印 const watermarkText = `無敵暴龍獸-${year}-${month}-${day}-${hour}:${minute}-加密`; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const fontSize = 20; const textColor = 'rgba(0, 0, 0, 0.2)'; // 計算文本寬度和高度 ctx.font = `${fontSize}px Arial`; const textMetrics = ctx.measureText(watermarkText); const textWidth = textMetrics.width; const textHeight = fontSize; // 計算旋轉(zhuǎn)后的文本邊界 const angle = -Math.PI / 4; // 旋轉(zhuǎn)45度 const rotatedWidth = Math.abs(textWidth * Math.cos(angle)) + Math.abs(textHeight * Math.sin(angle)); const rotatedHeight = Math.abs(textHeight * Math.cos(angle)) + Math.abs(textWidth * Math.sin(angle)); // 設(shè)置Canvas大小 canvas.width = rotatedWidth + 20; // 增加一些邊距 canvas.height = rotatedHeight + 20; // 繪制水印文本 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.translate(canvas.width / 2, canvas.height / 2); ctx.rotate(angle); ctx.font = `${fontSize}px Arial`; ctx.fillStyle = textColor; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(watermarkText, 0, 0); // 將Canvas轉(zhuǎn)換為Image對象 const image = new Image(); image.src = canvas.toDataURL('image/png'); // 添加水印到每一頁PDF for (const page of pages) { const { width, height } = page.getSize(); // 計算新的水印尺寸,以便它可以跨越頁面的兩個相鄰邊緣 const cornerMargin = 50; // 角落與頁面邊緣之間的最小距離 const cornerSizeMultiplier = 0.5; // 控制水印相對于頁面尺寸的比例 const scale = 1; // 水印縮放比例 const cornerWidth = Math.min(width, height) * cornerSizeMultiplier * scale; const cornerHeight = cornerWidth; // 假設(shè)是正方形水印 // 計算水印的新位置,使其跨越頁面的兩個相鄰邊緣 const positions = [ { x: cornerMargin, y: cornerMargin }, // 左上角 { x: width - cornerWidth - cornerMargin, y: cornerMargin }, // 右上角 { x: cornerMargin, y: height - cornerHeight - cornerMargin }, // 左下角 { x: width - cornerWidth - cornerMargin, y: height - cornerHeight - cornerMargin } // 右下角 ]; // 需要重新創(chuàng)建水印圖像以匹配新尺寸 const newCanvas = document.createElement('canvas'); const newCtx = newCanvas.getContext('2d'); newCanvas.width = cornerWidth; newCanvas.height = cornerHeight; // 復(fù)制舊水印到新畫布 newCtx.drawImage(canvas, 0, 0, cornerWidth, cornerHeight); // 將新畫布轉(zhuǎn)換回Image對象 const newImage = new Image(); newImage.src = newCanvas.toDataURL('image/png'); // 嵌入新水印到PDF文檔 const newImg = await pdfDoc.embedPng(newImage.src); for (const pos of positions) { page.drawImage(newImg, { x: pos.x, y: pos.y, width: newImg.width, height: newImg.height, }); } } // 保存修改后的PDF const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true }); const downloadLink = document.getElementById('downloadLink'); downloadLink.href = pdfDataUri; downloadLink.download = 'watermarked.pdf'; downloadLink.click(); } </script> </body> </html>
效果圖
到此這篇關(guān)于使用pdf-lib.js實現(xiàn)pdf添加自定義水印功能的文章就介紹到這了,更多相關(guān)pdf-lib實現(xiàn)pdf添加自定義水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript發(fā)送短信驗證碼實現(xiàn)代碼
我們在注冊賬號,或者是參加活動時,都會向手機發(fā)送收短信驗證碼,短信驗證碼到底是如何實現(xiàn)的,本文為大家揭曉,并為大家分項1javascript發(fā)送短信驗證碼實現(xiàn)代碼,感興趣的小伙伴們可以參考一下2015-11-11js中關(guān)于new Object時傳參的一些細節(jié)分析
這里討論給Object傳參時,其內(nèi)部的處理。參考:ECMA262 V5 15.2.2.12011-03-03淺析JS中的 map, filter, some, every, forEach, for in, for of 用法總
本文是小編給大家總結(jié)的關(guān)于javascript中的map, filter, some, every, forEach, for in, for of 用法,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-03-03基于Bootstrap模態(tài)對話框只加載一次 remote 數(shù)據(jù)的解決方法
下面小編就為大家?guī)硪黄贐ootstrap模態(tài)對話框只加載一次 remote 數(shù)據(jù)的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07微信jssdk踩坑之簽名錯誤invalid signature
這篇文章主要介紹了微信jssdk踩坑之簽名錯誤invalid signature,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2020-05-05Javascript 原型和繼承(Prototypes and Inheritance)
前面我們看到了如何使用 constructor 來初始化對象。如果這樣做,那么每一個創(chuàng)建的新對象都會對那些相同的屬性,方法建立一個獨立的副本。而實際上有更加有效的方法來指定方法,常量,以及其他一些可被所有該類的對象共享的屬性。2009-04-04