Angular 項目 PDF 批注插件庫在線版 API 示例教程

本文章介紹 Angular 項目中 PDF 批注插件庫 ElasticPDF 在線版 API 示例教程,API 包含 ① 導出批注后PDF數據;② 導出純批注 json 數據;③ 加載舊批注;④ 切換文檔;⑤ 切換用戶;⑥ 清空批注 等數據處理功能,可滿足通常業務需求。本教程可用于月付許可和在線測試版,歡迎 聯系我們 咨詢和獲取接入 key。

封面.png

0 ElasticPDF 產品介紹

ElasticPDF基于開源pdf.js,增加了多種開箱即用的 PDF 批注功能。代碼包延續了 pdf.js-dist 獨立且完全離線的結構風格,僅增加了用于支持批注的離線 Javascript 代碼,可以快速完美集成到任何可以運行Javascript, HTML, CSS 的項目環境中,在公網及內網環境都可以完美的運行。

項目結構-中文.png

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

① 批注合成版: https://demos.libertynlp.com/#/pdfjs-annotation
② 專業批注版: https://www.elasticpdf.com/demo

1 導入頁面 HTML 及初始化

首先將以下代碼導入到目標 HTML頁面,此處為 app.component.html

<div *ngIf='language==="zh-cn"' class='project-title'><img src="https://elasticpdf.com/elasticpdf-image/logo-no-back.png" alt="" /><h2>Angular 項目在線 API 示例教程</h2><a style="cursor: pointer;text-decoration: none;" href='https://www.elasticpdf.com/contact-us.html'target="_blank"><div title='聯系我們獲取測試 key' class='message-div info-message'><i class="fa fa-info-circle" aria-hidden="true"></i><span>獲取測試 key</span></div></a><button style="margin-left: 20px;" class='theme-btn btn-outline-warning'(click)="getPDFData()">獲取PDF數據</button><button class='theme-btn btn-outline-help' (click)="outputAnnotation()">導出批注</button><button class='theme-btn btn-outline-success' (click)="changeFile()">切換文檔</button><button class='theme-btn btn-outline-warning' (click)="setMember('test_id')">切換用戶</button><button class='theme-btn btn-outline-danger' (click)="clearAnnotation()">清空批注</button><button class='theme-btn btn-outline-info' (click)="reloadOldAnnotationData()">加載舊批注</button>
</div>
<div style="width: 100%;height: auto;"><iframe src="https://pdfmaster.libertynlp.com/web/viewer.html?file=tutorial.pdf" id='elasticpdf-iframe' (load)='initialPDFEditor()' width="100%" height="680px" frameborder="0"></iframe>
</div>

再將以下邏輯代碼導入到 app.component.html 對應的 ts 頁面中,此處為 app.component.ts,其中包含了初始化代碼 initialPDFEditor() 和接收所有回報信息的函數,所有導出的 PDF數據,批注數據 都在函數 @HostListener 下,可以與后續的業務融合。

