IT评测·应用市场-qidao123.com技术社区

标题: Vue 项目利用 pdf.js 及 Elasticpdf 教程 [打印本页]

作者: 兜兜零元    时间: 2025-4-8 17:19
标题: Vue 项目利用 pdf.js 及 Elasticpdf 教程
摘要:本文章先容如安在 Vue 中利用 pdf.js 及基于 pdf.js 的批注开发包 Elasticpdf。简单 5 步可完成集成摆设,包罗数据的云端同步,示例代码美满且简单,文末有集成代码分享。

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 的项目环境中,在公网及内网环境下运行。

1.2 Elasticpdf 在线 Demo

根据不同的功能及预算需求,有两个版本的产物可供选择,两者仅在最终的批注保存阶段有区别,产物 Demo 地址如下:
① 批注合成版: https://demos.libertynlp.com/#/pdfjs-annotation
② 专业批注版: https://www.elasticpdf.com/demo
2. 移动至 Vue 项目

移动 pdf.js 或 Elasticpdf 代码包到 Vue 项目的 public 文件夹下。

pdf.js 乐成导入 Vue 快照

3. 导入 viewer.html

① 通过 <iframe> 导入 elasticpdf 或 pdf.js 代码包中的 viewer.html 文件,注意路径不要写错。
  1. <!-- elasticpdf 示例 -->
  2. <iframe @load='initialPDFEditor()' id='elasticpdf-iframe' src="elasticpdf/web/viewer.html"
  3.         frameborder="0" width="100%" height="700px"></iframe>
  4. <!-- pdf.js 示例 -->
  5. <iframe @load='initialPDFEditor()' id='elasticpdf-iframe' src="pdfjs-3.2/web/viewer.html"
  6.         frameborder="0" width="100%" height="700px"></iframe>
复制代码
② 将 web 文件夹下 viewer.js 中 defaultUrl 默认值置空,否则在第 ① 步中导入 viewer.html 时会默认加载 compressed.tracemonkey-pldi-09.pdf 文件,影响自定义加载文件的流程。Elasticpdf 代码包中的 viewer.js 已默认修改完成。
  1. // 原 defaultUrl 默认值
  2. defaultOptions.defaultUrl = {
  3.   value: "compressed.tracemonkey-pldi-09.pdf",
  4.   kind: OptionKind.VIEWER
  5. };
  6. // 置空后默认值
  7. defaultOptions.defaultUrl = {
  8.   value: "",
  9.   kind: OptionKind.VIEWER
  10. };
复制代码
③ 在 Vue 页面中的 <iframe> onLoad() 函数下调用 initialApp() 函数,由于 pdf.js 和 elasticpdf 中的函数都是在 iframe 的作用域下,因此必须在 iframe load结束可获取 contentWindow 后再调用。
  1. var elasticpdf_viewer = null;
  2. function initialPDFEditor() {
  3.         listenPDFEditorMessage();
  4.         elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
  5.         console.log('elasticpdf_viewer', elasticpdf_viewer);
  6.         var pdf_url="compressed.tracemonkey-pldi-09.pdf";
  7.         elasticpdf_viewer.initialApp({
  8.                 'language': 'zh-cn', // 交互语言
  9.                 'pdf_url': pdf_url,
  10.                 'member_info': { //用户信息
  11.                         'id': 'elasticpdf_id',
  12.                         'name': 'elasticpdf',
  13.                 },
  14.         });
  15. }
  16.        
  17. // 监听 pdf 编辑等各种信息的回调
  18. function listenPDFEditorMessage() {
  19.         window.addEventListener('message', (e) => {
  20.                 if (e.data.source !== 'elasticpdf') {
  21.                         return;
  22.                 }
  23.                 // pdf 加载结束的回调,可以在此处导入服务器上储存的批注文件
  24.                 if (e.data.function_name === 'pdfLoaded') {
  25.                         console.log('PDF加载成功');
  26.                         reloadData();
  27.                 }
  28.         });
  29. }
复制代码
④ pdf.js 初始化函数如下,主要内容为调用 PDFViewerApplication.open() 打开传入的文档链接,并利用 loadPdf() 函数监听文档是否初始化结束,最后通过 postMessage 广播加载状态至 Vue 页面。
  1. <script type='text/javascript'>
  2.         //初始化函数
  3.         function initialApp(paras) {
  4.                 var oriUrl=paras['pdf_url'];
  5.                 PDFViewerApplication.open(oriUrl);
  6.                 interval = setInterval('loadPdf()', 1000);
  7.         }
  8.        
  9.         //监听文档是否初始化完成
  10.         var interval = null;
  11.         function loadPdf() {
  12.                 if (PDFViewerApplication.pdfDocument == null) {
  13.                         console.info('Loading...');
  14.                 } else {
  15.                         //文档初始化完成
  16.                         console.log('PDF Load successfully');
  17.                         clearInterval(interval);
  18.                         //广播信息
  19.                         postPDFData("pdfLoaded", '');
  20.                 }
  21.         }
  22.        
  23.         //广播 pdf.js 操作状态信息
  24.         function postPDFData(function_name,new_content){
  25.                 window.parent.postMessage({"type":0,"source":"elasticpdf",'function_name':function_name,"content":new_content},'*');
  26.                 window.postMessage({"type":0,"source":"elasticpdf",'function_name':function_name,"content":new_content},'*');
  27.         }
  28. </script>
