网站首页 > 技术文章 正文
更多编程技术文章,请查阅IOKKS - 专业编程技术分享平台
便携文档格式(PDF)被广泛用于在各种平台上共享文档。PDF之所以受欢迎,是因为它以一种方式保持文档的格式和布局,使得任何操作系统或PDF查看器都不会显示任何修改的迹象。PDF是通过称为PDF查看器的软件工具来显示的,这些工具具有许多与文档交互的功能,如导航、放大和缩小以及跳转到特定页面。
每个PDF查看器都有特定的功能,这限制了新功能的可能性。因此,开发人员可能希望创建自己的PDF查看器软件,以满足其特定的需求和偏好,如文档分析或数据提取。创建自定义PDF查看器有许多优势,其中一些如下:
- 定制化 :开发自己的PDF查看器允许您根据特定需求定制其界面、功能和功能。
- 集成 :构建自定义PDF查看器使您能够无缝集成到您的平台或应用程序中,而不会牺牲任何功能。
- 安全和隐私 :自定义PDF查看器使您能够控制加密和访问控制等安全措施,以确保PDF文件中敏感内容的保密性。
在本文中,您将使用PDF.js库构建一个简单的自定义PDF查看器。PDF.js是Mozilla开发的基于HTML5的开源PDF查看器库,用于呈现和解析PDF。
使用PDF.js库开发PDF查看器
在开始之前,您需要选择一个代码编辑器和PDF.js库,可以通过CDN(本教程中使用)连接或从GitHub下载。
设置环境
首先,您将设置一个Vanilla JS项目,其中包含一个简单的包含HTML、CSS和JavaScript功能的网页。
在文件夹中设置一个名为PDF Viewer 的项目文件夹,并在文件夹中创建以下三个文件:
- index.html
- styles.css
- viewer.js
项目文件夹结构应如下所示:
项目结构
为PDF查看器创建用户界面
下一步是创建一个界面来使用PDF查看器。
打开index.html文件,然后输入以下代码并保存:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple PDF Viewer</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Simple PDF Viewer</h1>
<div id="pdf-container"></div>
<div id="page-controls">
<button id="prev-page">Previous</button>
<span id="page-num">Page 1</span>
<button id="next-page">Next</button>
<input type="number" id="go-to-page-input" placeholder="Go to Page">
<button id="go-to-page-btn">Go</button>
</div>
<div>
<button id="zoom-out">Zoom Out</button>
<button id="zoom-in">Zoom In</button>
</div>
<input type="file" id="file-input" accept=".pdf">
</body>
</html>
上述代码创建了一个简单的界面,包括以下元素:
- 用于显示PDF文件的容器
- “上一页”和“下一页”按钮,用于导航PDF文件的页面
- 用于跳转到PDF文件指定页面编号的输入字段
- “放大”和“缩小”按钮
- 用于从用户本地文件资源管理器中选择PDF文件的按钮
除了创建用户界面外,还有两个用于外部JavaScript文件的脚本标签,用于向网页添加功能。
第一个脚本标签https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js是用于呈现PDF文档的PDF.js库的链接。这将把PDF.js库集成到您的项目中。
第二个脚本标签viewer.js是用于实现PDF查看器功能的自定义JavaScript文件的链接。
这样,HTML文件中的代码就结束了。生成的网页应如下所示:
PDF查看器
使用CSS为界面添加样式
虽然本教程不侧重于为用户界面添加样式,但您可以使其看起来更加美观。将以下代码保存在styles.css中:
/* styles.css */
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
font-family: Arial, sans-serif;
}
#pdf-container {
border: 1px solid #ccc;
overflow: auto;
width: 80%;
max-width: 800px;
height: 70vh;
}
.button-group, #zoom-controls, #file-controls {
display: flex;
align-items: center;
margin-top: 10px;
}
.button-group button, #zoom-controls button, #file-controls button, #file-controls input[type="file"] {
margin: 0 5px;
padding: 5px 10px;
border: none;
background-color: #007bff;
color: #fff;
cursor: pointer;
border-radius: 4px;
font-size: 14px;
transition: background-color 0.3s ease;
}
.button-group button:hover, #zoom-controls button:hover, #file-controls button:hover, #file-controls input[type="file"]:hover {
background-color: #0056b3;
}
#go-to-page-input, #go-to-page-btn {
margin-left: 5px;
}
上述代码将元素居中,为显示PDF的空间进行了组织,并对所有按钮和输入字段进行了对齐。
生成的网页现在应如下所示:
带有CSS样式的PDF查看器
使用JavaScript和PDF.js添加功能
现在,您已经使用CSS组织了PDF查看器的界面。最后一步是使用JavaScript和PDF.js库添加功能。
首先,为了向PDF查看器添加功能,您需要将所有相关代码放入名为DOMContentLoaded的事件监听器中。这样可以确保在HTML文档完全加载后执行JavaScript代码:
document.addEventListener('DOMContentLoaded', function() {
// 所有代码在此处
});
您还需要通过JavaScript启用与HTML(DOM)元素的交互,例如按钮和输入字段。document.getElementById()函数允许访问文档对象模型(DOM)元素,从而可以为稍后使用的每个元素创建变量:
const pdfContainer = document.getElementById('pdf-container');
const prevPageBtn = document.getElementById('prev-page');
const nextPageBtn = document.getElementById('next-page');
const pageNumSpan = document.getElementById('page-num');
const goToPageInput = document.getElementById('go-to-page-input');
const goToPageBtn = document.getElementById('go-to-page-btn');
const zoomOutBtn = document.getElementById('zoom-out');
const zoomInBtn = document.getElementById('zoom-in');
const fileInput = document.getElementById('file-input');
然后,您将初始化以下三个变量:pdfDoc、pageNum和scale。pdfDoc变量存储加载的PDF文档实例,pageNum变量跟踪当前显示的页面编号,scale变量用于跟踪缩放比例,以实现放大和缩小功能:
let pdfDoc = null;
let pageNum = 1;
let scale = 1.0;
接下来,renderPage()函数呈现加载的PDF文件的特定页面。它获取PDF页面,调整画布尺寸以匹配页面,清除容器,并将页面内容呈现到画布上,从而在容器内有效地显示页面:
async function renderPage(num) {
const page = await pdfDoc.getPage(num);
const viewport = page.getViewport({ scale: scale });
const canvas = document.createElement('canvas');
const canvasContext = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
pdfContainer.innerHTML = '';
pdfContainer.appendChild(canvas);
const renderContext = {
canvasContext,
viewport,
};
await page.render(renderContext);
}
loadPDF()函数从给定的URL加载PDF文档,使用pdfjsLib.getDocument()方法。然后调用renderPage()来显示初始页面并更新页面计数:
async function loadPDF(url) {
const loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
接下来,您将为多个按钮添加事件监听器,以实现点击功能,例如:
- prevPageBtn和nextPageBtn按钮用于页面导航,同时更新要显示的页面编号
- goToPageBtn按钮,用于跳转到goToPageInput字段中输入的值(页面编号),以跳转到PDF文件的特定页面
- zoomOutBtn和zoomInBtn按钮用于放大和缩小显示的页面
prevPageBtn.addEventListener('click', () => {
if (pageNum > 1) {
pageNum--;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
nextPageBtn.addEventListener('click', () => {
if (pageNum < pdfDoc.numPages) {
pageNum++;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
goToPageBtn.addEventListener('click', () => { // 用于“跳转到页面”按钮的事件监听器
const targetPage = parseInt(goToPageInput.value);
if (targetPage >= 1 && targetPage <= pdfDoc.numPages) {
pageNum = targetPage;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
zoomOutBtn.addEventListener('click', () => {
if (scale > 0.25) {
scale -= 0.25;
renderPage(pageNum);
}
});
zoomInBtn.addEventListener('click', () => {
if (scale < 3) {
scale += 0.25;
renderPage(pageNum);
}
});
最后一部分是fileInput监听器,用于检查change事件以加载和呈现用户从本地文件资源管理器中选择的任何文件:
fileInput.addEventListener('change', async (event) => {
const selectedFile = event.target.files[0];
if (selectedFile) {
const fileURL = URL.createObjectURL(selectedFile);
loadPDF(fileURL);
}
});
以下是添加功能的完整代码。打开已创建的viewer.js文件,然后输入以下代码并保存:
document.addEventListener('DOMContentLoaded', function() {
const pdfContainer = document.getElementById('pdf-container');
const prevPageBtn = document.getElementById('prev-page');
const nextPageBtn = document.getElementById('next-page');
const pageNumSpan = document.getElementById('page-num');
const goToPageInput = document.getElementById('go-to-page-input'); // 添加的输入元素
const goToPageBtn = document.getElementById('go-to-page-btn'); // 添加的按钮元素
const zoomOutBtn = document.getElementById('zoom-out');
const zoomInBtn = document.getElementById('zoom-in');
const fileInput = document.getElementById('file-input');
let pdfDoc = null;
let pageNum = 1;
let scale = 1.0;
async function renderPage(num) {
const page = await pdfDoc.getPage(num);
const viewport = page.getViewport({ scale: scale });
const canvas = document.createElement('canvas');
const canvasContext = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
pdfContainer.innerHTML = '';
pdfContainer.appendChild(canvas);
const renderContext = {
canvasContext,
viewport,
};
await page.render(renderContext);
}
async function loadPDF(url) {
const loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
prevPageBtn.addEventListener('click', () => {
if (pageNum > 1) {
pageNum--;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
nextPageBtn.addEventListener('click', () => {
if (pageNum < pdfDoc.numPages) {
pageNum++;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
goToPageBtn.addEventListener('click', () => { // 用于“跳转到页面”按钮的事件监听器
const targetPage = parseInt(goToPageInput.value);
if (targetPage >= 1 && targetPage <= pdfDoc.numPages) {
pageNum = targetPage;
renderPage(pageNum);
pageNumSpan.textContent = `Page ${pageNum} of ${pdfDoc.numPages}`;
}
});
zoomOutBtn.addEventListener('click', () => {
if (scale > 0.25) {
scale -= 0.25;
renderPage(pageNum);
}
});
zoomInBtn.addEventListener('click', () => {
if (scale < 3) {
scale += 0.25;
renderPage(pageNum);
}
});
fileInput.addEventListener('change', async (event) => {
const selectedFile = event.target.files[0];
if (selectedFile) {
const fileURL = URL.createObjectURL(selectedFile);
loadPDF(fileURL);
}
});
});
这标志着使用PDF.js开发自定义PDF查看器的开发工作已经完成。
测试PDF查看器
使用PDF.js完成PDF查看器项目后,现在让我们尝试渲染一些PDF并看看它的效果。
如果你渲染一个PDF文件,它会看起来像这样:
PDF查看器测试
放大:
PDF查看器:放大
缩小:
PDF查看器:缩小
下一页:
PDF查看器:下一页
上一页:
PDF查看器:上一页
结论
在本文中,你探索了如何使用PDF.js库从头开始开发自定义PDF查看器。你可以在这些步骤的基础上构建许多不同版本的PDF查看器,添加你需要的任何功能。
你可以在这个GitHub存储库中找到本文中使用的所有代码。
猜你喜欢
- 2024-11-17 fastapi+vue3文件上传(vue ftp上传)
- 2024-11-17 Dooring可视化之从零实现动态表单设计器
- 2024-11-17 在 FastAPI 中处理表单和用户输入:综合指南
- 2024-11-17 Laravel9表单的验证(validate表单验证)
- 2024-11-17 第63节 Form表单-Web前端开发之JavaScript-王唯
- 2024-11-17 Gateway结合Sentinel1.8限流熔断及自定义异常
- 2024-11-17 手机网站常见问题总结(手机网站出现错误怎么办)
- 2024-11-17 CSS实现去除Input框默认样式的详细教程
- 2024-11-17 企业必备实战之Sentinel规则Nacos持久化
- 2024-11-17 禁用qq浏览器数字文本框 鼠标滚轮滑动 数字加减
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-