import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { HostListener } from '@angular/core';@Component({selector: 'app-root',standalone: true,imports: [CommonModule, RouterOutlet],templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})export class AppComponent {language:any = 'en';elasticpdf_viewer:any = null;elasticpdf_iframe:any = null;initialPDFEditor() {let languages = navigator.languages as string[];		if (languages[0].toLowerCase().includes('zh')) {this.language = 'zh-cn';// alert(languages);}this.elasticpdf_iframe = document.getElementById('elasticpdf-iframe') as HTMLIFrameElement;// The online version only supports opening online documents// 在線版只支持打開在線文檔let pdf_url = "tutorial.pdf";if (this.elasticpdf_iframe && this.elasticpdf_iframe.contentWindow) {this.elasticpdf_viewer = this.elasticpdf_iframe?.contentWindow as any;this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "initialApp","content": {'language': this.language, // GUI language 交互語言'pdf_url': pdf_url,'member_info': { //Member Info  用戶信息'id': 'elasticpdf_id','name': 'elasticpdf',},}}, '*');}}// Listen for callbacks of various information about PDF editing// 監聽 pdf 編輯各種信息的回調@HostListener('window:message', ['$event'])onMessage(event : Event) : void {const e : any = event;if (e.data.source != 'elasticpdf') {return;}// PDF loading completed callback, you can import the annotation file stored on the server here// pdf 加載結束的回調,可以在此處導入服務器上儲存的批注文件if (e.data.function_name == 'pdfLoaded') {// console.log is invalid, please use alert to print content// console.log 無效,請使用 alert 打印內容// alert('PDF loaded successfully PDF加載成功');this.reloadData();}// PDF annotation export callback, where annotations can be exported and transferred to the server// pdf 批注導出回調,可以在此處導出批注并傳輸到服務器if (e.data.function_name == 'outputAnnotation') {// Only get the PDF annotation data, do not write it into the PDF// 僅獲取 pdf 批注文件,不寫入到 pdf 中let this_data = e.data.content;let annotation_content = JSON.stringify(this_data['file_annotation']);let file_name = this_data['file_name'];// console.log is invalid, please use alert to print content// console.log 無效,請使用 alert 打印內容alert('Annotation data 批注數據\n'+annotation_content);}// PDF annotation editing callback, where annotations can be exported and transferred to the server// pdf 批注編輯回調,可以在此處導出批注并傳輸到服務器if (e.data.function_name == 'annotationsModified') {// Only get the PDF annotation data, do not write it into the PDF// 僅獲取 pdf 批注文件,不寫入到 pdf 中let this_data = e.data.content;let annotation_content = JSON.stringify(this_data['file_annotation']);let file_name = this_data['file_name'];// console.log is invalid, please use alert to print content// alert('annotation modified 批注被修改');this.postService('upload-annotation-data', {'file_name': file_name,'file_id': '123ddasfsdffads','file_annotation': annotation_content,});}// Receive the edited PDF data, and the annotations are written into the PDF// 接收編輯后的pdf數據,批注被寫入 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'];// If the document has not been edited, pdf_base64 is still the file name or file url// Receive pdf data, where pdf_base64 can be quickly uploaded to the server// 如果文檔沒有被編輯過,則 pdf_base64 仍然是文件名或文件鏈接// 接收到 pdf 數據,其中 pdf_base64 可以快捷上傳到服務器this.postService('upload-pdf-data', {'file_name': file_name,'file_id': '123ddasfsdffads','file_data': pdf_base64,});alert('Get the pdf base64 data. Please go to postService function to add the subsequent function.\n\n獲取到 pdf base64 數據,如有需要請到postService中增加業務函數');}}
}

2 調用 API

① 導出批注數據

導出 pdf 批注的 json 數據,可以用于后續的篩選、合并、入庫保存等業務流程,非常適用于在線批注流程,因為只需要保存一個原 pdf 文檔,然后從數據庫中僅加載和回顯批注,可以節省很多的服務器性能、流量和帶寬費用。

// export annotations data 導出可保存的批注對象
outputAnnotation() {this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "outputAnnotation","content": ""}, '*');
}

② 導入舊批注

從服務器中依據文件 ID 或 PDF 鏈接加載 ① 中導出的批注數據并回顯至文檔上,支持再次操作編輯,以此來實現批注數據的云端同步。

// reload old annotation data
// 加載舊批注
reloadOldAnnotationData() {var old_annotation = this.getOldAnnotation();this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "setFileAnnotation","content": old_annotation}, '*');
}// Generate simulated old annotation data
// 生成模擬舊批注數據
getOldAnnotation() {var old_annotation = {"annos-for-page-1": {"page_id": "annos-for-page-1","page_canvas_container": {},"page_annotations": [],"page_canvas": {"fabric_canvas": {"version": "5.2.0","objects": [{"type": "rect","version": "5.2.0","left": 64.38,"top": 159.99,"width": 608.27,"height": 290.3,"fill": "rgba(255,237,0,0.3)","stroke": "rgba(17,153,158,1)","erasable": true}],"background": "rgba(255, 255, 255, 0)"},"width": 994,"height": 1407,"fabric_canvas_json": {"version": "5.2.0","objects": [{"type": "rect","version": "5.2.0","left": 64.38,"top": 159.99,"width": 608.27,"height": 290.3,"fill": "rgba(255,237,0,0.3)","stroke": "rgba(17,153,158,1)","erasable": true,"id": "1742436474916_1","hasControls": true,"hasBorders": true,"selectable": true,"lockMovementX": false,"lockMovementY": false,"member_id": "elasticpdf_id","member_name": "elasticpdf","my_type": "rectangle","comment": "添加批注","backup_opacity": 1,"lockRotation": false}],"background": "rgba(255, 255, 255, 0)"}}}}return JSON.stringify(old_annotation);
}

③ 導出 PDF 文件

將批注合并到批注文件并導出批注后 PDF 文檔 base64 數據,可以直接入庫保存。

// export edited pdf data
// 導出批注編輯后pdf數據
getPDFData() {this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "getPDFData","content": ""}, '*');
}

④ 切換和打開文檔

打開在線文檔,其中文件服務器或站點需要允許 CORS 跨域,否則加載文檔會失敗。

// You can change test_pdf with any online pdf url
// The file server needs to be configured to allow cross-domain
// 切換打開的文檔,可以把 test_pdf 換成任意在線pdf鏈接
// 文件服務器需要配置允許跨域
changeFile() {var test_pdf = 'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf';this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "openFile","content": test_pdf}, '*');
}

⑤ 設置用戶信息

