下沙论坛

标题: 让PDF文件也支持书签功能 [打印本页]

作者: 煎饼    时间: 2011-5-20 10:18
标题: 让PDF文件也支持书签功能
最近经常看一些PDF的电子文档,痛苦的是Adobe Reader竟然没有提供书签的功能,每次看完之后再回到上次看的地方都很麻,到网上一找,还真有人就做了PDF的书签,下载一试效果不错,于是参看了一下Adobe Reader的SDK,修改了一点地方,以更方便的使用,下面是程序的使用方法
7 v* x  \0 |3 l, _, a: N& _8 \1、打开编辑的首选项项
" y' J( G% J% T% \. I
0 z. j0 j% f& H( m2、确保下面的选项都被选中7 k8 ~7 y( f' c! G0 I

7 j% E% B; Q3 B* t3 把下面的代码保存为一个bookmark_page.js文件
1 y: H% T! l. a) C, a, u// bookmark_page.js, ver. 1.0
7 V, d( D: e# }// visit: www.pdfhacks.com/bookmark_page/* @' w0 p( f& \! ^% c& }3 W
// edit:cjs 2008-02-17
0 r+ y* Z- t) y2 d4 n$ e  a// 1 修改为中文标签
9 ~& ^+ N% W% p$ j9 X* {// 2 设置书签时可以自动获取当前的书名
$ N' Y/ ^% C0 J0 }# N* v// 3 自动获取当前所在的页码与总页数,方便查阅% C2 }2 d' q" F/ c/ F
// 4 实现更多功能可以参看Adobe Reader的SDK
2 E9 V2 r0 g  b% o' r+ f" d: m* v9 y" ~+ ^7 J& f! V
// use this delimiter for serializing our array0 ]4 g, O; _+ i$ O$ G3 c
var bp_delim= '%#%#';2 H, Z0 S8 l2 y& z" d5 T' `3 k
function SaveData( data ) ...{. B1 P# \  w' d7 J1 }6 ^
  // data is an array of arrays that needs9 P# r. Y: U1 z! L
  // to be serialized and stored into a persistent
: a$ }# E/ T: V9 W/ W# L  O  // global string% R2 x; G' J. m, d' x
  var ds= '';
2 A: P6 B6 R% h+ Q  for( ii= 0; ii< data.length; ++ii ) ...{: I" K$ u+ \' {
    for( jj= 0; jj< 3; ++jj ) ...{% ^' e  j  }: D
      if( ii!= 0 || jj!= 0 )3 K  b& n/ q$ ]9 @* Q4 w
        ds+= bp_delim;
6 f  F$ |0 L  A3 n+ v      ds+= data[ii][jj];" f) a9 ?/ }7 `" @9 J9 B# y; {3 [
    }0 h% \& t# [: J- n  p
  }
# t3 m) O! E$ O. ^4 m% P  global.pdf_hacks_js_bookmarks= ds;
" H' N' P$ Z) b  global.setPersistent( "pdf_hacks_js_bookmarks", true );
  z4 k, }7 R6 I0 f) x0 R}! V  q0 |) Y& N! k4 N. q, n
function GetData() ...{+ N% b0 k) ~0 T% c+ ^) B$ r; U/ I3 X
  // reverse of SaveData; return an array of arrays$ h/ z% [8 X5 j+ h0 r) I/ V+ @& C( Q' d
  if( global.pdf_hacks_js_bookmarks== null ) ...{
' s) W# L1 ~" x; G7 s1 _    return new Array(0);
! F8 X% r: ]- f' Q8 Q4 C  }0 J) _6 ?7 C+ \( L( f% c; D
  var flat= global.pdf_hacks_js_bookmarks.split( bp_delim );
