テキストにリンクを追加

TOP > サンプル / 関数 > *      [...]


相馬野馬追@TCK

 

概要

PDFの指定テキストに以下のリンクを追加します。

  1. PDF内のページ移動
  2. 他のPDFファイルを開く
  3. Webページを開く

処理方法は大きく2つです。

  1. 指定テキストのページ番号と座標を取得
  2. その情報でリンクを追加する為のAcrobat JavaScriptを実行

共にVBAからAcrobat OLE経由でAcrobat JavaScriptを実行して処理をします。

 

関数の利用

関数:文字列のページ番号と座標を返す」で紹介している関数: GetTextsGetRects を使用して、文字列検索をさせ、そのページ番号と座標を取得します。その結果を使ってリンクを追加します。

 

サンプル

テキストを検索し、それに以下のリンクを設定します。

  • "マニュアルを参照": ABC.pdfを開く
  • "PDF": pdf-file.nnn2.comを開く
  • "目次の先頭": ページ番号=4 へ移動

以下は実行するAcrobat JavaScriptのサンプルです。

001 var link = this.addLink(0, [200,200,400,300]); 002 link.setAction( "this.pageNum = 9"); 003 link.borderColor = color.red; 004 link.borderWidth = 1;

 

参照設定が2つ必要です。

ダウンロード:sample-AddLinkTexts.xls

 

 

