Adobe Acrobat Professional和Adobe Reader都是Adobe公司的产品。前者用来编辑制作PDF文档,后者只能用来阅读PDF。令人郁闷的是Adobe Reader中虽然有书签这一项显示,却没有添加书签的功能。解决方法一是使用Adobe Acrobat Professional,另一个方法如下:

http://www.pdfhacks.com/bookmark_page/bookmark_page.js-1.0.zip 上面下载一个javascript脚本文件,把这个文件放到Adobe/Acrobat 7.0/Reader/Javascripts目录下。如果忘记了Adobe的安装目录,可以运行Adobe Reader,然后使用process explorer查看进程对应的可执行文件路径。文件放好后,重新运行Adobe Reader,就可以在“视图”菜单项的下面发现四个新增的条项。这四个新增的条项就是那个javascript文件的效果,它们能够实现书签的功能。这个新增的书签功能自然是不能和Adobe Acrobat Professional中的书签功能相比,但对于阅读文档也足够了。

下面是那个javascript文件的内容:

===================================代码开始================================

// bookmark_page.js, ver. 1.0

// visit: www.pdfhacks.com/bookmark_page/

// use this delimiter for serializing our array

var bp_delim= '%#%#';

function SaveData( data ) {

// data is an array of arrays that needs

// to be serialized and stored into a persistent

// global string

var ds= '';

for( ii= 0; ii< data.length; ++ii ) {

for( jj= 0; jj< 3; ++jj ) {

if( ii!= 0 || jj!= 0 )

ds+= bp_delim;

ds+= data[ii][jj];

}

}

global.pdf_hacks_js_bookmarks= ds;

global.setPersistent( "pdf_hacks_js_bookmarks", true );

}

function GetData() {

// reverse of SaveData; return an array of arrays

if( global.pdf_hacks_js_bookmarks== null ) {

return new Array(0);

}

var flat= global.pdf_hacks_js_bookmarks.split( bp_delim );

var data= new Array();

for( ii= 0; ii< flat.length; ) {

var record= new Array();

for( jj= 0; jj< 3 && ii< flat.length; ++ii, ++jj ) {

record.push( flat[ii] );

}

if( record.length== 3 ) {

data.push( record );

}

}

return data;

}

function AddBookmark() {

// query the user for a name, and then combine it with

// the current PDF page to create a record; store this record

var label=

app.response( "Bookmark Name:",

"Bookmark Name",

"",

false );

if( label!= null ) {

var record= new Array(3);

record[0]= label;

record[1]= this.path;

record[2]= this.pageNum;

data= GetData();

data.push( record );

SaveData( data );

}

}

function ShowBookmarks() {

// show a pop-up menu; this seems to only work when

// a PDF is alreay in the viewer;

var data= GetData();

var items= '';

for( ii= 0; ii< data.length; ++ii ) {

if( ii!= 0 )

items+= ', ';

items+= '"'+ ii+ ': '+ data[ii][0]+ '"';

}

// assemble the command and the execute it with eval()

var command= 'app.popUpMenu( '+ items+ ' );';

var selection= eval( command );

if( selection== null ) {

return; // exit

}

// the user made a selection; parse out its index and use it

// to access the bookmark record

var index= 0;

// toString() converts the String object to a string literal

// eval() converts the string literal to a number

index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );

if( index< data.length ) {

try {

// the document must be 'disclosed' for us to have any access

// to its properties, so we use these FirstPage NextPage calls

//

app.openDoc( data[index][1] );

app.execMenuItem( "FirstPage" );

for( ii= 0; ii< data[index][2]; ++ii ) {

app.execMenuItem( "NextPage" );

}

}

catch( ee ) {

var response=

app.alert("Error trying to open the requested document./nShould I remove this bookmark?", 2, 2);

if( response== 4 && index< data.length ) {

data.splice( index, 1 );

SaveData( data );

}

}

}

}

function DropBookmark() {

// modelled after ShowBookmarks()

var data= GetData();

var items= '';

for( ii= 0; ii< data.length; ++ii ) {

if( ii!= 0 )

items+= ', ';

items+= '"'+ ii+ ': '+ data[ii][0]+ '"';

}

var command= 'app.popUpMenu( '+ items+ ' );';

var selection= eval( command );

if( selection== null ) {

return; // exit

}

var index= 0;

index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );

if( index< data.length ) {

data.splice( index, 1 );

SaveData( data );

}

}

function ClearBookmarks() {

if( app.alert("Are you sure you want to erase all bookmarks?", 2, 2 )== 4 ) {

SaveData( new Array(0) );

}

}

app.addMenuItem( {

cName: "-",              // menu divider

cParent: "View",         // append to the View menu

cExec: "void(0);" } );

app.addMenuItem( {

cName: "Bookmark This Page &5",

cParent: "View",

cExec: "AddBookmark();",

cEnable: "event.rc= (event.target != null);" } );