設置插件內當前操作用戶的 ID 和用戶名,這些信息會被記錄到每個批注中,后續可以用于做權限差異設置,例如是否允許當前用戶操作他人批注。

// set member info including id and name
// 設置用戶的 id 和 name
setMember(id:string) {var this_member = {'id': 'test-id','name': 'test-name',};this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "setMember","content": this_member}, '*');
}

⑥ 清空批注數據

將當前文檔對應的操作批注完全清空。

// clear all annotations
// 清空批注
clearAnnotation() {this.elasticpdf_viewer.postMessage({"source": "test-elasticpdf","function_name": "clearFileAnnotation","content": ""}, '*');
}

總結

至此,elasticpdf 在線測試版集成于 Angular 項目并調用數據業務 API 的代碼介紹完畢,測試代碼文件已上傳至 Github(網址:https://github.com/ElasticPDF/Angular-use-pdf.js-elasticpdf),歡迎聯系我們咨詢和獲取 Key。

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

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

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

相關文章

Spring Boot 中利用 Jasypt 實現數據庫字段的透明加密解密

1. 引言 1.1 什么是 Jasypt Jasypt(Java Simplified Encryption)是一個用于簡化 Java 應用程序中加密操作的庫。 1.2 為什么使用 Jasypt 簡化加密操作:提供簡單的 API 進行加密和解密。透明加密:自動處理加密和解密過程,無需手動干預。多種加密算法:支持多種加密算法,…

Linux的: /proc/sys/net/ipv6/conf/ 筆記250405

Linux的: /proc/sys/net/ipv6/conf/ /proc/sys/net/ipv6/conf/ 是 Linux 系統中用于 動態配置 IPv6 網絡接口參數 的核心目錄。它允許針對不同網絡接口&#xff08;如 eth0、wlan0&#xff09;或全局設置&#xff08;all&#xff09;調整 IPv6 協議棧的行為。 它通過虛擬文件系…

Spring Cloud 框架為什么能處理高并發

Spring Cloud框架能夠有效處理高并發場景&#xff0c;核心在于其微服務架構設計及多組件的協同作用&#xff0c;具體機制如下&#xff1a; 一、分布式架構設計支撐高擴展性 服務拆分與集群部署 Spring Cloud通過微服務拆分將單體系統解耦為獨立子服務&#xff0c;每個服務可獨…

無人機智慧路燈桿:智慧城市的‘全能助手’

在城市發展的進程中&#xff0c;智慧路燈桿作為智慧城市建設的關鍵載體&#xff0c;正逐步從傳統的照明設備轉型為集多種功能于一體的智能基礎設施。無人機與智慧路燈桿的創新性融合&#xff0c;為城市管理和服務帶來了全新的變革與機遇。 一、無人機智慧路燈桿的功能概述 照…

Libevent UDP開發指南

UDP 與 TCP 的核心區別 無連接:不需要建立/維護連接 不可靠:不保證數據包順序和到達 高效:頭部開銷小,沒有連接管理負擔 支持廣播/多播:可以向多個目標同時發送數據 一、基礎UDP服務器實現 1. 創建 UDP 套接字 #include <event2/event.h> #include <event2/lis…

基于阿里云可觀測產品構建企業級告警體系的通用路徑與最佳實踐

前言 1.1 日常生活中的告警 任何連續穩定運行的生產系統都離不開有效的監控與報警機制。通過監控&#xff0c;我們可以實時掌握系統和業務的運行狀態&#xff1b;而報警則幫助我們及時發現并響應監控指標及業務中的異常情況。 在日常生活中&#xff0c;我們也經常遇到各種各樣…

智能多媒體處理流水線——基于虎躍辦公API的自動化解決方案

在內容爆炸的時代&#xff0c;多媒體文件處理&#xff08;圖片壓縮、視頻轉碼、音頻降噪&#xff09;已成為內容生產者的日常挑戰。本文將演示如何基于虎躍辦公的多媒體處理API&#xff0c;構建自動化處理流水線&#xff0c;實現&#xff1a; 批量文件智能分類格式自動轉換質量…

01-STM32(介紹、工具準備、新建工程)p1-4

文章目錄 工具準備和介紹硬件設備stm32簡介和arm簡介stm32簡介STM32命名規則STM32選型STM32F103C8T6最小系統板引腳定義STM32啟動配置STM32最小系統電路ARM簡介 軟件安裝注冊器件支持包安裝ST-LINK驅動安裝USB轉串口驅動 新建工程創建stm32工程STM32工程編譯和下載型號分類及縮…

【ABAP】REST/HTTP技術(一)

1、概念 1.1、SAP 如何提供 Http Service 如果要將 SAP 應用程序服務器 &#xff08;application server&#xff09;作為 http 服務提供者&#xff0c;需要定義一個類&#xff0c;這個類必須實現 IF_HTTP_EXTENSION 接口。IF_HTTP_EXTENSION 接口只有一個方法 HANDLE_REQUEST。…

[實戰] linux驅動框架與驅動開發實戰

linux驅動框架與驅動開發實戰 Linux驅動框架與驅動開發實戰一、Linux驅動框架概述1.1 Linux驅動的分類1.2 Linux驅動的基本框架 二、Linux驅動關鍵API詳解2.1 模塊相關API2.2 字符設備驅動API2.3 內存管理API2.4 中斷處理API2.5 PCI設備驅動API 三、Xilinx XDMA驅動開發詳解3.1…

1. hadoop 集群的常用命令

1.上傳文件 1)hadoop fs -put words.txt /path/to/input/ 2)hdfs dfs -put words.txt /path/wc/input/ 2.獲取hdfs中的文件 hadoop fs -get /path/wc/input/words.txt 3.合并下載多個文件 hadoop fs -getmerge /path/wc/input/words.txt /path/wc/input/words2.txt 4.查…