001 Option Explicit 002 003 '************************************************** 004 ' 005 ' サンプル:テキストにリンクを追加 006 ' 007 ' 作成:2020/04/01 008 ' 更新:2020/06/18 009 ' 010 ' https://pdf-file.nnn2.com/?p=1100 011 ' 012 ' 注意:傾いた文字列には正しくリンクを設定出来ない 013 ' 場合が有ります。 014 ' 015 '************************************************** 016 017 Sub Sample_AddLinkTexts() 018 019 Dim start As Double: start = Timer 020 Debug.Print "Sample_AddLinkTexts " & Time 021 022 Dim bRet As Boolean 023 Dim sFilePathIn As String 024 Dim sFilePathOut As String 025 Dim iOutCnt As Long 026 Dim i1 As Long 027 Dim gSerch(6) As type_SerchTexts 028 Dim gRects() As type_TextRect 029 Dim sAction(6) As String 030 031 '初期化 032 i1 = 0 033 '▼検索テキスト 034 gSerch(i1).sSerchText = "マニュアルを参照" 035 ' リンクで動作するAcrobat JavaScript 036 sAction(i1) = "app.openDoc('/D/ABC/xyz.pdf');" 037 'sAction(i1) = "app.openDoc('/I//サンプル/test-001.pdf');" 038 i1 = i1 + 1 039 gSerch(i1).sSerchText = "PDF" 040 sAction(i1) = "this.getURL('https://pdf-file.nnn2.com/');" 041 i1 = i1 + 1 042 gSerch(i1).sSerchText = "目次の先頭" 043 sAction(i1) = "this.pageNum=3;" 044 i1 = i1 + 1 045 gSerch(i1).sSerchText = "プロパティ" 046 sAction(i1) = "this.pageNum=3;" 047 i1 = i1 + 1 048 gSerch(i1).sSerchText = "メソッド" 049 sAction(i1) = "this.pageNum=3;" 050 i1 = i1 + 1 051 gSerch(i1).sSerchText = "追加機能がありますが" 052 sAction(i1) = "this.pageNum=3;" 053 054 '▼テキストを検索し、ページ番号と座標を得る 055 sFilePathIn = ThisWorkbook.Path & "\test-003.pdf" 056 'See URL. https://pdf-file.nnn2.com/?p=1099 057 bRet = GetTextsGetRects(sFilePathIn, -1, -1, _ 058 gSerch, gRects, iOutCnt) 059 060 '▼リンクを追加する 061 Dim objAcroApp As New Acrobat.AcroApp 062 Dim objAcroAVDoc As New Acrobat.AcroAVDoc 063 Dim objAcroPDDoc As New Acrobat.AcroPDDoc 064 Dim objAcroPDPage As Acrobat.AcroPDPage 065 Dim objAcroAVPageView As Acrobat.AcroAVPageView 066 Dim objAFormApp As AFORMAUTLib.AFormApp 067 Dim objAFormFields As AFORMAUTLib.Fields 068 069 objAcroApp.CloseAllDocs 070 objAcroApp.Hide '稀に表示されるので隠す 071 072 'PDFファイルを開く 073 bRet = objAcroAVDoc.Open(sFilePathIn, "") 074 075 Set objAcroPDDoc = objAcroAVDoc.GetPDDoc 076 Set objAFormApp = CreateObject("AFormAut.App") 077 Set objAFormFields = objAFormApp.Fields 078 Set objAcroPDDoc = objAcroAVDoc.GetPDDoc 079 080 Dim sWkQuads() As String 081 Dim i2 As Long 082 Dim sAJS As String 083 Dim sReturn As String '未使用 084 085 Const sAcrobatJavaScript As String = _ 086 "var link = this.addLink(@P, [@1,@2,@3,@4]) ;" & _ 087 "link.setAction(""@A"") ;" & _ 088 "link.borderColor = @C ;" & _ 089 "link.borderWidth = @W ;" 090 091 For i1 = 0 To iOutCnt 092 With gRects(i1) 093 If .iSearchNo = -1 Then Exit For 094 ' Debug.Print "Text(" & i1 & ")=" & _ 095 ' gSerch(.iSearchNo).sSerchText & _ 096 ' " Index=" & .iSearchNo & _ 097 ' " Page=" & .iPageNo & _ 098 ' " Quads=" & .sQuads 099 sWkQuads = Split(.sQuads, ",") 100 For i2 = 0 To UBound(sWkQuads) Step 8 101 'Acrobat JavaScriptの編集 102 sAJS = sAcrobatJavaScript 103 sAJS = Replace(sAJS, "@P", .iPageNo) 104 sAJS = Replace(sAJS, "@1", sWkQuads(i2 + JZ.iLeft)) 105 sAJS = Replace(sAJS, "@2", sWkQuads(i2 + JZ.iTop)) 106 sAJS = Replace(sAJS, "@3", sWkQuads(i2 + JZ.iRight)) 107 sAJS = Replace(sAJS, "@4", sWkQuads(i2 + JZ.iBottom)) 108 sAJS = Replace(sAJS, "@A", sAction(.iSearchNo)) 109 sAJS = Replace(sAJS, "@C", "color.blue") 110 sAJS = Replace(sAJS, "@W", 1) 111 'Acrobat JavaScript の実行 112 sReturn = objAFormFields.ExecuteThisJavascript(sAJS) 113 Next i2 114 End With 115 Next i1 116 117 'PDFファイルを別名で保存 118 sFilePathOut = Replace(sFilePathIn, ".pdf", "-AddLinks.pdf") 119 If objAcroPDDoc.Save(1, sFilePathOut) = False Then 120 MsgBox "PDFファイルへ保存出来ませんでした", _ 121 vbOKOnly + vbCritical, "実行エラー" 122 End If 123 124 '変更しないで閉じます。 125 bRet = objAcroAVDoc.Close(False) 126 'Acrobatアプリケーションの終了 127 objAcroApp.Hide 128 objAcroApp.Exit 129 'オブジェクトの開放 130 Set objAcroAVPageView = Nothing 131 Set objAcroPDPage = Nothing 132 Set objAcroPDDoc = Nothing 133 Set objAcroAVDoc = Nothing 134 Set objAFormApp = Nothing 135 Set objAFormFields = Nothing 136 Set objAcroApp = Nothing 137 138 Debug.Print "出力件数 = " & iOutCnt 139 Debug.Print "処理時間 = " & Timer - start 140 End Sub


 Highlight:プログラミング言語のソースコードを構文で色分け (GUI編)
 

関数: GetTextsGetRects のソースはコチラから持ってきてください。

 

実行結果

