Uni-app PDF Annotation plugin library online API examples

news2025/5/10 19:32:36

This article introduces the online version of the ElasticPDF API tutorial for the PDF annotation plug-in library in Uni-app projects. The API includes ① Export edited PDF data; ② Export annotations json data; ③ Reload old annotations; ④ Change files; ⑤ Set member info; ⑥ Clear annotations and other data processing functions to meet common business needs. This tutorial can be used for monthly licenses and online trial versions. Welcome Contact us for consultation and obtain trial keys.

poster.png

0 ElasticPDF Introduction

ElasticPDF is based on the open source pdf.js (Demo:https://mozilla.github.io/pdf.js/web/viewer.html) and adds a variety of out-of-the-box PDF annotation features. The code package continues the independent and completely offline structure style of pdf.js-dist, and only adds offline Javascript code to support annotations. It can be quickly and perfectly integrated into any project environment that can run Javascript, HTML, and CSS, and run perfectly in both public and intranet environments.

Project-Structure.png

For the different features and budget requirements, there are two versions of the products, they are only differ in the final annotation saving stage, demos are as follows:

① Annotation synthesis version: https://demos.libertynlp.com/#/pdfjs-annotation
② Professional annotation version: https://www.elasticpdf.com/demo

1 Import Viewer HTML and Initial

First, import the following HTML code into the target page, which includes the initialization code initialPDFEditor() and the function listenPDFEditorMessage() that receives all feedback information. All exported PDF data and annotation data are under the function listenPDFEditorMessage() and can be integrated with subsequent functions.

<template>
	<view class="content">
		<div v-if='language=="en"' class='project-title'>
			<img src="https://elasticpdf.com/elasticpdf-image/logo-no-back.png" alt="" />
			<h2> Uni-app project Online API Examples</h2>
			<a style="cursor: pointer;text-decoration: none;" href='https://www.elasticpdf.com/contact-us.html'
				target="_blank">
				<div title='contact us for trial key' class='message-div info-message'>
					<i class="fa fa-info-circle" aria-hidden="true"></i>
					<span>Get trial key</span>
				</div>
			</a>
			<button class='theme-btn btn-outline-warning'
				@click="getPDFData()">Get PDF Data</button>
			<button class='theme-btn btn-outline-help' @click="outputAnnotation()">Export Annotations</button>
			<button class='theme-btn btn-outline-success' @click="changeFile()">Change File</button>
			<button class='theme-btn btn-outline-warning' @click="setMember()">Change User</button>
			<button class='theme-btn btn-outline-danger' @click="clearAnnotation()">Clear</button>
			<button class='theme-btn btn-outline-info' @click="reloadOldAnnotationData()">Reload Annotations</button>
		</div>
		<web-view id='elasticpdf-iframe'
			src="https://pdfmaster.libertynlp.com/web/viewer.html?file=tutorial.pdf"
			style="position: relative; width: 100%; height: 660px;"></web-view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello',
				language:'en',
			}
		},
		onLoad() {
			var that = this;
			let count = 0;
			
			const userLang = navigator.languages;
			// alert('userLang'+userLang);
			if (userLang[0].toLowerCase().includes('zh')) {
				this.language='zh-cn';
			}
			
			const timer = setInterval(function() {
				const iframe = document.getElementById('elasticpdf-iframe');

				if (iframe) {
					clearInterval(timer);
					that.initialPDFEditor();
				} else {
					count++;
					if (count >= 30) { // 最多尝试 10 次
						clearInterval(timer);
						console.warn('未检测到 iframe,已停止尝试');
					}
				}
			}, 1000);
		},
		methods: {
			initialPDFEditor() {
				// Listen for callbacks of various information about PDF editing
				// 监听 pdf 编辑各种信息的回调
				this.listenPDFEditorMessage();
				var elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
				// The online version only supports opening online documents
				// 在线版只支持打开在线文档
				var pdf_url = 'tutorial.pdf';
				elasticpdf_viewer.postMessage({
					"source": "test-elasticpdf",
					"function_name": "initialApp",
					"content": {
						'language': this.language, // 交互语言
						'pdf_url': pdf_url,
						'member_info': { //用户信息
							'id': 'elasticpdf_id',
							'name': 'elasticpdf',
						},
					}
				}, '*');
			},
			
			// For security reasons, console output has been disabled by the test website and cannot use console.log to print out content
			// Please use alert to print content
			// 出于安全考虑, 控制台输出已被测试网站禁用无法使用 console.log 打印出内容
			// 请用 alert 打印内容
			listenPDFEditorMessage() {
				window.addEventListener('message', (e) => {
					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 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,
						});
					}

					// 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);
					}


					// 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中增加业务函数');
					}
				});
			}
		}
	}
</script>

2 Call APIs

① Export annotation data

The json data of the exported PDF annotations can be used for subsequent business processes such as filtering, merging, storage and saving. It is very suitable for online annotation application, because you only need to save an original PDF document, and then reload only the annotations from the database, which can save a lot of server, internet and bandwidth costs.

