基本思路:大多数的扫描版PDF电子图书都可以在官网或者各大网上书店找到目录,很多都是带有页码的(图1)。 将目录用文本文件保存起来,作为附件添加到PDF中,利用JavaScript读取附件,生成数组,用循环处理字符串,再生成书签。
图1就是某网上书店的目录页面,可以看到后面每行都带有页码,这就是我们想要的!
下面是具体步骤:
3.打开Acrobat,并打开需要添加书签的PDF文件。
选择"帮助"菜单下的"Mark”选项。<-就是我们刚刚用JS添加的!(图3)
图3
4.选中"Mark"菜单后会弹出下面的选择文件窗口
页码为1的页面就是PDF文件的第一页,但一般都不是正文的第一页。
图7
因此,对于图7来说,图6中就应该输入14,然后按确定
稍等一下,带连接的书签就自动生成了(图8)。
注:如果书签比较长,比较长,这个过程会卡顿一会,没办法,JS没有多线程
图8
如上图,页码2的页数是15,则页码1的页数是14,以此类推。
有的PDF正文内可能插有其他的内容,例如发布网站的广告等,这时要把这些页面删掉,以确保正文的页数跟目录是一致的,否则将连接不到正确的页面。
脚本也能处理没有页数的目录,但是需要手动设置书签的目标了…
Acrobat Pro的版本要高于9.3,否则不能读取附件内容。
最后附上JS的源码:
app.addMenuItem({ cName : "Mark", cParent : "Help", //加在”帮助(Help)“菜单下面 nPos : 0, //0为尽可能最顶,忽略则最底位置 cExec : "makeBookmark();", cEnable : "event.rc= (event.target != null);" //当有文档打开时(event.target != null)才可用 }); function makeBookmark() { //提示导入目录 if (!(this.importDataObject("txtBookmark"))) { return } //检验目录是否TXT文本格式 var MyData = this.getDataObject("txtBookmark"); if (MyData["MIMEType"] != "text/plain") { app.alert("附件不是TXT格式!"); this.removeDataObject("txtBookmark"); return } var FirstPageNum = app.response({ cQuestion : "输入页码为1的实际页数", cTitle : "若缺少1页码,则输入2页码的实际页数,依此类推", cDefault : "2", cLabel : "输入:" }); if (FirstPageNum != null) { var MyStream = this.getDataObjectContents("txtBookmark"); var MyString = util.stringFromStream(MyStream, "utf-8"); //替换全角空格 Unicode值\u3000 MyString = MyString.replace(/\u3000/g, "\u0020"); //处理前后空格 Unicode值\u0020 MyString = MyString.replace(/^\u0020\.*|\u0020$/gm, ""); var myArr = MyString.split("\n"); this.bookmarkRoot.remove(); this.bookmarkRoot.createChild("目录"); var Bkm = new Array(10); //创建一个数组来缓存书签 Bkm[0] = this.bookmarkRoot.children[0]; var HasPart = false; //设置一个flag表示是否遇到“部分”等没有.号的大分类 for (var i in myArr) { var myRow = myArr[i]; if (myRow.length > 2) { //空行的length=1,设置为2即不处理空行 var Num_Dot = 0; var BeforeSpace = myRow.match(/^(\d+\.)+\d+\u0020/g); //1.2.3空格 if (BeforeSpace != null) { var DotMatches = BeforeSpace.toString().match(/\./g); //匹配.符号 Num_Dot = DotMatches.length + HasPart; } else { var myRegExp = /第.*[\d一二三四五六七八九十]+.*部分|附录|索引/; if (myRegExp.test(myRow)) { Num_Dot = 0; HasPart = true; } else { Num_Dot = HasPart + 0; } } var LastSpaceIndex = myRow.lastIndexOf("\u0020"); //最后一个空格的位置 var Page = Number(myRow.slice(LastSpaceIndex)); var Page_Bookmark = isNaN(Page) ? 0 : Page - 2 + Number(FirstPageNum); //书签指向的页码 var Name_Bookmark = isNaN(Page) ? myRow : myRow.slice(0, LastSpaceIndex); //书签的名字 with (Bkm[Num_Dot]) { createChild(Name_Bookmark, "this.pageNum=" + Page_Bookmark + ";", (children != null ? children.length : 0)); Bkm[Num_Dot + 1] = children[children.length - 1]; //目录中最后一个章节 } } } collapsBM(Bkm[0]); } } function collapsBM(BM) { //折叠所有书签 if (BM.children != null) { if (BM != this.bookmarkRoot) { for (var i in BM.children) { if (BM.children[i].children != null) { BM.children[i].open = false; } } } for (var i in BM.children) { collapsBM(BM.children[i]) } } }附近请下最后一个。