app.addMenuItem( {

cName: "Go To Bookmark &6",

cParent: "View",

cExec: "ShowBookmarks();",

cEnable: "event.rc= (event.target != null);" } );

app.addMenuItem( {

cName: "Remove a Bookmark",

cParent: "View",

cExec: "DropBookmark();",

cEnable: "event.rc= (event.target != null);" } );

app.addMenuItem( {

cName: "Clear Bookmarks",

cParent: "View",

cExec: "ClearBookmarks();",

cEnable: "event.rc= true;" } );

===================================代码结束================================

给Adobe Reader添加书签功能的更多相关文章

  1. Firefox火狐添加书签功能失灵解决办法

    一直使用firefox,书签管理用的是插件Tabmix.感觉很好,只是不知道从那天起添加书签就不灵了!不论是Ctrl+D快捷键,还是Add Bookmark Here2插件,甚至“将此页加为书签”的菜 ...

  2. 设置Adobe Reader打开PDF文件保持记忆功能

    设置Adobe Reader打开PDF文件保持记忆功能 打开菜单“编辑”->“首选项”. 选择种类中的“文档”,在“打开设置”区域勾上“重新打开文档时恢复上次视图设置(R)”,确定之后就可以在下 ...

  3. 在Adobe Reader中保存PDF表单数据的方法

    通常,Adobe Reader 用户填写表单后,是无法保存所填表单的副本的.但是,对于 Reader 8 和更高版本的用户,您可以扩展其权限,使他们可以完成此操作.如果您使用的是 Acrobat Pr ...

  4. ADOBE READER把PDF转换成WORD教程

    目前国外很多软件的支持信息都使用PDF方式进行发布,如果没有Adobe  Reader,无法查看其内容,如果没有相关的编辑软件又无法编辑PDF文件.转换为DOC格式则可以实现编辑功能.尽管有些软件也可 ...

  5. pypdf2:下载Americanlife网页生成pdf合并pdf并添加书签

    初步熟悉 安装 pip install pypdf2 合并并添加书签 #!/usr/bin/env python3.5 # -*- coding: utf-8 -*- # @Time : 2019/1 ...

  6. 创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段

    创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段 添加查询功能 本文将实现通过Name查询用户信息. 首先更新GetAll方法以启用查询: public async ...

  7. lucene3.6笔记添加搜索功能

    lucene为程序添加搜索功能,此功能基于已创建好的文档的索引之上.这里我已经为一些文档建立了索引,并保存到硬盘上.下面开始针对这些索引,添加搜索功能. 1.简单的TermQuery搜索 Java代码 ...

  8. Ubuntu安装Adobe Reader

               到 这里依次选择最新版本的Adobe Reader,我选择目前最新的 9.5.5版本的,下载下来后,双击选择dep包,启动软件中心进行安装,中间会提示软件包欠佳,选择" ...

  9. 011.Adding Search to an ASP.NET Core MVC app --【给程序添加搜索功能】

    Adding Search to an ASP.NET Core MVC app 给程序添加搜索功能 2017-3-7 7 分钟阅读时长 作者 本文内容 1.Adding Search by genr ...

随机推荐

  1. CakeDC(cakephp company)Git workflow--适合于较大团队大型项目开发

    CakeDC Git workflow是一个项目开发和版本发布的工作流,在这个工作流程中开发和版本发布周期是基于几个关键阶段(key phases): Development: 所有活跃的开发活动都由 ...

  2. 如何使用LiveSuite debian img格式的镜像文件刷入nand

    1. liveSuite启动后 2. 选择固件(就是对应的img文件) 3. 将cubieboard板子的fel按钮按住不要松,然后使用otg接口线插入电脑和cubieboard板子,直到liveSu ...

  3. SQL group by分组查询(转)

    本文导读:在实际SQL应用中,经常需要进行分组聚合,即将查询对象按一定条件分组,然后对每一个组进行聚合分析.创建分组是通过GROUP BY子句实现的.与WHERE子句不同,GROUP BY子句用于归纳 ...

  4. asp.net(C#)清除全部Session与单个Session

    Session.Abandon();//清除全部SessionSession["UserName"] = null;Session.Remove("UserName&qu ...

  5. 深入理解OpenERP的工作流(Workflow)

    一.工作流定义: <?xml version="1.0"?>  <terp><data>    <record model="w ...

  6. Heritrix源码分析(一) 包介绍(转)

    本博客属原创文章,欢迎转载!但转载请务必注明出处:http://guoyunsky.iteye.com/blog/613249 本博客已迁移到本人独立博客: http://www.yun5u.com/ ...

  7. linux内核值shmmax问题

    问题:(rac安装过程中grid检测)  Please run the following script on each node as "root" user to execut ...

  8. android中的style部分属性值介绍

    转自:http://blog.sina.com.cn/s/blog_70c759fd01013phv.html Android平台定义的主题样式: android:theme="@andro ...

  9. jdbc操作数据库返回结果集的注意事项

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  10. RPC调用框架比较分析

    什么是RPC: RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 简言之,RPC ...