// export annotations data 导出可保存的批注对象
outputAnnotation() {
	var elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
	elasticpdf_viewer.postMessage({
		"source": "test-elasticpdf",
		"function_name": "outputAnnotation",
		"content": ""
	}, '*');
},

② Import old annotations

Load the annotation data exported in ① from the server according to the file ID or PDF link and reshow it on the document, supporting continuely editing, so as to achieve cloud synchronization of annotation data.

// reload old annotation data
// 加载旧批注
reloadOldAnnotationData() {
	var elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
	var old_annotation = this.getOldAnnotation();
	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);
},

③ Export Edited PDF file

Export edited PDF file after merging the annotations into it, the base64 PDF data can be directly saved in the database.

// export edited pdf data
// 导出批注编辑后pdf数据
getPDFData() {
	var elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
	elasticpdf_viewer.postMessage({
		"source": "test-elasticpdf",
		"function_name": "getPDFData",
		"content": ""
	}, '*');
},

④ Change and open files

Open online documents, where the file server or file site needs to allow CORS, otherwise the document loading will fail.

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

⑤ Set member information

Set userID and userName of current user in elasticpdf. This information will be recorded in each annotation and can be used to set permissions, such as whether the current user is allowed to edit other people’s annotations.

// set member info including id and name
// 设置用户的 id 和 name
setMember(id) {
	var elasticpdf_viewer = document.getElementById('elasticpdf-iframe').contentWindow;
	var this_member = {
		'id': 'test-id',
		'name': 'test-name',
	};
	elasticpdf_viewer.postMessage({
		"source": "test-elasticpdf",
		"function_name": "setMember",
		"content": this_member
	}, '*');
},

⑥ Clear annotation data

Clear the annotations of current document.

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

Summary