実行前です。

実行後です。

以下のリンク動作は正常に確認できました。

  • "マニュアルを参照": ABC.pdfを開く
  • "PDF": pdf-file.nnn2.comを開く
  • "目次の先頭": ページ番号=2へ移動

 

使用上の注意

  1. 座標が正しく検索できないことが有ります。詳細は「関数: GetTextsGetRects 」を御覧ください。
  2. テキスト(文字列)の回転角度によってはリンク枠が表示できないときが有ります。rect座標で指定しているのが原因です。Quads座標で指定できれば解決できるのですが、文法上出来ません。

 

Acrobat JavaScriptの説明

リンクを追加するAcrobat JavaScriptの各命令(メソッドとプロパティ)の説明です。

特に深く理解する必要は無いです。サンプルのやり方を真似るだけで結構です。

ココでの説明はメーカーのマニュアル「JavaScript™ for Acrobat® API Reference Adobe® Acrobat® SDK バージョン 8.0」とは異なり、Acrobat JavaScript専用の表現を無くしています。説明も関係する部分のみとしました。

*AD:ネット公開されている上記の日本語マニュアルを表示します。

 

1. addLink( nPage , [ Left , Top , Right , Bottom ] )

指定したページに、指定した座標で新しいリンクを追加します。位置情報のみを指定します。( *AD )

  • nPage:リンクを追加するページ番号。1ページ目は 0 です。
  • Left:座標Leftの値
  • Top:座標Topの値
  • Right:座標Rightの値
  • Bottom:座標Bottomの値

 

2. setAction

動作を示すAcrobat JavaScript コードを指定します。今回のリンクに関連する動作としては以下の3つが有ります。( *AD )

  1. PDF内のページ移動
    • 例:3ページ目に移動する。
      setAction( "this.pageNum = 2;" );
    • ページ番号の先頭は0です。
    • 次ページへの移動は
      setAction( "this.pageNum++;" );
       
  2. 他のPDFファイルを開く
    • 例:D:¥ABC¥xyz.pdf を開く。
      setAction( "app.openDoc( '/D/ABC/xyz.pdf ' );" );
    • パスはWindowsのパスでは無く、上記のような形式にします。
    • フォルダ名に日本語が入ってもOKです。
    • パスはシングルクォーテーション「'」で囲みます。
       
  3. Webページを開く
    • 例: pdf-file.nnn2.com を開く。
      setAction(" this.getURL( 'https://pdf-file.nnn2.com/' ); ");
    • URLはシングルクォーテーション「'」で囲みます。
       

 

3. borderColor

リンクの境界線の色を指定します。( *AD )

例:borderColor = color.red;

  • 白:color.white
  • 赤:color.red
  • 緑:color.green
  • 青:color.blue
  • シアン:color.cyan
  • マゼンタ:color.magenta
  • イエロー:color.yellow
  • ダークグレー:color.dkGray
  • グレー:color.gray
  • ライトグレー:color.ltGray

他の色を使いたい時はRGBやCMYKで指定してください。詳細はマニュアルを御覧ください。

 

4. borderWidth

リンクの境界線の幅を指定します。 ( *AD )

例:borderWidth = 1 ;

  • 0:なし
  • 1:細
  • 2:標準
  • 3:太

 

5. highlightMode

リンクの領域内でマウスボタンを押したときに使用する視覚効果を設定します。混乱させないためにもデフォルトの方がユーザーにはイイです。( *AD )

  • None:効果なし
  • Invert ( デフォルト):
  • Outline:アウトライン
  • Push:プッシュ

 

6. rect

リンクの矩形を表す 4 つの数値配列です。左上隅のx 座標、左上隅のy 座標、右下隅のx 座標、右下隅のy 座標を配列「[ Left , Top , Right , Bottom ]」を表します。( *AD )

例:今回は直に配列で指定するので省略。

 

備考

  • 処理時間は掛かります。業務での使用時はSSDなどの高速な環境をご用意ください。

 

参照

 