Keepalived+LVS+nginx高可用架構

注明&#xff1a;所有軟件已經下載好&#xff0c;防火墻和SELinux已經全部關閉 一.搭建NFS 1.服務端 1.創建文件 [rootnfs ~]# mkdir -p /nfs/data 2、修改權限 [rootnfs ~]# chmod orw /nfs/data 3、寫配置文件 [rootnfs ~]# cat /etc/exports /nfs/data 192.168.111.118(r…

深度學習處理文本(13)

我們使用基于GRU的編碼器和解碼器來在Keras中實現這一方法。選擇GRU而不是LSTM&#xff0c;會讓事情變得簡單一些&#xff0c;因為GRU只有一個狀態向量&#xff0c;而LSTM有多個狀態向量。首先是編碼器&#xff0c;如代碼清單11-28所示。 代碼清單11-28 基于GRU的編碼器 fro…

HashMap 底層原理詳解

1. 核心數據結構 JDK 1.7 及之前&#xff1a;數組 鏈表 JDK 1.8 及之后&#xff1a;數組 鏈表/紅黑樹&#xff08;鏈表長度 ≥8 時轉紅黑樹&#xff0c;≤6 時退化為鏈表&#xff09; // JDK 1.8 的 Node 定義&#xff08;鏈表節點&#xff09; static class Node<K,V&g…

使用MySQL時出現 Ignoring query to other database 錯誤

Ignoring query to other database 錯誤 當在遠程連接軟件中輸入MySQL命令出現該錯誤 導致錯誤原因是&#xff1a;登錄mysql時賬戶名沒有加上u 如果出現該錯誤&#xff0c;退出mysql&#xff0c;重新輸入正確格式進入即可&#xff01;

哈爾濱工業大學:大模型時代的具身智能

大家好&#xff0c;我是櫻木。 機器人在工業領域&#xff0c;已經逐漸成熟。具身容易&#xff0c;智能難。 機器人-》智能機器人&#xff0c;需要自主能力&#xff0c;加上通用能力。 智能機器人-》人類&#xff0c;這個階段就太有想象空間了。而最受關注的-類人機器人。 如何…

Javascript代碼壓縮混淆工具terser詳解

原始的JavaScript代碼在正式的服務器上,如果沒有進行壓縮,混淆,不僅加載速度比較慢,而且還存在安全和性能問題. 因此現在需要進行壓縮,混淆處理. 處理方案簡單描述一下: 1. 使用 terser 工具進行 安裝 terser工具: # npm 安裝 npm install terser --save-dev# 或使用 yarn 安…

Java String 常用方法詳解

目錄 一、獲取字符串信息(一)獲取字符串長度(二)獲取指定索引處的字符(三)獲取子字符串二、字符串比較(一)比較字符串內容(二)忽略大小寫比較三、字符串轉換(一)轉換為大寫(二)轉換為小寫四、字符串查找(一)查找子字符串的位置(二)從指定位置開始查找五、字符…

Linux驅動開發練習案例

1 開發目標 1.1 架構圖 操作系統&#xff1a;基于Linux5.10.10源碼和STM32MP157開發板&#xff0c;完成tf-a(FSBL)、u-boot(SSBL)、uImage、dtbs的裁剪&#xff1b; 驅動層&#xff1a;為每個外設配置DTS并且單獨封裝外設驅動模塊。其中電壓ADC測試&#xff0c;采用linux內核…

leetcode-代碼隨想錄-哈希表-贖金信

題目 題目鏈接&#xff1a;383. 贖金信 - 力扣&#xff08;LeetCode&#xff09; 給你兩個字符串&#xff1a;ransomNote 和 magazine &#xff0c;判斷 ransomNote 能不能由 magazine 里面的字符構成。 如果可以&#xff0c;返回 true &#xff1b;否則返回 false 。 maga…