So far, the code for integrating the elasticpdf online trial version into Uni-app projects and calling the data business API has been introduced. The test code file has been uploaded to Github (URL: https://github.com/ElasticPDF/uniapp-use-pdf.js-elasticpdf). You are welcome to contact us for consultation and to obtain the key.

Tips: This article was first published on https://www.elasticpdf.com ,Please indicate the source when republishing: https://www.elasticpdf.com/blog/uniapp-pdf-annotation-plugin-library-online-api-examples.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327698.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringKafka消息发布:KafkaTemplate与事务支持

文章目录 引言一、KafkaTemplate基础二、消息序列化三、事务支持机制四、错误处理与重试五、性能优化总结 引言 在现代分布式系统架构中&#xff0c;Apache Kafka作为高吞吐量的消息系统&#xff0c;被广泛应用于事件驱动应用开发。Spring Kafka为Java开发者提供了与Kafka交互…

进行性核上性麻痹护理指南,助患者安稳生活

生活细致照料 安全保障&#xff1a;进行性核上性麻痹患者易出现平衡障碍、步态不稳&#xff0c;居家环境需格外留意安全。移除地面障碍物&#xff0c;保持通道畅通&#xff0c;在卫生间、走廊安装扶手&#xff0c;防止患者摔倒受伤。 饮食协助&#xff1a;患者常伴有吞咽困难&…

提取嘉立创3D封装

嘉立创上元器件基本都有3D封装&#xff0c;当用AD或其他软件画PCB时&#xff0c;需要用到的3D封装可以从嘉立创EDA中提取。 首先新建工程&#xff0c;然后放置要提取3D封装的器件 导出-》3D文件 因为导出的文件中包含器件的3D封装和PCB板&#xff0c;需要把PCB板删除才能使用…

工作记录 2017-03-24

工作记录 2017-03-24 序号 工作 相关人员 1 修改了邮件上的问题。 更新RD服务器。 郝 更新的问题 1、修改了New User时 init的保存。 2、文件的查询加了ID。 3、加了 patient insurance secondary 4、修改了payment detail的处理。 识别引擎监控 Ps (iCDA LOG :剔除…

chromium魔改——修改 navigator.webdriver 检测

chromium源码官网 https://source.chromium.org/chromium/chromium/src 说下修改的chromium源码思路&#xff1a; 首先在修改源码过检测之前&#xff0c;我们要知道它是怎么检测的&#xff0c;找到他通过哪个JS的API来做的检测&#xff0c;只有知道了如何检测&#xff0c;我们…

Qt 信号量使用方法

Qt 信号量使用方法 QSemaphore 类 常用函数介绍 函数名称函数功能QSemaphore()构造并初始化对象acquire()尝试获取n个资源&#xff0c;如果没有那么多资源&#xff0c;线程将阻塞直到有n个资源可用available()返回当前信号量可用的资源个数&#xff0c;这个数永远不可能为负…

【通俗易懂说模型】生成对抗网络·GAN

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;《深度学习理论直觉三十讲》_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目…

容器适配器-stack栈

C标准库不只是包含了顺序容器&#xff0c;还包含一些为满足特殊需求而设计的容器&#xff0c;它们提供简单的接口。 这些容器可被归类为容器适配器(container adapter)&#xff0c;它们是改造别的标准顺序容器&#xff0c;使之满足特殊需求的新容器。 适配器:也称配置器,把一…

【UE5 C++课程系列笔记】31——创建Json并保存为文件

目录 方式一&#xff08;不推荐&#xff09; 方式二&#xff08;推荐&#xff09; 一、生成普通Json对象 二、对象嵌套对象 三、对象嵌套数组 四、对象嵌套数组再嵌套对象 方式一&#xff08;不推荐&#xff09; 如下代码实现了把JSON字符串保存到文件中 #include &qu…

Photoshop 2025 Mac中文 Ps图像编辑软件

Photoshop 2025 Mac中文 Ps图像编辑软件 文章目录 Photoshop 2025 Mac中文 Ps图像编辑软件一、介绍二、效果三、下载 一、介绍 Adobe Photoshop 2025 Mac版集成了多种强大的图像编辑、处理和创作功能。①强化了Adobe Sensei AI的应用&#xff0c;通过智能抠图、自动修复、图像…

使用Redis构架你自己的私有大模型

使用Redis构架你自己的私有大模型--楼兰 ​ Redis你通常用来做什么?缓存?分布式锁?数据过滤器?不够不够,这远远不够。之前给大家分享过基于Redis Stack提供的一系列插件,完全可以把Redis作为一个类似于Elastic Search的JSON数据库使用。不光可以存储并操作JSON格式的数据…

从内核到应用层:Linux缓冲机制与语言缓冲区的协同解析

系列文章目录 文章目录 系列文章目录前言一、缓冲区1.1 示例11.2 缓冲区的概念 二、缓冲区刷新方案三、缓冲区的作用及存储 前言 上篇我们介绍了&#xff0c;文件的重定向操作以及文件描述符的概念&#xff0c;今天我们再来学习一个和文件相关的知识-----------用户缓冲区。 在…

【AI News | 20250403】每日AI进展

AI Repos 1、llm-server-docs 项目提供了一份基于Debian系统的本地语言模型服务器搭建指南&#xff0c;适用于Linux初学者。教程涵盖驱动安装、GPU功耗设置、自动登录配置及开机自启脚本部署等关键步骤&#xff0c;支持Ollama/vLLM等多种OpenAI兼容方案。方案设计强调四大原则…

深入理解SQL中的<>运算符:不等于的灵活运用

在SQL的世界里&#xff0c;数据的筛选与查询是最常见的操作之一。在编写查询语句时&#xff0c;比较运算符是我们不可忽视的工具&#xff0c;其中&#xff0c;<> 运算符作为 不等于 的代表&#xff0c;起着至关重要的作用。它不仅能够帮助我们筛选出符合特定条件的数据&a…

数据清洗的具体内容

&#xff08;一&#xff09;ETL介绍 “ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;、加载&#xff08;Load&#xff09;至目的端的过程。ETL一词较…

小家电等电子设备快充方案,XSP15支持全协议和支持MCU与电脑传输数据

随着USB-C的普及&#xff0c;市面上消费者PD充电器越来越多&#xff0c;如何让小家电等电子产品也能够支持PD协议快充呢&#xff1f;就需要加入一颗汇铭达XSP15取电协议芯片&#xff0c;这颗芯片不仅能支持取电&#xff0c;还能通过串口读取充电器支持的最大输出功率和支持外部…

缺页异常导致的iowait打印出相关文件的绝对路径

一、背景 在之前的博客 增加等IO状态的唤醒堆栈打印及缺页异常导致iowait分析-CSDN博客 里&#xff0c;我们进一步优化了D状态和等IO状态的事件的堆栈打印&#xff0c;补充了唤醒堆栈打印&#xff0c;也分析了一种比较典型的缺页异常filemap_fault导致的iowait的情况。 在这篇…

记录学习的第十七天

今天对昨天下午的洛谷蓝桥杯模拟赛和今天早上的力扣周赛进行复盘。 昨天的蓝桥杯模拟赛&#xff0c;硬坐了4个小时&#xff0c;只会做前面的三道入门题。&#x1f625;而且第一道填空题竟然还算错了。其他的五道题我都没啥思路了&#xff0c;实在难受啊&#xff01; Q1:这道题硬…

全面解析 Mybatis 与 Mybatis-Plus:深入原理、实践案例与高级特性对比

全面解析 Mybatis 与 Mybatis-Plus&#xff1a;深入原理、实践案例与高级特性对比 &#x1f680; 前言一、基础介绍 ✨1. Mybatis 简介 &#x1f50d;2. Mybatis-Plus 简介 ⚡ 二、核心区别与高级特性对比 &#x1f50e;1. 开发模式与配置管理2. 功能丰富度与扩展性3. 自动填充…

Ubuntu 22.04 一键部署openManus

openManus 前言 OpenManus-RL,这是一个专注于基于强化学习(RL,例如 GRPO)的方法来优化大语言模型(LLM)智能体的开源项目,由来自UIUC 和 OpenManus 的研究人员合作开发。 前提要求 安装deepseek docker方式安装 ,windows 方式安装,Linux安装方式