PDFをテキストに変換する方法(Excel VBAサンプル)

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


Method of conversion from PDF to Text.

説明

PDFをテキストに変換しファイル出力を行います。

2種類の形式でテキスト出力するサンプルです。

サンプル:ExcelのVBA

  • F8キーでステップ実行しながら動作確認出来ます。
  • 事前に参照設定もして下さい。
001 Option Explicit 002 003 Sub CommandButton21_Click() 004 005 Dim objAcroApp As New Acrobat.AcroApp 006 Dim objAcroAVDoc As New Acrobat.AcroAVDoc 007 Dim objAcroPDDoc As Acrobat.AcroPDDoc 008 Dim lRet As Long 009 Dim jso As Object 010 011 'Acrobatアプリケーションを起動する。 012 lRet = objAcroApp.Show 013 'PDFファイルを開いて表示する。 014 lRet = objAcroAVDoc.Open("E:¥save_as_xml.pdf", "") 015 'PDDocオブジェクトを取得する 016 Set objAcroPDDoc = objAcroAVDoc.GetPDDoc() 017 'JavaScriptオブジェクトを作成する。 018 Set jso = objAcroPDDoc.GetJSObject 019 020 'PDFをアクセステキスト(accesstext)に変換する。 021 jso.SaveAs "E:¥test-01A.txt", "com.adobe.acrobat.accesstext" 022 'PDFをプレーンテキスト(plain-text)に変換する。 023 jso.SaveAs "E:¥test-01P.txt", "com.adobe.acrobat.plain-text" 024 025 'PDFファイルを閉じます。 026 lRet = objAcroAVDoc.Close(1) 027 'Acrobatアプリケーションを終了する。 028 lRet = objAcroApp.Hide 029 lRet = objAcroApp.Exit 030 'OLEを行うとAcrobatが不安定になるので 031 '一応オブジェクトを強制開放する。 032 Set objAcroPDDoc = Nothing 033 Set objAcroAVDoc = Nothing 034 Set objAcroApp = Nothing 035 036 End Sub


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

補足

  1. Acrobat Readerでは出来ません。
    Acrobat本体がデフォルトでインストールされているパソコン環境だけです。
  2. accesstext(アクセステキスト):
    PDFに透明テキスト文字列があればテキスト変換されます。
    改行があれば、その位置で改行してテキスト出力されます。
  3. plain-text(プレーンテキスト):
    PDFの透明テキスト文字列があればテキスト変換されます。
    改行コードは無視されます。
    よって、2行が1行につながってテキスト出力され、文章としては読みずらいです。
    ページによってはテキストに変換されない場合もあります。
    この仕様は不明です。
    Acrobat SDK 8.1にある「Extending the Acrobat SaveAsXML Plug-in」save_as_xml.pdf の場合は2ページ目の内容がテキストの最後に変換されてテキスト出力されます。
    この形式に変換する目的も機能も当サイト管理者には理解出来ません。
  4. 上記サンプルでは objAcroApp.Show でAcrobatアプリ本体を起動表示しています。
    これはjso.SaveAs メソッドを連続で行うときに発生する不可解なエラー回避策です。
    高速化したいのならば objAcroApp.CloseAllDocs に置き換えて下さい。
  5. 当サンプルよりも以下の関数を利用してのテキスト変換をおすすめします。
    関数:PDFを特定のフォーマットに変換する
    当ページのサンプルよりも安全にテキスト変換が可能になります。

注意

  1. Acrobat SDK 8.1 に書かれているSaveAsメソッドの第2引数の説明が一部間違っています。
    以下が正解です。
    SDK:com.adobe.Acrobat.accesstext ※間違い
    SDK:com.adobe.Acrobat.plain-text ※間違い
    正解:com.adobe.acrobat.accesstext ※「a」1文字違う
    正解:com.adobe.acrobat.plain-text ※「a」1文字違う
    この情報は、"C:¥Program Files¥Adobe¥Acrobat 8.0¥Acrobat¥ExportTask.xml"ファイルに入っている内容から当サイト管理者が勝手に判断したものです。
    この「ExportTask.xml」ファイルに関する説明はAcrobat SDKにはありません。
  2. 当サイト作成「Acrobat SDK:正誤表」も参考にして下さい。
  3. OSがインストールされているC:ドライブへの保存は出来ません
    詳細は、「Acrobat JavaScript における「Safe Path」についての注意事項」を参照。

