书签 (Bookmark)
福昕 PDF SDK 提供了名为书签的导航工具,允许用户在 PDF 文档中快速定位和链接他们感兴趣的部分。PDF 书签也称为大纲 (outline),每个书签包含一个目标位置或动作来描述它链接到的位置。它是一个树形的层次结构,因此在访问 bookmark 树之前,必须首先获取整个 bookmark 树的根节点。这里,书签根节点
是一个抽象对象,它只有一些子节点,没有兄弟节点, 也没有任何数据 (包括 bookmark 数据,目标位置数据和动作数据)。
以 Java 开发语言为例:
获取整个 bookmark 树的根节点,使用 pdf.PDFDoc.getRootBookmark
接口。因为它没有任何数据,因此无法在应用程序界面上显示,能够调用的接口只有 Bookmark.getFirstChild
。
在获取书签根节点后,就可以调用以下的接口去访问其他的书签:
- 访问 parent bookmark,使用
Bookmark.getParent
接口。 - 访问第一个 child bookmark,使用
Bookmark.getFirstChild
接口。 - 访问 next sibling bookmark,使用
Bookmark.getNextSibling
接口。 - 插入一个新的 bookmark,使用
Bookmark.insert
接口。 - 移动一个 bookmark,使用
Bookmark.moveTo
接口。
遍历 PDF 文档中所有的书签
c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_filespec.h"
#include "include/pdf/fs_bookmark.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/fs_pdfpage.h"
using namespace foxit;
using namespace foxit::common;
using foxit::common::Library;
using namespace pdf;
...
// Assuming PDFDoc doc has been loaded.
Bookmark root = doc.GetRootBookmark();
Bookmark first_bookmark = root.GetFirstChild();
if (first_bookmark != null)
{
TraverseBookmark(first_bookmark, 0);
}
Private void TraverseBookmark(Bookmark root, int iLevel)
{
if (root != null)
{
Bookmark child = root.GetFirstChild();
while (child != null)
{
TraverseBookmark(child, iLevel + 1);
child = child.GetNextSibling();
}
}
}
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_filespec_c.h"
#include "include/fs_bookmark_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfpage_c.h"
...
// Assuming FS_PDFDOC_HANDLE doc has been loaded.
FS_BOOKMARK_HANDLE root;
FSDK_PDFDoc_GetRootBookmark(doc, &root);
FS_BOOKMARK_HANDLE first_bookmark;
FSDK_Bookmark_GetFirstChild(root, &first_bookmark);
if (first_bookmark != null)
{
TraverseBookmark(first_bookmark, 0);
}
Private void TraverseBookmark(FS_BOOKMARK_HANDLE root, int iLevel)
{
if (root != null)
{
FS_BOOKMARK_HANDLE child;
FSDK_Bookmark_GetFirstChild(root, &child);
while (child != null)
{
TraverseBookmark(child, iLevel + 1);
FSDK_Bookmark_GetNextSibling(child, &child);
}
}
}
...
java
import com.foxit.sdk.pdf.Bookmark;
import com.foxit.sdk.pdf.PDFDoc;
...
// Assuming PDFDoc doc has been loaded.
...
Bookmark root = doc.getRootBookmark();
if (root.isEmpty()) {
root = doc.createRootBookmark();
}
String titleStr = "";
Bookmark iterBookmark = root.getFirstChild ();
if (iterBookmark.isEmpty())
return;
while (!iterBookmark.isEmpty())
{
titleStr = iterBookmark.getTitle();
if (iterBookmark.hasChild())
{
Bookmark childBookmark = iterBookmark.getFirstChild();
titleStr = childBookmark.getTitle();
}
iterBookmark = iterBookmark.getNextSibling();
}
...
py
import sys
import site
if sys.version_info.major == 2:
_PYTHON2_ = True
else:
_PYTHON2_ = False
if _PYTHON2_:
#replace with the python2 lib path
site.addsitedir('../../../')
from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *
...
# Assuming PDFDoc doc has been loaded.
root = doc.GetRootBookmark()
first_bookmark = root.GetFirstChild()
def TraverseBookmark(root, iLevel):
if root is not None:
child = root.GetFirstChild()
while child is not None:
TraverseBookmark(child, iLevel + 1)
child = child.GetNextSibling()
if first_bookmark is not None:
TraverseBookmark(first_bookmark, 0)
...
objc
#include "FSPDFObjC.h"
...
// Assuming FSPDFDoc doc has been loaded.
...
FSBookmark *root = [doc getRootBookmark];
if (![root isEmpty]) {
ShowBookmarkInfo(root, info, 0);
}
void ShowBookmarkInfo(FSBookmark *bookmark, int depth) {
if (depth > 32)
return;
if ([bookmark isEmpty]) {
return;
}
ShowBookmarkInfo([bookmark getFirstChild], depth + 1);
ShowBookmarkInfo([bookmark getNextSibling], depth);
}
...
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");
...
// Assuming PDFDoc doc has been loaded.
let root = doc.GetRootBookmark();
let first_bookmark = root.GetFirstChild();
function TraverseBookmark(root, iLevel){
if(!root.IsEmpty()) {
let child = root.GetFirstChild()
while(!child.IsEmpty()) {
TraverseBookmark(child, iLevel + 1)
child = child.GetNextSibling()
}
}
}
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.actions;
...
//Assuming PDFDoc doc has been loaded.
...
Bookmark root = doc.GetRootBookmark();
Bookmark first_bookmark = root.GetFirstChild();
if (first_bookmark != null)
{
TraverseBookmark(first_bookmark, 0);
}
Private void TraverseBookmark(Bookmark root, int iLevel)
{
if (root != null)
{
Bookmark child = root.GetFirstChild();
while (child != null)
{
TraverseBookmark(child, iLevel + 1);
child = child.GetNextSibling();
}
}
}
...
向 PDF 文档中添加一个新的书签
c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_filespec.h"
#include "include/pdf/fs_bookmark.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/fs_pdfpage.h"
using namespace std;
using namespace foxit;
using namespace foxit::common;
using foxit::common::Library;
using namespace pdf;
// Assuming PDFDoc doc has been loaded.
Bookmark root = doc.GetRootBookmark();
if (root.IsEmpty())
{
root = doc.CreateRootBookmark();
}
Destination dest = Destination::CreateFitPage(doc, 0);
CFX_WideString ws_title;
ws_title.Format((FX_LPCWSTR)L"A bookmark to a page (index: %d)", 0);
Bookmark child = root.Insert(ws_title, foxit::pdf::Bookmark::e_PosLastChild);
child.SetDestination(dest);
child.SetColor(0xF68C21);
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_filespec_c.h"
#include "include/fs_bookmark_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfpage_c.h"
int string2wstring(const char *source, size_t source_size, wchar_t *dest, size_t dest_size) {
const char *_source;
wchar_t *_dest;
if (!source || !dest) return 0;
_source = source;
_dest = dest;
setlocale(LC_ALL, "chs");
mbstowcs(_dest, _source, _Dsize);
setlocale(LC_ALL, "C");
return (int)dest_size;
}
// Assuming FS_PDFDOC_HANDLE doc has been loaded.
FS_BOOKMARK_HANDLE root;
FSDK_PDFDoc_GetRootBookmark(doc, &root);
FS_BOOL return_value;
FSDK_Bookmark_IsEmpty(root, &return_value);
if (return_value)
{
FSDK_PDFDoc_CreateRootBookmark(doc, &root);
}
FS_DESTINATION_HANDLE dest;
FSDK_Destination_CreateFitPage(doc, 0, &dest);
char str[128];
sprintf(str, "A bookmark to a page (index: %d)", i);
wchar_t ws_title[MAX_FILE_PATH];
FSErrorCode error_code;
string2wstring(path, MAX_FILE_PATH, ws_title, MAX_FILE_PATH);
FS_BOOKMARK_HANDLE child;
FSDK_Bookmark_Insert(root, ws_title, e_FSPosLastChild, &child);
FSDK_Bookmark_SetDestination(child, dest);
FSDK_Bookmark_SetColor(child, 0xF68C21);
java
import com.foxit.sdk.pdf.Bookmark;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.actions.Destination;
import static com.foxit.sdk.pdf.Bookmark.e_PosLastChild;
// Assuming PDFDoc doc has been loaded.
Bookmark root = doc.getRootBookmark();
if (root.isEmpty()) {
root = doc.createRootBookmark();
}
Destination dest = Destination.createFitPage(doc, 0);
String ws_title = String.format("A bookmark to a page (index: %d)", 0);
Bookmark child = root.insert(ws_title, e_PosLastChild);
child.setDestination(dest);
child.setColor(0xF68C21);
py
import sys
import site
if sys.version_info.major == 2:
_PYTHON2_ = True
else:
_PYTHON2_ = False
if _PYTHON2_:
#replace with the python2 lib path
site.addsitedir('../../../')
from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *
# Assuming PDFDoc doc has been loaded.
root = doc.GetRootBookmark()
if root.IsEmpty():
root = doc.CreateRootBookmark()
dest = Destination.CreateFitPage(doc, 0)
ws_title = str.format("A bookmark to a page (index: {})", 0)
child = root.Insert(ws_title, Bookmark.e_PosLastChild)
child.SetDestination(dest)
child.SetColor(0xF68C21)
objc
#include "FSPDFObjC.h"
// Assuming PDFDoc doc has been loaded.
FSBookmark *root = [doc getRootBookmark];
if ([root isEmpty]) {
root = [doc createRootBookmark];
}
FSDestination *dest = [FSDestination createFitPage:doc page_index:0];
NSString *title = [NSString stringWithFormat:@"A bookmark to a page (index: %d)", 0];
FSBookmark *child = [root insert:title position:FSBookmarkPosLastChild];
[child setDestination:dest];
[child setColor:0xF68C21];
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");
// Assuming PDFDoc doc has been loaded.
let root = doc.GetRootBookmark();
if (root.IsEmpty())
{
root = doc.CreateRootBookmark();
}
let dest = FSDK.Destination.CreateFitPage(doc, i);
let ws_title = `A bookmark to a page (index: ${i})`;
let child = root.Insert(ws_title, FSDK.Bookmark.e_PosLastChild);
child.SetDestination(dest);
child.SetColor(i * 0xF68C21);
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.actions;
// Assuming PDFDoc doc has been loaded.
Bookmark root = doc.GetRootBookmark();
if (root.IsEmpty())
{
root = doc.CreateRootBookmark();
}
using (Destination dest = Destination.CreateFitPage(doc, 0))
{
string ws_title = string.Format("A bookmark to a page (index: {0})", 0);
Bookmark child;
using (child = root.Insert(ws_title, Bookmark.Position.e_PosLastChild))
{
child.SetDestination(dest);
child.SetColor(0xF68C21);
}
}
根据 PDF 的书签信息创建目录表
c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_filespec.h"
#include "include/pdf/fs_bookmark.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/pdf/fs_pdfpage.h"
using namespace foxit;
using namespace foxit::common;
using foxit::common::Library;
using namespace pdf;
...
void AddTOCToPDF(PDFDoc doc) {
//Set the table of contents configuration.
Int32Array intarray;
int depth = doc.GetBookmarkLevelDepth();
if (depth > 0) {
for (int i = 1; i <= depth; i++) {
intarray.Add(i);
}
}
WString title = L"";
TableOfContentsConfig toc_config = TableOfContentsConfig(title, intarray, true, false);
//Add the table of contents
doc.AddTableOfContents(toc_config);
}
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_filespec_c.h"
#include "include/fs_bookmark_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_pdfpage_c.h"
void AddTOCToPDF(FS_PDFDOC_HANDLE& doc) {
// Set the table of contents configuration.
int depth = 0;
FSDK_PDFDoc_GetBookmarkLevelDepth(doc, &depth);
int* intarray = (int*)malloc(depth * sizeof(int));
if (depth > 0) {
for (int i = 1; i <= depth; i++) {
intarray[i - 1] = i;
}
}
FS_WSTR title;
title.str = NULL;
title.len = 0;
FSTableOfContentsConfig toc_config;
toc_config.bookmark_level_array = intarray;
toc_config.bookmark_level_array_length = depth;
toc_config.title = title;
toc_config.is_show_serial_number = true;
toc_config.include_toc_pages = false;
// Add the table of contents.
FSDK_PDFDoc_AddTableOfContents0(doc, toc_config);
free(intarray);
}
java
import com.foxit.sdk.pdf.Bookmark;
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.actions.Destination;
import static com.foxit.sdk.pdf.Bookmark.e_PosLastChild;
static void AddTOCToPDF(PDFDoc doc) throws PDFException {
Int32Array intarray = new Int32Array();
int depth = doc.getBookmarkLevelDepth();
if (depth > 0) {
for (int i = 1; i <= depth; i++) {
intarray.add(i);
}
}
String title = "";
TableOfContentsConfig toc_config = new TableOfContentsConfig(title, intarray, true, false);
// Add the table of contents
doc.addTableOfContents(toc_config);
}
py
import sys
import site
if sys.version_info.major == 2:
_PYTHON2_ = True
else:
_PYTHON2_ = False
if _PYTHON2_:
#replace with the python2 lib path
site.addsitedir('../../../')
from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *
...
def AddTOCToPDF(doc):
# Set the table of contents configuration.
intarray = Int32Array()
depth = doc.GetBookmarkLevelDepth()
if depth > 0:
for i in range(1, depth):
intarray.Add(i)
title = ""
toc_config = TableOfContentsConfig(title, intarray, True, False)
# Add the table of contents
doc.AddTableOfContents(toc_config)
objc
#include "FSPDFObjC.h"
...
void addTOCToPDF(FSPDFDoc* doc) {
@autoreleasepool {
// Set the table of contents configuration.
FSInt32Array* intarray = [[FSInt32Array alloc] init];
int depth = [doc getBookmarkLevelDepth];
if (depth > 0) {
for (int i = 1; i <= depth; i++) {
[intarray add:i];
}
}
NSString* title = @"";
FSTableOfContentsConfig* toc_config = [[FSTableOfContentsConfig alloc] initWithTitle:title bookmark_level_array:intarray is_show_serial_number:true include_toc_pages:false];
// Add the table of contents.
[doc addTableOfContentsWithTableOfContentsConfig:toc_config];
}
}
js
const FSDK = require("@foxitsoftware/foxit-pdf-sdk-node");
...
function AddTOCToPDF(doc){
// Set the table of contents configuration.
let name_array = new FSDK.Int32Array();
depth = doc.GetBookmarkLevelDepth()
if(depth > 0) {
for(var i = 0; i < depth; i++) {
name_array.Add(i);
}
}
let title = ""
let toc_config = new FSDK.TableOfContentsConfig(title, intarray, True, False)
}
// Add the table of contents
doc.AddTableOfContents(toc_config)
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
using foxit.pdf.actions;
static void AddTOCToPDF(PDFDoc doc)
{
//Set the table of contents configuration.
using (var intarray = new Int32Array())
{
int depth = doc.GetBookmarkLevelDepth();
if (depth > 0)
{
for (int i = 1; i <= depth; i++)
{
intarray.Add(i);
}
}
string title = "";
using (var toc_config = new TableOfContentsConfig(title, intarray, true, false))
{
//Add the table of contents
doc.AddTableOfContents(toc_config);
}
}
}