0 I2 |" m5 s# C8 k; F3 w, s& Q  var data= new Array();( ~8 D8 \# A+ X
  for( ii= 0; ii< flat.length; ) ...{! _7 U/ a% |0 J" V' P- V
    var record= new Array();* r3 P4 w9 G6 f: p7 v# a
    for( jj= 0; jj< 3 && ii< flat.length; ++ii, ++jj ) ...{* l( R% }7 i* O9 K* H  i* U
      record.push( flat[ii] );% B# T2 w6 G2 e8 O1 o, g
    }
- X. @% U* {' `4 p  l! S; y    if( record.length== 3 ) ...{
* J2 H9 Z4 ]2 ]: J* q6 ~      data.push( record );
4 w5 z& s. g2 b0 O    }
* E) m  s/ q7 K+ r  }
- l2 w$ p5 @( K& M8 x  return data;
0 V6 y6 |7 @9 f}
' [" Q6 _4 l% _5 y5 E//Get Current Date
2 [( q, H3 v3 {& x- r9 qfunction DateNow()...{
+ \' [8 U' U/ _% {/ y' }   var d, s ;
  Z3 g8 `. }1 y7 B) ]   d = new Date();2 N8 c: H1 R; J7 K0 i* U
   s = d.getFullYear()+"/";
* ^3 y# ~) z" P   s += (d.getMonth() + 1) + "/";% G; l1 ^- \2 |; F5 Q. I! S
   s += d.getDate() ;
# F' t4 T/ x9 b( ^$ m   /**//*/ F& i/ a) U; _" w( F7 T
   s += d.getHours() + ":";* L0 v7 |/ z0 J+ J9 n! d/ \( m6 T, i0 D
   s += d.getMinutes() + ":";
5 l4 ?3 M- t. t# e5 w   s += d.getSeconds() ;
- A% @. D% ?* ^   */+ o0 U7 z+ G! s: N: s2 V* Q/ ~; ?$ [
   return(s);! s  X% y' a8 \/ y% R
}$ v6 c+ F7 S$ j1 e/ @( ^' e# S

0 }7 q2 i6 {6 k% J  y0 I% ~, @- Z) Efunction AddBookmark() ...{
) @/ y/ O( @: k8 t: _  // query the user for a name, and then combine it with
. e/ Q2 }( }3 f/ Z. M, m1 B: a  // the current PDF page to create a record; store this record% X# c) }' m7 L  H$ I) f
  var thisfilename=this.documentFileName;
; ^# ?1 }! o$ B% @  thisfilename=thisfilename.substr(0,thisfilename.lastIndexOf("."));7 `( ]. C: v, H2 \0 B1 Z$ T+ d
  var numPlugInss=this.pageNum+1;
5 B# v2 ~- V. Q% k- j+ _  var currentdate=DateNow();- M  f" U; D" F; r
  var label= 6 |) o) D2 E# t9 \
    app.response( "书签名称,可以修改以便于记忆:",- I: e7 {. w% Z  C5 v! m
                  "书签名称",
- K' B/ [8 f, L                  "《"+thisfilename+"》第 "+numPlugInss+" 页/共 "+this.numPages+" 页  "+currentdate,
9 P. v) l, ~. M0 K/ y$ [                  false );
4 l  P4 A  g4 f* d* o& H  |3 U( I3 n  if( label!= null ) ...{4 s  P& W/ {" I  N, L9 W  }0 t
    var record= new Array(3);
+ o; g# O# t5 r5 R    record[0]= label;, [3 L) X( c: _
    record[1]= this.path;
9 t1 X0 ~+ p" L0 f: o4 @* c% ]& Y    record[2]= this.pageNum;
8 p( }! i+ ~! A1 l    data= GetData();
( {: ^, L4 d: Z7 C$ q    data.push( record );2 a! j( r2 l9 O) \$ @) n+ k( R
    SaveData( data );
4 P- y0 ]9 X3 j: I/ n# {& {  }+ \8 y' t6 o# c$ p6 h) W* X
}
% @) c& D8 O; ofunction ShowBookmarks() ...{% h; O% S- x% N) r: h$ [
  // show a pop-up menu; this seems to only work when* v7 x" {$ {6 e1 u1 X6 w
  // a PDF is alreay in the viewer;3 U9 ]+ ^$ R# H8 H; y; U! e
  var data= GetData();
0 x! K- E0 S2 J" I# a7 ?. {  var items= '';
: D  s: M, f& A0 \: }# Y4 P3 j; }  for( ii= 0; ii< data.length; ++ii ) ...{
' F& x6 a: c! t; K! ]! Q$ {    if( ii!= 0 )
: S& X7 {$ x0 Q2 Z- F  K      items+= ', ';
" `: z8 [+ C- v3 s! G    items+= '"'+ ii+ ': '+ data[ii][0]+ '"';& f* v" [, f. g( c# C
  }
4 B( E3 [8 V. {: ~2 }: @  // assemble the command and the execute it with eval()
+ ~/ l8 r# |6 C2 Y5 Y2 d  var command= 'app.popUpMenu( '+ items+ ' );';
& l( Q7 Z- o. K  var selection= eval( command );) t8 L- K0 u  p/ _9 ^2 B& ?
  if( selection== null ) ...{6 x% v& r6 t; @3 \
    return; // exit
: Y" e3 ^( @. y1 \2 X  }
( L1 q/ L& U. G: K9 r  // the user made a selection; parse out its index and use it
  z* e! Z& k; t# L! ?  r8 S  // to access the bookmark record
% ]) K2 r. U( A# o5 e  var index= 0;3 ~/ k7 n5 a3 w
  // toString() converts the String object to a string literal
, [/ ?+ \5 v8 R% u) W  C* t* V  // eval() converts the string literal to a number
4 N% ^4 k1 ?; c* T; B; I  index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );: }8 |  [9 L8 P1 ~
  if( index< data.length ) ...{' S- z0 B* m# O! o4 u
    try ...{
, t' J' J( a; H$ t4 |      // the document must be 'disclosed' for us to have any access0 m( ]0 m# d+ r" k, }
      // to its properties, so we use these FirstPage NextPage calls
( \. i3 F2 q, ]% w/ B      //& A" W* v6 q+ I) T. P5 L  L) O
      app.openDoc( data[index][1] );& g  b+ R3 b8 V% q# \% h
      app.execMenuItem( "FirstPage" );
$ V* p5 ]- C5 d5 j% u" X5 k0 ]      for( ii= 0; ii< data[index][2]; ++ii ) ...{
  ~  X, I- l* ]% K2 ?; m+ r        app.execMenuItem( "NextPage" );
+ l' z& C1 a: T      }
! C1 @( G: o" ]" M. ^' g    }" S! k; `* u6 g9 Q
    catch( ee ) ...{
3 d# [9 ]5 R7 @4 K+ K1 h      var response= ! U: S, G7 [2 S9 F: t2 z$ J( Z
        app.alert("打开书签错误. 是否删除本书签?", 2, 2,"删除书签");
& G+ x" }' d, q$ y" b      if( response== 4 && index< data.length ) ...{$ G1 V/ p# ?+ ~( y/ w
        data.splice( index, 1 );
3 C5 u4 s5 g5 ~3 H2 Q; |4 ^! D7 X        SaveData( data );8 @: b+ m# r2 c& S1 i
      }6 }" h% c3 _( U( k
    }0 D0 w4 O" a/ z" L
  }& V# ?9 ~0 }6 C8 X5 A
}
) z6 E; R5 s1 w9 @. u! J  Gfunction DropBookmark() ...{
" J* _, H( ]5 f# x7 q( W- c  // modelled after ShowBookmarks()
& Y! m  Y5 F6 Q& b  var data= GetData();
& I" j! o# ~6 O  var items= '';1 r; t6 s/ k3 ?0 `/ }8 Z3 `
  for( ii= 0; ii< data.length; ++ii ) ...{
* ]+ k+ ^  g+ [    if( ii!= 0 )
( P5 X' y1 ~/ Y8 T4 }      items+= ', ';$ ~3 j# |) M; |: e7 \7 q- \, T
    items+= '"'+ ii+ ': '+ data[ii][0]+ '"';
( @+ m  v5 [2 L1 F  }+ N% [0 c$ L# K" J  f, D
  var command= 'app.popUpMenu( '+ items+ ' );';9 L4 P: J' q+ e0 B, s5 k4 l
  var selection= eval( command );
8 h! r8 \& Q7 L# J& n& ^  if( selection== null ) ...{
1 H6 a/ j1 U7 y4 z    return; // exit
, @$ V# |! S3 J/ p/ z  }
# Z! F& T- @$ g9 e  var index= 0;
, V9 o5 i& {* K6 R( ?$ q  index= eval( selection.substring( 0, selection.indexOf(':') ).toString() );
: w+ o" l6 p$ e  if( index< data.length ) ...{
4 W3 G  `$ E& V, w/ w' V    data.splice( index, 1 );
1 ]7 I& ?9 W$ b/ Z- F2 U    SaveData( data );
- M7 w4 M8 ^2 m/ Z8 {3 J  }
- R. ~8 v, O% B}
+ U! R8 S2 |2 A8 i- w" |: a9 Cfunction ClearBookmarks() ...{6 _3 i6 O! A% {& R4 u6 I0 W. i7 ~
  if( app.alert("确认要清除所有的书签吗?", 2, 2,"删除书签" )== 4 ) ...{
" Y  `- Y$ v7 x- b  U4 ]+ e    SaveData( new Array(0) );
: c+ l1 q2 N$ Q; ~  }3 o# Y* D% i' B
}
5 [8 E# `5 j, E; q! yapp.addMenuItem( ...{8 Q  L, @0 V8 f" m- i: n
cName: "-",              // menu divider7 B* C5 A( B& \, Q$ Y
cParent: "View",         // append to the View menu
5 B) Q$ A* P6 f: V( W4 NcExec: "void(0);" } );. F2 y; q; C  g5 e
app.addMenuItem( ...{
/ A/ U! c0 V% v# XcName: "设置本页为书签(&B)",
9 Q$ S& F; ^# TcParent: "View",
3 t4 q1 q0 w3 vcExec: "AddBookmark();",2 [! L+ o" A* A5 \1 k5 C
cEnable: "event.rc= (event.target != null);" } );0 l  p* x/ b' _& v% q
app.addMenuItem( ...{( z* O+ B. `8 l
cName: "转到指定书签(&T)",
; g' [2 \" h7 ?# o  J, _0 R" zcParent: "View",+ L; V+ f( g/ V+ i
cExec: "ShowBookmarks();",
' ]1 C  `3 m" Z' }4 I6 zcEnable: "event.rc= (event.target != null);" } );1 [6 w( x: e; R/ W: x& ^( Y
//cEnable: "event.rc= true;" } );2 w* j) `0 B' @) G5 {, _4 a! ?
app.addMenuItem( ...{/ n4 U7 i4 }# A5 ^) |" Q
cName: "删除一个书签(&D)",
& T: ?. x) H. Q: w8 i1 ]( WcParent: "View",
& R. g& H0 N( q0 mcExec: "DropBookmark();",
" `& X7 X4 u; C& d$ X/ L, FcEnable: "event.rc= (event.target != null);" } );! [; Q  {1 d. ~2 o( }
app.addMenuItem( ...{
3 T- ]& f& p: m6 q' bcName: "清除所有书签(&C)",5 O' u; s  e( @, ^
cParent: "View",9 Z$ m" @% Q, M2 F# D, G" o
cExec: "ClearBookmarks();",9 l2 F. \) p' [5 g) `4 |# ~
cEnable: "event.rc= true;" } );
9 S$ P% \0 ]) u8 O4 将文件拷贝到C:\Program Files\Adobe\Reader 8.0\Reader\Javascripts目录下/ _! O0 h# x. W+ p* X# b" C( ^
5 重新打开Adobe Reader,看看下面的图形,相信不用说任何东西,大家都会用了/ Y5 O- R7 C* w3 x- V! c) v, H6 ]
) C0 d% M6 h! ], k4 H
) v9 ?. h  r8 A0 y/ ^; `  A
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aohan/archive/2008/02/20/2108051.aspx




欢迎光临 下沙论坛 (http://bbs.xiasha.cn/) Powered by Discuz! X3.3