「テキストにリンクを追加」への3件のフィードバック

  1. 初めまして。内容拝見し、参考にさせいただいております。

    リンク貼り付けのメソッド(Sub Sample_AddLinkTexts())の参考例を用いて、参照先PDFファイルのページ指定を実装しようと試みましたができません。
    アドバイスいただけますと幸いです。

    参考には以下のとおりあるのですが、実装が出来ませんでした。
    https://kb2.adobe.com/jp/cps/511/511727/attachments/511727_js_api_reference.pdf
    P133
    例 6(Acrobat 8.0)文書を開いて、指定の名前の移動先にジャンプします。app.openDoc({ cPath: "/c/temp/myDoc.pdf", cDest: "myDest" });

    コメントアウト参考部分
    'sAction(i1) = "app.openDoc('/I//サンプル/test-001.pdf');"

    sAction(i1) = "app.openDoc({ cPath: /C//tmp/PDF1.pdf,cDest: " })"

    OS名 バージョン:Windows11
    Acrobat バージョン:Acrobat DC Pro
    ツール(Excel等) バージョン:Excel 2019

  2. 初めまして、上記に記載テキストにリンクを追加の例とAdobeのドキュメントを参考に、参照先ファイルの特定ページへジャンプをするメソッドを作成してみましたが、うまくいきません。
    何卒ご教示いただけますと幸いです。

    (記載の例)
    'sAction(i1) = "app.openDoc('/I//サンプル/test-001.pdf');"

    (Adobe内のドキュメント)
    app.openDoc({ cPath: "/c/temp/myDoc.pdf", cDest: "myDest" });

    (作成したコード)
    パターン1
    'sAction(i1) = "app.openDoc('/I//サンプル/test-001.pdf');"
    パターン2
    'sAction(i1) = "app.openDoc('/I//サンプル/test-001.pdf').pangeNum = 0;"

  3. dino さん はじめまして。

    パターン1は文法上も動作もOKですが、パターン2は文法上はNGです。
    実際の動作も検証し、Adobeのドキュメントも何度も見てみましたが、ご希望の手順でのページ移動の方法は無いです。但し、一定の条件が整えば可能な例が1つだけ有ります。

    【ケース1】
    sAction(i1) = "this.getURL('http://www.abc.com/xyz.pdf#page=10');"

    ネットワーク(URL)上のPDFならば上記のページ指定が可能です。当然ですがPDF表示はWebブラウザになります。ならば、URL部分をPCローカルに指定すれば良いのでは?と思いますが、

    【ケース2】
    sAction(i1) = "this.getURL('file:///D|/work/WW-4.pdf');"
    【ケース3】※ページ指定は無視される。
    sAction(i1) = "this.getURL('file:///D:/work/WW-4.pdf#page=10');"

    文法上はOKで、AcrobatのJavaScriptデバッガーでも実行できますが、リンク内に設定すると動作しません。環境設定も確認しましたが、問題点を見つけることは出来ませんでした。
    Adobeのドキュメントでページ移動に関するものは「pageNum」プロパティしかないです。但し、これはドキュメントの説明不足で、「現在のオブジェクト」を対象にするもので、リンク先で開いたPDFには機能しません。

    【ケース4】
    sAction(i1) = "var oDoc=app.openDoc('/D///work/WW-4.pdf'); oDoc.pageNum=10 ;"

    上記は文法上もOKでPDFも表示されますが、pageNumでエラーなります。
    Adobeのドキュメントに無いケースもいろいろと試してみましたが、出来るのはケース1だけです。
    ご検討ください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA



SAMURAI Plugin

コメントをする時は出来れば以下もお願いします。

  • OS名 バージョン
  • Acrobat バージョン
  • ツール(Excel等) バージョン
コメントにサンプルコードを入れる時はコードを全て全角文字列にしてください。コチラで半角に戻します。それでもエラーが回避できない時はコメント下さい。個別に対処します。



お仕事で当サイトを見ている方へ
考え込んだら、ご質問下さい。
一緒に解決策を考えましょう。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください