Vue 項目使用 pdf.js 及 Elasticpdf 教程

摘要:本文章介紹如何在 Vue 中使用 pdf.js 及基于 pdf.js 的批注開發包 Elasticpdf。簡單 5 步可完成集成部署,包括數據的云端同步,示例代碼完善且簡單,文末有集成代碼分享。

Elasticpdf-快照.png

1. 工具庫介紹與 Demo

1.1 代碼包結構

ElasticPDF基于開源 pdf.js (Demo地址:https://mozilla.github.io/pdf.js/web/viewer.html),增加了多種開箱即用的 PDF 批注功能。代碼包延續了 pdf.js-dist 獨立且完全離線的結構風格,僅增加了用于支持批注的離線 Javascript 代碼,與 pdf.js-dist 一樣可以快速完美集成到任何可以運行Javascript, HTML, CSS 的項目環境中,在公網及內網環境下運行。
項目結構-中文.png

1.2 Elasticpdf 在線 Demo

根據不同的功能及預算需求,有兩個版本的產品可供選擇,兩者僅在最終的批注保存階段有區別,產品 Demo 地址如下:

① 批注合成版: https://demos.libertynlp.com/#/pdfjs-annotation

② 專業批注版: https://www.elasticpdf.com/demo

2. 移動至 Vue 項目

移動 pdf.js 或 Elasticpdf 代碼包到 Vue 項目的 public 文件夾下。
package-position.png

pdf.js 成功導入 Vue 快照
pdfjs-快照.png

3. 導入 viewer.html

① 通過 <iframe> 導入 elasticpdf 或 pdf.js 代碼包中的 viewer.html 文件,注意路徑不要寫錯。

<!-- elasticpdf 示例 -->
<iframe @load='initialPDFEditor()' id='elasticpdf-iframe' src="elasticpdf/web/viewer.html"frameborder="0" width="100%" height="700px"></iframe><!-- pdf.js 示例 -->
<iframe @load='initialPDFEditor()' id='elasticpdf-iframe' src="pdfjs-3.2/web/viewer.html"frameborder="0" width="100%" height="700px"></iframe>

② 將 web 文件夾下 viewer.jsdefaultUrl 默認值置空,否則在第 ① 步中導入 viewer.html 時會默認加載 compressed.tracemonkey-pldi-09.pdf 文件,影響自定義加載文件的流程。Elasticpdf 代碼包中的 viewer.js 已默認修改完成。

// 原 defaultUrl 默認值
defaultOptions.defaultUrl = {value: "compressed.tracemonkey-pldi-09.pdf",kind: OptionKind.VIEWER
};// 置空后默認值
defaultOptions.defaultUrl = {value: "",kind: OptionKind.VIEWER
};

③ 在 Vue 頁面中的 <iframe> onLoad() 函數下調用 initialApp() 函數,由于 pdf.js 和 elasticpdf 中的函數都是在 iframe 的作用域下,因此必須在 iframe load結束可獲取 contentWindow 后再調用。

var elasticpdf_viewer = null;
function initialPDFEditor() {listenPDFEditorMessage();elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;console.log('elasticpdf_viewer', elasticpdf_viewer);var pdf_url="compressed.tracemonkey-pldi-09.pdf";elasticpdf_viewer.initialApp({'language': 'zh-cn', // 交互語言'pdf_url': pdf_url,'member_info': { //用戶信息'id': 'elasticpdf_id','name': 'elasticpdf',},});
}// 監聽 pdf 編輯等各種信息的回調
function listenPDFEditorMessage() {window.addEventListener('message', (e) => {if (e.data.source !== 'elasticpdf') {return;}// pdf 加載結束的回調,可以在此處導入服務器上儲存的批注文件if (e.data.function_name === 'pdfLoaded') {console.log('PDF加載成功');reloadData();}});
}

④ pdf.js 初始化函數如下,主要內容為調用 PDFViewerApplication.open() 打開傳入的文檔鏈接,并使用 loadPdf() 函數監聽文檔是否初始化結束,最后通過 postMessage 廣播加載狀態至 Vue 頁面。

<script type='text/javascript'>//初始化函數function initialApp(paras) {var oriUrl=paras['pdf_url'];PDFViewerApplication.open(oriUrl);interval = setInterval('loadPdf()', 1000);}//監聽文檔是否初始化完成var interval = null;function loadPdf() {if (PDFViewerApplication.pdfDocument == null) {console.info('Loading...');} else {//文檔初始化完成console.log('PDF Load successfully');clearInterval(interval);//廣播信息postPDFData("pdfLoaded", '');}}//廣播 pdf.js 操作狀態信息function postPDFData(function_name,new_content){window.parent.postMessage({"type":0,"source":"elasticpdf",'function_name':function_name,"content":new_content},'*');window.postMessage({"type":0,"source":"elasticpdf",'function_name':function_name,"content":new_content},'*');}
</script>

⑤ 需要注意的是 pdf.js 端和存放 pdf 文件的都要支持跨域,否則會報 CORS 跨域錯誤。具體來說如果服務器是通過 Java 或者 Python 等程序提供文檔,則需要在程序中允許跨域;而如果是 nginx 服務器,則在配置中可以如下設置。

location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Headers *;add_header Access-Control-Expose-Headers  Accept-Ranges,Content-Range;add_header Accept-Ranges bytes;
}

對于 pdf.js 端的跨域,需要在 elasticpdf 或 pdf.js 的 viewer.js 中搜索 HOSTED_VIEWER_ORIGINS 并加入域名。

const HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io"];

4. 導出 pdf 及批注數據

Elasticpdf 所生成批注數據的保存有兩種方式,我們推薦方式二。pdf.js 默認將批注寫入文檔,無法分離保存。

4.1 方式一:批注寫入PDF

將批注寫入到 pdf 中然后下載整個文檔,一般用戶可以通過Ctrl+S快捷鍵和 UI 按鈕來完成,這種方式完全不需要后端服務的支持。

在需要保存批注后 pdf 至服務器的場景中,可以通過如下代碼實現。

// 綁定該函數至 dom 用于觸發 pdf 保存
function getPDFData() {elasticpdf_viewer.getPDFData();
}// 接收pdf數據并且上傳至服務器
window.addEventListener('message', (e) => {if (e.data.source != 'elasticpdf') {return;}// 接收pdf數據if (e.data.function_name == 'downloadPDF') {let file_name = e.data.content['file_name'];let pdf_blob = e.data.content['pdf_blob'];let pdf_base64 = e.data.content['pdf_base64'];// 接收到 pdf 數據,其中 pdf_base64 字符串數據可以快捷上傳到服務器postService('upload-pdf-data', {'file_name':file_name,'file_id':'123ddasfsdffads','file_data':pdf_base64,});}
});

4.1 方式二:批注單獨保存

針對云端同步批注的需求,單獨將批注文件導出為JSON文件,傳輸并保存于服務器,之后加載回顯后可繼續編輯批注。

這樣的方式僅需一個在線PDF原文件,只傳輸很小體積的批注(通常不到 1M 大小),可以節約很多的存儲和寬帶費用。

// 在 pdf 批注編輯后的回調函數中可以讀取所有批注文件并且上傳至服務器
window.addEventListener('message', (e) => {if (e.data.source != 'elasticpdf') {return;}// pdf 批注編輯回調,可以在此處導出批注并傳輸到服務器if (e.data.function_name == 'annotationsModified') {// 僅獲取 pdf 批注文件,不寫入到 pdf 中let this_data = elasticpdf_viewer.pdfAnnotation.outputAnnotations();let annotation_content = JSON.stringify(this_data['file_annotation']);let file_name = this_data['file_name'];postService('upload-annotation-data', {'file_name':file_name,'file_id':'123ddasfsdffads','file_annotation':annotation_content,});}
});

5. 重載 pdf 及批注數據

單獨將 pdf 批注保存至服務器后,可以在加載 pdf 文件后再次從服務器中下載批注并且重載回顯到 pdf 上繼續編輯。

// 在 pdf 加載完成后的回調中可以從服務器請求相應的批注并重載于 pdf 上。
window.addEventListener('message', (e) => {if (e.data.source != 'elasticpdf') {return;}// pdf 加載完成的回調,可以在此處導入服務器上儲存的批注文件if (e.data.function_name == 'pdfLoaded') {let file_name = 'tutorial.pdf'let annotation_content =await postService('get-annotation-data', {'file_name':'tutorial.pdf','file_id':'123ddasfsdffads',});// 批注重載回顯于當前文件elasticpdf_viewer.setPureFileAnnotation({'file_annotation': annotation_content});}
});

以上的所有與服務器的交互需要前后端協同,后端服務器需要響應程序來接收和保存數據,對于 Elasticpdf 的用戶我們有簡單的 PHP、Python 及 Java 代碼示例供參考。

前端發起請求的示例函數 postService() 代碼如下。

// 與后端服務器進行網絡通信的函數
async function postService(url, data) {var new_data = new URLSearchParams();var encrpte_data = data;new_data.append('data', encrpte_data);var base_url = "your-server-url";var posturl = base_url + url;const response = await fetch(posturl, {method: 'POST',headers: {},body: new_data, });const resp = await response.json();resp['data'] = JSON.parse(resp['data']);return resp;
}

總結

至此,pdf.js 及 elasticpdf 集成于 Vue 項目的代碼完畢,帶有 pdf.js 代碼包的 Vue 示例項目包內容已上傳至 Github(網址:https://github.com/ElasticPDF/Vue-use-pdf.js-elasticpdf),可以直接下載。Elasticpdf 客戶如有其他應用場景需求歡迎聯系我們,我們將為您提供示例代碼。

溫馨提示:本文首發于?https://www.elasticpdf.com?,轉載請注明出處:https://www.elasticpdf.com/blog/vue-pdf-annotation-plugin-library-online-api-examples-zh.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76014.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76014.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76014.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

聊聊Spring AI的ChromaVectorStore

序 本文主要研究一下Spring AI的ChromaVectorStore 示例 pom.xml <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-vector-store-chroma</artifactId></dependency>配置 spring:ai:vectorstore:…

整數編碼 - 華為OD統一考試(A卷、Java)

題目描述 實現一種整數編碼方法,使得待編碼的數字越小,編碼后所占用的字節數越小。 編碼規則如下: 編碼時7位一組,每個字節的低7位用于存儲待編碼數字的補碼。字節的最高位表示后續是否還有字節,置1表示后面還有更多的字節,置0表示當前字節為最后一個字節。采用小端序編…

Linux 遞歸查找并刪除目錄下的文件

在 Linux 中&#xff0c;可以使用 find 命令遞歸查找并刪除目錄下的文件 1、示例命令 find /path/to/directory -type f -name "filename_pattern" -exec rm -f {} 2、參數說明 /path/to/directory&#xff1a;要查找的目標目錄type f&#xff1a;表示查找文件&am…

【筆記】VS中C#類庫項目引用另一個類庫項目的方法

VS中C#類庫項目引用另一個類庫項目的方法 在 C# 開發中&#xff0c;有時我們需要在一個類庫項目中引用另一個類庫項目&#xff0c;但另一個項目可能尚未編譯成 DLL。在這種情況下&#xff0c;我們仍然可以通過 Visual Studio 提供的項目引用功能進行依賴管理。 &#x1f3af; …

第五講(下)| string類的模擬實現

string類的模擬實現 一、Member constants&#xff08;成員常數&#xff09;npos 二、Member functions&#xff08;成員函數&#xff09;constructor&#xff08;構造&#xff09;、destructor&#xff08;析構&#xff09;、c_str遍歷1 &#xff1a;Iterators遍歷2&#xff1…

洛谷題單3-P4956 [COCI 2017 2018 #6] Davor-python-流程圖重構

題目描述 在征服南極之后&#xff0c;Davor 開始了一項新的挑戰。下一步是在西伯利亞、格林蘭、挪威的北極圈遠征。 他將在 2018 年 12 月 31 日開始出發&#xff0c;在這之前需要一共籌集 n 元錢。 他打算在每個星期一籌集 x 元&#xff0c;星期二籌集 xk 元&#xff0c;……

【正點原子】如何設置 ATK-DLMP135 開發板 eth0 的開機默認 IP 地址

開機就想讓 eth0 乖乖用靜態 IP&#xff1f;別再被 DHCP 搶走地址了&#xff01; 三步教你徹底掌控 ATK-DLMP135 的網絡啟動配置&#xff0c;簡單粗暴&#xff0c;實測有效&#xff01; 正點原子STM32MP135開發板Linux核心板嵌入式ARM雙千兆以太網CAN 1. 刪除 dhcpcd 自動獲取…

以UE5第三方插件庫為基礎,編寫自己的第三方庫插件,并且能夠在運行時復制.dll

首先&#xff0c;創建一個空白的C 項目&#xff0c;創建第三方插件庫。如下圖所示 編譯自己的.Dll 和.lib 庫&#xff0c;打開.sln 如下圖 ExampleLibrary.h 的代碼如下 #if defined _WIN32 || defined _WIN64 #define EXAMPLELIBRARY_IMPORT __declspec(dllimport) #elif d…

正則表達式示例集合

目錄&#xff1a; 1、精準匹配2、字符匹配3、參考示例3.1、一個合理的用戶名正則表達式3.2、匹配 HTML 標簽及內容3.3、其他示例3.4、微信號正則表達式3.5、QQ號正則表達式3.6、車牌號號正則表達式3.7、郵箱正則表達式 1、精準匹配 單字符模式&#xff0c;如 a&#xff0c;不論…

2025 年前端與后端開發方向的抉擇與展望-優雅草卓伊凡

2025 年前端與后端開發方向的抉擇與展望-優雅草卓伊凡 在 2025 年這個科技浪潮奔涌的時代&#xff0c;軟件開發領域持續變革&#xff0c;前端與后端開發方向的抉擇&#xff0c;成為眾多從業者和愛好者亟待破解的關鍵命題。卓伊凡就頻繁收到這樣的疑問&#xff1a;“2025 年了&…

巧用數論與動態規劃破解包子湊數問題

本文針對“包子湊數”問題&#xff0c;深入解析如何通過最大公約數&#xff08;GCD&#xff09;判斷無法組成的數目是否無限&#xff0c;并結合動態規劃高效求解有限情況下的具體數目。通過清晰的算法思路、代碼實現及示例詳解&#xff0c;揭秘數論與動態規劃在組合問題中的巧妙…

什么是數據

一、數據的本質定義?? ??哲學視角?? 亞里士多德《形而上學》中"未加工的觀察記錄"現代認知科學&#xff1a;人類感知系統接收的原始刺激信號&#xff08;如視網膜光信號、聽覺神經電信號&#xff09;信息論奠基人香農&#xff1a;消除不確定性的度量載體 ??…

FreeRTOS中互斥量實現數據共享優化

在 FreeRTOS 中&#xff0c;當讀操作遠多于寫操作時&#xff0c;使用**互斥量&#xff08;Mutex&#xff09;會導致讀任務頻繁阻塞&#xff0c;降低系統性能。此時&#xff0c;可以通過實現讀者-寫者鎖&#xff08;Reader-Writer Lock&#xff09;**優化&#xff0c;允許多個讀…

國內虛擬電廠(VPP)管控平臺供應商

以下是幾家專注于虛擬電廠業務的供應商及其官網地址&#xff1a; 1. 華茂能聯科技有限公司 官網地址&#xff1a;https://huamod.com/簡介&#xff1a;華茂能聯是分布式資源管理與虛擬電廠產品與服務提供商&#xff0c;團隊匯聚了來自美國、歐洲和國內多個行業知名研究機構或…

協方差相關問題

為什么無偏估計用 ( n ? 1 ) (n-1) (n?1) 而不是 n n n&#xff0c;區別是什么&#xff1f; 在統計學中&#xff0c;無偏估計是指估計量的期望值等于總體參數的真實值。當我們用樣本數據估計總體方差或協方差時&#xff0c;分母使用 ( n ? 1 ) (n-1) (n?1) 而不是 n n…

算法設計學習6

實驗目的及要求&#xff1a; 目標是使學生學會分析數據對象的特點&#xff0c;掌握數據組織的方法和在計算機中的存儲方式&#xff0c;能夠對具體問題中所涉及的數據選擇合適的邏輯結構、存儲結構&#xff0c;進而在此基礎上&#xff0c;對各種具體操作設計高效的算法&#xff…

Java 三大特性—多態

目錄 1、多態的概念2、多態的條件3、向上轉型3.1 概念3.2 使用場景 4、向下轉型5、多態的優缺點 1、多態的概念 多態&#xff0c;通俗來講就是多種形態&#xff0c;即對于同樣的行為&#xff0c;不同的對象去完成會產生不同的狀態。比如動物都會吃東西&#xff0c;小狗和小貓都…

Ubuntu 24.04 LTS系統安裝RTX 4090顯卡驅動和cuda并部署ollama下載DeepSeek模型【自用詳細版】

自己搗鼓玩玩哈&#xff0c;正好有機子 1. 安裝驅動前的系統配置工作 卸載原有驅動并禁用nouveau sudo apt remove --purge nvidia*sudo cp /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf.backup //備份文件sudo vim /etc/modprobe.d/blacklist.conf //修…

【一篇搞定配置】一篇帶你從配置到使用(PyCharm遠程)完成服務器運行項目(配置、使用一條龍)【全網最詳細版】

&#x1f308; 個人主頁&#xff1a;十二月的貓-CSDN博客 &#x1f525; 系列專欄&#xff1a; &#x1f3c0;各種軟件安裝與配置_十二月的貓的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻擋不了春天的腳步&#xff0c;十二點的黑夜遮蔽不住黎明的曙光 目錄 1.…

Mamba模型

為什么要提出mamba模型&#xff1f; transformer特點&#xff1a;訓練快&#xff0c;推理慢&#xff0c;計算成本O&#xff08;n*n&#xff09; Rnn的特點&#xff1a;訓練慢&#xff0c;推理快&#xff0c;容易遺忘 其實很容易理解&#xff0c;因為RNN的輸入只包含前一個隱…