動作確認環境

  • WindowsXP Pro + SP3 +
    Acrobat 8.1.6 Pro + Office 2003 + フルMicrosoftUpdate

サンプル一覧

「PDFをテキストに変換する方法(Excel VBAサンプル)」への18件のフィードバック

  1. 初めてメールします。アクロバットプロ11で大量のTIFファイルをPDF化しOCRをかけようとしています。アクションウィザードを使えば、一つのフォルダーの中にある全てのファイルに対し、上記の処理はできます。ところが、なぜか、OCRができないファイルがあるために、そこで、ファイルが開いたまま止まってしまいます。原因はよくわかりません。そこで、VBAでOCRをかけ、もしも、30分以上、かかってもOCRが終了しない場合は、とっとと、次のファイルのOCRをするようなプログラムを組めないかと思っています。あるいは、もっと、良い手軽かもしれませんが、教えてください。よろしくお願いいたします。

  2. 倉崎 さん。
    はじめまして。

    VBA等の言語に関係無く、AcrobatのOCR機能部分をプログラミング操作できる命令等の部分は見つかりません。
    アクションウイザードの処理部分もプログラミング操作等が出来ないかと再調査しましたが、出来ないと、言うより出来る方法が見つかりませんでした。
    OCR処理でフリーズ?した場合にスキップ処理をさせたいという部分は理解できますが。

    TIFからPDFへ変換して、そのPDF上の文字画像をテキスト化をするにはAcrobat以外に選択肢は無いでしょう。
    唯一知っているPDFのテキスト化ソフトに「読んde!!ココ」が有りますが、2012年9月30日を持って当ソフトは販売終了となりました。
    ※今でも大事に使ってますが(汗
    「読取革命」と言うOCRソフトも有るらしいですが使った事を無いので仕様等は不明です。

    何か倉崎さんの助けになる様な情報を思案しましたが、見つかりません。
    残念です。

  3. 倉崎 さんへ。

    前のコメントで「見つからない」と返答しましたが・・・。

    以前から検討していた事が有り、現在はその手段が見つかっています
    と言っても「出来る」かはテストして見ないと分かりません。

    1ヶ月前からのテストで、Acrobat 10 以下のバージョンのアクション処理(バッチ処理)のプログラミング操作が可能な状態になっています。
    現在はその手法のドキュメント化(HTML)作業を行っています。
    それと同じ手法を使えばOCRの起動と稼働の監視が可能かもしれません。

    但し、Acrobat 11 に関してはアクション処理自体の仕様が下位バージョンと基本的に変わっているので、手法は同じですがプログラミング操作に関しては再検討(再作成)する必要が有る状態です。

    この内容が伝わる事を祈っています。

  4. いろいろとアドバイスありがとうございます。
    取り急ぎ、お礼を申し上げます。
    いろいろと試してみます。
    また、よろしくお願いいたします。

  5. いつも参考にさせていただいており、大変助かっております。

    質問なのですが、PDFの先頭ページのみをテキスト化する方法はございますでしょうか。
    もしご存知でしたらご教示いただけますと幸いです。

    どうぞよろしくお願いいたします。

  6. きゃべつ さん
    初めまして。

    テキスト化時にページ指定は無いので、一時的に先頭ページ以外を削除します。

    このページのサンプルの以下のコードの下に、
    Set objAcroPDDoc = objAcroAVDoc.GetPDDoc()

    以下を追加します。
    '2ページ目から最後までを削除する
    lRet = objAcroPDDoc.DeletePages(1, objAcroPDDoc.GetNumPages() - 1)

    詳細はAcroExch.PDDoc: DeletePages メソッドを御覧ください。
    なお、ページの削除をするので当ページのサンプルのように保存しないで閉じて下さい。
    テキスト化まで動作確認してないですが、多分大丈夫でしょう。

    参考になれば幸いです。

  7. 管理人様

    ありがとうございます、期待していた動作となりました、助かりました。

    もう1点質問なのですが、保護のかかったPDFファイル(開いたときにウィンドウ枠に 「~(ファイル名)~.pdf(保護) 」と出るタイプ)をテキスト化しようとすると、
    「この操作は、この文書では許可されていません。」
    とエラーポップアップが出て止まってしまいます。

    保護ファイルはテキスト化できなくて問題ないので、
     ①SaveAs メソッドの前に保護されているかどうか確認するif文を設定する
     ②エラーが出た後にポップアップを消すプログラムを入れる
    のいずれかで対応したいのですが、プログラムをお教えいただけませんでしょうか。

    また、先ほどは記載しておらず申し訳ございませんでしたが、私の環境は以下となります。
    OS:Windows 10 64bit
    Acrobat:Adobe Acrobat 8 professional
    Excel:2016

    お忙しいところお手数ですが、何卒よろしくお願いいたします。

  8. きゃべつ さんへ。

    以下をお試し下さい。
    Option Explicit
     
    Sub CommandButton21_Click()
     
    Dim objAcroPDDoc As New Acrobat.AcroPDDoc
    Dim lRet As Long
    Dim lPageCnt As Long
    Dim jso As Object
     
    Const CON_FILE = "I:¥AcroPDDoc¥Open\PasswordCopy.pdf"
     
    Const CON_TEXT1 = "I:¥AcroPDDoc¥text1.txt"
    Const CON_TEXT2 = "I:¥AcroPDDoc¥text2.txt"
     
    lRet = objAcroPDDoc.Open(CON_FILE)
    If lRet = 0 Then
    'このPDFは文書を開くときにパスワードが必要です。
    Debug.Print "PDFファイルはパスワードで保護されている。"
    GoTo Skip_02:
    End If
    lPageCnt = objAcroPDDoc.GetNumPages()
    lRet = objAcroPDDoc.DeletePages(1, lPageCnt - 1)
    If lRet = 0 Then
    'PDF文書はセキュリティ(パスワード)で保護されているので
    ' ページの削除は出来ない。
    Debug.Print "PDFの編集は出来ない。"
    GoTo Skip_01:
    End If
     
    Set jso = objAcroPDDoc.GetJSObject
    'PDFをアクセステキスト(accesstext)に変換する。
    jso.SaveAs CON_TEXT1, "com.adobe.acrobat.accesstext"
    'PDFをプレーンテキスト(plain-text)に変換する。
    jso.SaveAs CON_TEXT2, "com.adobe.acrobat.plain-text"
    Set jso = Nothing
     
    Skip_01:
    lRet = objAcroPDDoc.Close
     
    Skip_02:
    Set objAcroPDDoc = Nothing
     
    End Sub

    ・PDFファイルを開くときのパスワード付き
    ・PDF文書のコピー&編集に付いたパスワード付き
    の2種類対応版です。

    正確にPDFの文書プロパティの保護情報を調べたいときは上記のOLEを使用したサンプルでは無理です。
    別途、コマンドラインの別ソフトが必要になる場合が有ります。
    ※例:qpdf.exe xxx.pdf --show-encryption > text.txt
    ※上記例のtext.txtの内容を読み込んで判断する。

    各メソッドは該当ページを御覧ください。

    希望通りの処理が出来るかの確認をお願いします。

  9. お忙しい中ご回答いただきありがとうございます。大変助かります。

    2ページ以上のPDFファイルについては今回お教えいただいたコードで希望の動作となることを確認いたしました。

    ただし、1ページのPDFファイルのときは保護されていなくてもエラーとなってしまうので、似たようなロジックで回避してみました。
    (貴サイトにあるものを色々試しましたが、今のところ使えそうなのがSaveメソッドしか見つかりませんでした。。)

    ファイルが上書きされてしまうのが難点ですが、一旦別のフォルダにコピーしてから実行すればいいので最悪これでもいいかなと思っております。
    もし、1ページのファイルに対しても使えるロジックをなにかご存知でしたら、再三で恐縮ですがお教えいただけると非常に助かります。

    どうぞよろしくお願いいたします。


    プログラムコードを記載したところエラーになってしまいましたが、
    「lRet = objAcroPDDoc.DeletePages(1, lPageCnt - 1)」の下に

    '別名でPDFファイルを保存する
    lRet = objAcroPDDoc.Save(&H20, "C:\Users\temporary.pdf") 'なぜか~~.pdfで上書きされてしまう
    を追加しました。

  10. きゃべつ さんへ。

    >・・1ページのファイルに対しても使えるロジック・・

    If lPageCnt > 1 Then
    lRet = objAcroPDDoc.DeletePages(1, lPageCnt - 1)
    End If

    とすればイイのでは?
    objAcroPDDoc.GetNumPages()の結果が入ったlPageCnt にページ数が入っているので、1ページ以上の時のみ実行する。
    lPageCnt の内容を見て処理をすればイイと思います。

  11. ご回答いただき、ありがとうございました。

    そちらのロジックですと、
    1ページしかない&保護されているPDF
    でポップアップを回避できなくなってしまうので断念いたしました。。

  12. きゃべつ さんへ。

    どうやら、私がうまく質問内容を理解できてないみたいです。
    最初から読み返してみました。

    >・・PDFの先頭ページのみをテキスト化する方法・・

    これが最初の質問で一番の目的と見ました。

    >・・保護のかかったPDFファイル・・・・エラーポップアップが出て止まってしまいます。

    これもサンプルで 2箇所でlRetの結果を見て処理する、でOKと見ました。

    >・・1ページのPDFファイルのときは保護されていなくてもエラーとなってしまう・・

    これもlPageCntの判断で回避できる。ただし・・、

    >・・がSaveメソッドしか見つかりません・・

    この意味が不明です。なぜ保存する必要が有るのか?
    テキスト化(のみ)が目的と思っていたのですが・・。

    >ファイルが上書きされてしまうのが難点・・

    サンプルは上書きしないで閉じています。
    lRet = objAcroPDDoc.Close
    どこで上書きするのでしょうか?

    こちらの提示したサンプルは全ての要件を満たしておりません。
    2ページ目以降を削除しているのは、テキスト化するときにページ指定が出来ないので、その対処方法としてです。削除したPDFを保存する必要は無いです。サンプルは保存せずに閉じています。

    と書きましたが、「何か私が見落としている」のでしょう。
    すこし時間を置いて、もう一度最初からコメントを見直すつもりです。

  13. 管理人様

    お世話になっております。

    読み返してみましたが、私の説明が明らかに不足しておりました。
    大変失礼いたしました。

    今回私が行いたいのは、
    「PDFの1ページ目をテキスト化し、保存すること」
    「ただし、保護がかかっているPDFについてはスキップすること」
    です。

    7/29にいただいたご回答(2ページ目以降を削除できるかどうかで、保護状況を確認する)で、
    ①保護なし複数ページPDF⇒テキスト化
    ②保護あり複数ページPDF⇒スキップ
    ③保護なし単ページPDF⇒【テキスト化】
    ④保護あり単ページPDF⇒スキップ
    となり③のパターンでテキスト化できませんでした。

    7/31にいただいたロジックを含めると
    ①②③はOKですが、④のパターンでエラーメッセージが出てしまいます。
    ("If lPageCnt > 1 Then" にひっかからず、テキスト変換まで進んでしまう)

    7/31のコメントの意味としては、
    「2ページ目以降を削除できるかどうかで、保護状況を確認する」を
    「&H20で保存できるかどうかで、保護状況を確認する」と変更したら③もクリアできそうです、
    (ただし、この確認を行う過程でPDFが上書きされてしまう)
    という内容でした。
    (3,4ファイル試しただけで、この方法ですべてのファイルの保護状況を確認できるかは疑問です)

    最後の段落の内容があまりに突飛なため混乱させてしまったかと思います。
    申し訳ございませんでした。

    現在の質問としては、「保護状況を確認するためにもう少しいい方法はないか」でございます。
    実行速度の観点からQpdfはなるべく避けたいと考えています。

    長文・駄文で申し訳ございませんが、どうぞよろしくお願いいたします。

  14. きゃべつ さんへ。
    イチから見直しました。

    Sub Call_PrintSave()
     
     Dim objAcroPDDocNew As New Acrobat.AcroPDDoc
     Dim objAcroPDDoc  As New Acrobat.AcroPDDoc
     Dim lRet      As Long
     Dim jso      As Object
     
     Const CON_FILE = "I:\AcroPDDoc\Open\NoPassword-1.pdf"
     
     Const SAVE_FILE = "I:\AcroPDDoc\Open\temporary.pdf"
     
     Const CON_TEXT1 = "I:\AcroPDDoc\Open\text1.txt"
     Const CON_TEXT2 = "I:\AcroPDDoc\Open\text2.txt"
     
     '① 空(0ページ)のPDFファイルを作成する
     lRet = objAcroPDDocNew.Create()
     
     '② 処理対象のPDFを開く
     lRet = objAcroPDDoc.Open(CON_FILE)
     If lRet = 0 Then
      '※このPDFは文書を開くときにパスワードが必要です。
      Debug.Print "PDFファイルはパスワードで保護されている。"
      GoTo Skip_02:
     End If
     
     '③ 1ページ目を取り出し、空のPDFへ入れる(コピーする)
     lRet = objAcroPDDocNew.InsertPages(-1, objAcroPDDoc, 0, 1, False)
     If lRet = 0 Then
      '※PDF文書はセキュリティ(パスワード)で保護されているので
      ' ページの抽出(コピー)は出来ない。
      Debug.Print "PDFは保護されていて抽出は出来ない。"
      GoTo Skip_01:
     End If
     
     '④ 1ページ目からテキストを取り出す
     Set jso = objAcroPDDocNew.GetJSObject
     'PDFをアクセステキスト(accesstext)に変換する。
     jso.SaveAs CON_TEXT1, "com.adobe.acrobat.accesstext"
     'PDFをプレーンテキスト(plain-text)に変換する。
     jso.SaveAs CON_TEXT2, "com.adobe.acrobat.plain-text"
     lRet = objAcroPDDocNew.Close()
     Set jso = Nothing
     
     '⑤ PDFを保存する。
     lRet = objAcroPDDoc.Save(&H1 + &H20, SAVE_FILE)
     
     '⑥ 保護(ページの編集)のチェックを行う。
     ' ※この処理は保険です。
     If objAcroPDDoc.GetNumPages() > 1 Then
      '2ページ目のみ削除する。※時間の短縮
      lRet = objAcroPDDoc.DeletePages(1, 1)
      If lRet = 0 Then
       '※PDF文書はセキュリティ(パスワード)で保護されているので
       ' ページの削除は出来ない。
       Debug.Print "PDFは保護されていて編集(ページ削除)は出来ない。"
       '以前に保存したファイルを削除する
       Kill CON_TEXT1
       Kill CON_TEXT2
       Kill SAVE_FILE
      End If
     End If
     
    Skip_01:
     lRet = objAcroPDDoc.Close
     
    Skip_02:
     Set objAcroPDDocNew = Nothing
     Set objAcroPDDoc = Nothing
     
    End Sub

    説明:

    ① ゼロページの空のPDFを仮に作ります
    OLEではゼロページのPDFを基本的に許しませんが、ココだけはOKです。

    ② 処理したいPDFを開きます。※「AのPDF」とこの後は呼びます。

    ③ AのPDFの1ページ目を空のPDFへコピーします。
    ここで「抽出」の保護が有れば、エラー扱いにします。

    ④ 1ページがコピーされた空のPDFを使って、テキスト化を行います。

    ⑤ AのPDFを別名で保存します。
    別名で保存する時は引数に「&H1」が必要です。無いと別名は無視されて上書きされます。

    ⑥ は保険です。
    「編集」の保護がかかっている場合は保存したテキストとPDFを削除します。
    「抽出(コピー)」出来て、「編集(削除)」が出来ないPDFには出会ったことは無いですが、100%無いと言う保証はないので入れました。不要ならば削除して下さい。
    Qpdfを使って厳密に保護情報をチェックしない場合は、少しカッコ悪い形ですが、処理速度を考えると、こうなるのかな?、と思いました。

    ご検証ください。

  15. 管理人様

    お世話になっております。
    おかげさまでようやく意図していた動作を確認することができました。
    ”objAcroPDDoc.Open(CON_FILE)” の部分で若干動作がもたつく傾向がありますが、
    こればかりは仕方ないですね。

    根気強くご説明いただき、大変感謝しております。
    本当にありがとうございました。
    またなにかございましたら相談させてください。

コメントを残す

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

CAPTCHA


出来るだけ早く返答する様には心がけています。
が、遅くなる時もありますのでご了承ください。


SAMURAI Plugin

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

  • OS名 バージョン
  • Acrobat バージョン
  • ツール(Excel等) バージョン
コメントにサンプルコードを入れるとエラーになる場合が有ります。その時はコードの前後に <code> ・・・</code> タグを入れてください。

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