复制代码
⑤ 必要注意的是 pdf.js 端和存放 pdf 文件的都要支持跨域,否则会报 CORS 跨域错误。具体来说如果服务器是通过 Java 大概 Python 等步伐提供文档,则必要在步伐中允许跨域;而如果是 nginx 服务器,则在设置中可以如下设置。
  1. location / {
  2.         add_header Access-Control-Allow-Origin *;
  3.         add_header Access-Control-Allow-Headers *;
  4.         add_header Access-Control-Expose-Headers  Accept-Ranges,Content-Range;
  5.         add_header Accept-Ranges bytes;
  6. }
复制代码
对于 pdf.js 端的跨域,必要在 elasticpdf 或 pdf.js 的 viewer.js 中搜索 HOSTED_VIEWER_ORIGINS 并参加域名。
  1. 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 至服务器的场景中,可以通过如下代码实现。
  1. // 绑定该函数至 dom 用于触发 pdf 保存
  2. function getPDFData() {
  3.         elasticpdf_viewer.getPDFData();
  4. }
  5. // 接收pdf数据并且上传至服务器
  6. window.addEventListener('message', (e) => {
  7.         if (e.data.source != 'elasticpdf') {
  8.                 return;
  9.         }
  10.         // 接收pdf数据
  11.         if (e.data.function_name == 'downloadPDF') {
  12.                 let file_name = e.data.content['file_name'];
  13.                 let pdf_blob = e.data.content['pdf_blob'];
  14.                 let pdf_base64 = e.data.content['pdf_base64'];
  15.                
  16.                 // 接收到 pdf 数据,其中 pdf_base64 字符串数据可以快捷上传到服务器
  17.                 postService('upload-pdf-data', {
  18.                         'file_name':file_name,
  19.                         'file_id':'123ddasfsdffads',
  20.                         'file_data':pdf_base64,
  21.                 });
  22.         }
  23. });
复制代码
4.1 方式二:批注单独保存

针对云端同步批注的需求,单独将批注文件导出为JSON文件,传输并保存于服务器,之后加载回显后可继续编辑批注。
如许的方式仅需一个在线PDF原文件,只传输很小体积的批注(通常不到 1M 大小),可以节约很多的存储和宽带费用。
  1. // 在 pdf 批注编辑后的回调函数中可以读取所有批注文件并且上传至服务器
  2. window.addEventListener('message', (e) => {
  3.         if (e.data.source != 'elasticpdf') {
  4.                 return;
  5.         }
  6.         // pdf 批注编辑回调,可以在此处导出批注并传输到服务器
  7.         if (e.data.function_name == 'annotationsModified') {
  8.                 // 仅获取 pdf 批注文件,不写入到 pdf 中
  9.                 let this_data = elasticpdf_viewer.pdfAnnotation.outputAnnotations();
  10.                 let annotation_content = JSON.stringify(this_data['file_annotation']);
  11.                 let file_name = this_data['file_name'];
  12.                 postService('upload-annotation-data', {
  13.                         'file_name':file_name,
  14.                         'file_id':'123ddasfsdffads',
  15.                         'file_annotation':annotation_content,
  16.                 });
  17.         }
  18. });
复制代码
5. 重载 pdf 及批注数据

单独将 pdf 批注保存至服务器后,可以在加载 pdf 文件后再次从服务器中下载批注而且重载回显到 pdf 上继续编辑。
  1. // 在 pdf 加载完成后的回调中可以从服务器请求相应的批注并重载于 pdf 上。
  2. window.addEventListener('message', (e) => {
  3.         if (e.data.source != 'elasticpdf') {
  4.                 return;
  5.         }
  6.         // pdf 加载完成的回调,可以在此处导入服务器上储存的批注文件
  7.         if (e.data.function_name == 'pdfLoaded') {
  8.                 let file_name = 'tutorial.pdf'
  9.                 let annotation_content =await postService('get-annotation-data', {
  10.                         'file_name':'tutorial.pdf',
  11.                         'file_id':'123ddasfsdffads',
  12.                 });
  13.                 // 批注重载回显于当前文件
  14.                 elasticpdf_viewer.setPureFileAnnotation({
  15.                         'file_annotation': annotation_content
  16.                 });
  17.         }
  18. });
复制代码
以上的所有与服务器的交互必要前后端协同,后端服务器必要相应步伐来接收和保存数据,对于 Elasticpdf 的用户我们有简单的 PHP、Python 及 Java 代码示例供参考。
前端发起哀求的示例函数 postService() 代码如下。
  1. // 与后端服务器进行网络通信的函数
  2. async function postService(url, data) {
  3.         var new_data = new URLSearchParams();
  4.         var encrpte_data = data;
  5.         new_data.append('data', encrpte_data);
  6.        
  7.         var base_url = "your-server-url";
  8.         var posturl = base_url + url;
  9.         const response = await fetch(posturl, {
  10.                 method: 'POST',
  11.                 headers: {},
  12.                 body: new_data,
  13.         });
  14.        
  15.         const resp = await response.json();
  16.         resp['data'] = JSON.parse(resp['data']);
  17.        
  18.         return resp;
  19. }
复制代码
总结

至此,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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4