「PDF」- 书签 与 大纲(Bookmark and Outline) @20210401

本文解释了PDF中Bookmark(书签)与Outline(大纲)的区别及联系,探讨两者为何会合并,并提供了选择PDF阅读软件时的注意事项。

问题描述

我们在 Okular 中添加书签(Bookmark),但是无法在 Foxit Reader 2.4.4、Evince 3.30.2 中显示。

我们最开始以为书签是软件自己维护的,但是随后我们发现 PDF 文件确实发生修改,因此可以排除。然后我们便查找 PDF 规范,查找相干博客文章对这个问题的说明。

该笔记将对该问题进行解释,并附加补充说明内容。注意,根据上下文,我们可能会使用 Bookmark 代指“书签”,使用 Outline 代指“大纲”。

问题原因

在 PDF 规范中,已经合并 Bookmark 和 Outline 并统称为 Outline,如 PDF 规范所述:

	The outline consists of a tree-structured hierarchy of outline items (sometimes called bookmarks), which serve as a visual table of contents to display the document’s structure to the user.

而 Bookmark 没有明确的规范,导致 PDF 都有自己的实现,因此软件的行为不同(正如我们遇到的问题)。

Bookmark and Outline

什么是书签(Bookmark)?

可以比喻为现实世界中的书签,做标记,然后让我们可以快速找到书中某些页面。

什么是大纲(Outline)?

而大纲是类似书中的摘要,通常位于章节的最开始,可以然我们快速了解到书(PDF)中的内容。这种“摘要”可能是小段文本描述,也可能是个内容列表(Table of Contents)

为什么大纲与目录会被合并?

首先,要明确两个问题:
1)PDF 是种文档格式,没有“目录”的概念,我们看到的目录,是人为添加的标记(书签、大纲)
2)大纲不一定是一段文

### 在 Vue3 中添加 PDF 文件的书签功能 为了在 Vue3 项目中实现 PDF书签功能,可以利用 `pdfjs-dist` 库来解析和显示 PDF 文件,并结合自定义逻辑处理书签。以下是具体的实现方法: #### 安装依赖库 首先,在项目中安装必要的 npm 包: ```bash npm install pdfjs-dist vue-pdf-embed --save ``` #### 加载并初始化 PDF.js 加载 PDF.js 并配置全局变量以便后续使用: ```javascript import * as pdfjsLib from 'pdfjs-dist'; // 设置 worker 路径 pdfjsLib.GlobalWorkerOptions.workerSrc = new URL( 'pdfjs-dist/build/pdf.worker.min.js', import.meta.url, ).toString(); ``` #### 解析 PDF 文档结构 读取 PDF 文件的同时提取其大纲(即书签)。这一步骤对于支持书签特性的 PDF 至关重要。 ```typescript async function loadPdf(url: string): Promise<PDFDocumentProxy> { const loadingTask = pdfjsLib.getDocument(url); return await loadingTask.promise; } function getBookmarks(pdfDoc: PDFDocumentProxy, outline?: OutlineItem[]): Array<{ title: string; destination: number }> { let bookmarks = []; if (!outline || !Array.isArray(outline)) { return []; } for (const item of outline) { if ('Title' in item && 'Dest' in item.Dest) { bookmarks.push({title: item.Title, destination: item.Dest[0]}); } // Recursively add children items to the list. if (item.Items?.length > 0) { bookmarks = [...bookmarks, ...getBookmarks(pdfDoc, item.Items)]; } } return bookmarks; } ``` 上述函数会遍历整个文档的大纲层次结构并将每一项转换成易于使用的对象数组[^1]。 #### 创建组件模板 创建一个简单的 Vue 组件用于呈现 PDF 和对应的书签列表。 ```vue <template> <div class="pdf-viewer"> <!-- 左侧导航栏 --> <aside id="sidebar" style="width:25%;"> <ul v-if="bookmarks.length !== 0"> <li v-for="(bookmark, index) in bookmarks" :key="index" @click="jumpToPage(bookmark.destination)"> {{ bookmark.title }} </li> </ul> </aside> <!-- 右边PDF查看区域 --> <section id="content-area" style="flex-grow:1;"> <div ref="pdfContainer"></div> </section> </div> </template> ``` #### 编写脚本部分 编写 JavaScript 部分负责实际业务逻辑,比如跳转至指定页码等操作。 ```javascript <script setup lang="ts"> import { onMounted } from 'vue'; let pdfContainer = $ref(null); onMounted(async () => { try { const url = '/path/to/your.pdf'; // 替换成自己的路径 const pdfDoc = await loadPdf(url); const outlines = await pdfDoc.getOutline(); // 获取大纲数据 const bookmarks = getBookmarks(pdfDoc, outlines); renderPdfPages(pdfDoc); // 渲染所有页面 } catch(error){ console.error('Error loading document:', error.message); } }); function jumpToPage(pageNumber:number){ // 实现滚动到特定页面的功能... } </script> ``` 以上代码片段展示了如何在一个基于 Vue3 构建的应用程序里集成基本的 PDF 查看器以及关联的书签导航特性[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值