監視フォルダに格納されたスキャンした請求書(イメージのPDF・DocuWorks文書)を深層学習OCRで読み取り、取引先コード・請求金額・請求日を取得します。取得した値を文書属性に設定し、「請求書_取引先コード_請求日」のファイル名にして出力フォルダへ移動します。
文字の読み取りには、深層学習OCRの PaddleOCR を使います。DocuWorksのOCRは使わないので、DocuWorks Ver.9 のOCRの制限解除のライセンスは不要です。PDFだけを処理する場合は、DocuWorksのインストールも不要です。(Version 2.7.0から。64ビットのWindowsが必要です。深層学習 OCR について)
読み取る位置(領域)は、テキスト抽出支援ツールで、スキャンした文書の画像の上で選ぶだけで設定できます。帳票の種類が複数あっても、帳票毎の取得マクロを作成すれば対応できます。
テキストを持ったPDFから読み取る場合は、PDFのテキスト抽出と属性設定2 を御覧ください。マクロの形は同じで、PDF_EXTRACT_TEXT が PDF_OCR_TEXT に変わるだけです。
eDocArrangement2のメイン画面のツールメニューからテキスト抽出支援ツールを作成するときに、「読み方」を「OCR (画像から読む)」にします。ブラウザーで開くと、ページの画像の上に、深層学習OCRで読み取った文字のまとまりが赤枠で表示されます。

取り出したい文字の領域を選ぶと、OCRの設定(ツールを作成したときと同じ解像度)と PDF_OCR_TEXT(DocuWorks文書の場合は DW_OCR_TEXT)のマクロが生成されます。この設定例では、生成されたマクロに、次の処理を書き足しています。
「御得意様コード(10001)」から数字だけを取り出す(REGEX_CAPTURE)。
請求金額のカンマを削除する。
取引先コードと請求日が読み取れなかった場合は、エラーフォルダへ分ける。
移動するときのファイル名を作る(請求日は DATE_ADD で yyyyMMdd の形にする)。
マクロ PDF_CREATE_OCR_TOOL・DW_CREATE_OCR_TOOL でもテキスト抽出支援ツールを作成できます。OCRのマクロの詳細は PDF_OCR_TEXT・DW_OCR_TEXT を御覧ください。
サンプルの請求書(イメージのPDFとイメージのDocuWorks文書)を処理した結果です。
|
入力 |
出力 |
文書属性 |
|---|---|---|
|
請求書_スキャン.pdf |
20_出力\請求書_10001_20250531.pdf |
取引先コード:10001 |
|
請求書_スキャン.xdw |
20_出力\請求書_10001_20250531.xdw |
取引先コード:10001 |
取引先コードや請求日が読み取れなかった文書(白紙のページなど)は 30_エラー\読み取りエラー フォルダへ、開けない文書などのエラーは 30_エラー フォルダへ移動します。
読み取りには、1ページ(A4・300dpi)で1~2秒ほどかかります(パソコンの性能と、ページの文字の量によって変わります)。この設定例のように狭い領域を指定すると、領域の周りだけを読み取ります。弊社のPCでは、サンプルの2つの文書の処理(読み取り・文書属性の設定・移動)が約1.3秒で終わりました。
C:\Homeの下に、以下のような構成でフォルダを作り、準備します。
フォルダ構成は以下の通りです。
以下のリンクから完成した設定をダウンロードしていただくことができます。
以下のフォルダに解凍すると設定が適用されます。
C:\Users\ユーザー名\AppData\Roaming\TechnoStyle\eDocArrangement2
スケジュール設定(10_入力フォルダを10秒間隔で監視して処理を実行する)も含まれています。90_System\10_Tool のサンプルは、テキスト抽出支援ツールの作成と、処理を試し直すときに使います。
グローバルデータの内容は以下の通りです。
|
名前 |
値 |
|---|---|
DemoTopFolder |
C:\Home\eDocArrangement2\Demo |
スキャンした請求書(PDF・DocuWorks文書)を深層学習OCRで読み取り、取引先コード・請求金額・請求日を文書属性に設定して、ファイル名に付けて移動します。
ログ設定
共通ログ設定の内容でログを出力する。
メイン画面のファイルリストを対象に繰り返し処理を行う。
ループ毎にユーザーデータをクリアする。
以下の条件を判定して処理を分岐する。
{%IF({%TO_LOWER({%GET(Extension)})}=.pdf,True,False)}
以下のマクロを実行する。
#判定を初期化
{%SET_U(wk,結果,True)}
#PDFファイルをオープン
{%PDF_OPEN({%GET(FullPathFileName)})}
# 座標領域を設定
{%SET_U(領域指定,Page,All,取引先コード,X,22.5)}
{%SET_U(領域指定,Page,All,取引先コード,Y,11.8)}
{%SET_U(領域指定,Page,All,取引先コード,BottomRightX,58.5)}
{%SET_U(領域指定,Page,All,取引先コード,BottomRightY,18.3)}
{%SET_U(領域指定,Page,All,請求金額,X,139.9)}
{%SET_U(領域指定,Page,All,請求金額,Y,69.47)}
{%SET_U(領域指定,Page,All,請求金額,BottomRightX,168.25)}
{%SET_U(領域指定,Page,All,請求金額,BottomRightY,74.47)}
{%SET_U(領域指定,Page,All,請求日,X,244.41)}
{%SET_U(領域指定,Page,All,請求日,Y,12.58)}
{%SET_U(領域指定,Page,All,請求日,BottomRightX,262.02)}
{%SET_U(領域指定,Page,All,請求日,BottomRightY,18.14)}
# OCRの設定 (テキスト抽出支援ツールを作ったときと同じ解像度で読む)
{%SET_U(OCR設定,Dpi,300)}
# PDF OCRテキスト抽出
{%PDF_OCR_TEXT(1,抽出データ,領域指定,OCR設定)}
# テキストを取得
{%SET_U(属性,取引先コード,{%JOIN(抽出データ,Pages,1,Rect,取引先コード,Texts, )})}
#「御得意様コード(10001)」の数字だけを取得
{%SET_U(属性,取引先コード,{%REGEX_CAPTURE((\d+),{%GET_U(属性,取引先コード)})})}
{%PDF_SET_DOCUMENT_ATTRIBUTE(取引先コード,{%GET_U(属性,取引先コード)})}
{%SET_U(属性,請求金額,{%JOIN(抽出データ,Pages,1,Rect,請求金額,Texts, )})}
#カンマを削除
{%SET_U(属性,請求金額,{%REPLACE({%GET_U(属性,請求金額)},|,,)})}
{%PDF_SET_DOCUMENT_ATTRIBUTE(請求金額,{%GET_U(属性,請求金額)})}
{%SET_U(属性,請求日,{%JOIN(抽出データ,Pages,1,Rect,請求日,Texts, )})}
{%PDF_SET_DOCUMENT_ATTRIBUTE(請求日,{%GET_U(属性,請求日)})}
#取引先コードと請求日が読み取れなければ業務エラー
{%IF({%GET_U(属性,取引先コード)}=,
{%SET_U(wk,結果,False)}
,)}
{%IF({%IS_DATE({%GET_U(属性,請求日)})}=False,
{%SET_U(wk,結果,False)}
,)}
#クローズ
{%PDF_CLOSE()}
#移動するときのファイル名 (請求書_取引先コード_請求日)
{%IF({%GET_U(wk,結果)}=True,
{%SET_U(work,ファイル名,請求書_{%GET_U(属性,取引先コード)}_{%DATE_ADD({%GET_U(属性,請求日)},yyyyMMdd)}{%GET(Extension)})}
,)}
DocuWorksファイル「{%GET(FullPathFileName)}」を読み書き可能でオープンする。
以下のマクロを実行する。
#判定を初期化
{%SET_U(wk,結果,True)}
# 座標領域を設定
{%SET_U(領域指定,Page,All,取引先コード,X,22.5)}
{%SET_U(領域指定,Page,All,取引先コード,Y,11.8)}
{%SET_U(領域指定,Page,All,取引先コード,BottomRightX,58.5)}
{%SET_U(領域指定,Page,All,取引先コード,BottomRightY,18.3)}
{%SET_U(領域指定,Page,All,請求金額,X,139.9)}
{%SET_U(領域指定,Page,All,請求金額,Y,69.47)}
{%SET_U(領域指定,Page,All,請求金額,BottomRightX,168.25)}
{%SET_U(領域指定,Page,All,請求金額,BottomRightY,74.47)}
{%SET_U(領域指定,Page,All,請求日,X,244.41)}
{%SET_U(領域指定,Page,All,請求日,Y,12.58)}
{%SET_U(領域指定,Page,All,請求日,BottomRightX,262.02)}
{%SET_U(領域指定,Page,All,請求日,BottomRightY,18.14)}
# OCRの設定 (テキスト抽出支援ツールを作ったときと同じ解像度で読む)
{%SET_U(OCR設定,Dpi,300)}
# XDW OCRテキスト抽出
{%DW_OCR_TEXT(XDW文書オープン1,1,抽出データ,領域指定,OCR設定)}
# テキストを取得
{%SET_U(属性,取引先コード,{%JOIN(抽出データ,Pages,1,Rect,取引先コード,Texts, )})}
#「御得意様コード(10001)」の数字だけを取得
{%SET_U(属性,取引先コード,{%REGEX_CAPTURE((\d+),{%GET_U(属性,取引先コード)})})}
{%DW_SET_DOCUMENT_ATTRIBUTE(XDW文書オープン1,取引先コード,{%GET_U(属性,取引先コード)})}
{%SET_U(属性,請求金額,{%JOIN(抽出データ,Pages,1,Rect,請求金額,Texts, )})}
#カンマを削除
{%SET_U(属性,請求金額,{%REPLACE({%GET_U(属性,請求金額)},|,,)})}
{%DW_SET_DOCUMENT_ATTRIBUTE(XDW文書オープン1,請求金額,{%GET_U(属性,請求金額)})}
{%SET_U(属性,請求日,{%JOIN(抽出データ,Pages,1,Rect,請求日,Texts, )})}
{%DW_SET_DOCUMENT_ATTRIBUTE(XDW文書オープン1,請求日,{%GET_U(属性,請求日)})}
#取引先コードと請求日が読み取れなければ業務エラー
{%IF({%GET_U(属性,取引先コード)}=,
{%SET_U(wk,結果,False)}
,)}
{%IF({%IS_DATE({%GET_U(属性,請求日)})}=False,
{%SET_U(wk,結果,False)}
,)}
#移動するときのファイル名 (請求書_取引先コード_請求日)
{%IF({%GET_U(wk,結果)}=True,
{%SET_U(work,ファイル名,請求書_{%GET_U(属性,取引先コード)}_{%DATE_ADD({%GET_U(属性,請求日)},yyyyMMdd)}{%GET(Extension)})}
,)}
「XDW文書オープン1」でオープンされた文書をクローズする。クローズ前に文書を保存する。
以下の条件を判定して処理を分岐する。
処理階層内のエラー回数が0回。
以下の条件を判定して処理を分岐する。
{%GET_U(wk,結果)}
文書を以下の通り移動する。
|
移動元 |
{%GET(FullPathFileName)} |
|
移動先 |
{%GET_G(DemoTopFolder)}\{%GET(SettingName)}\20_出力 |
ファイル名を「{%GET_U(work,ファイル名)}」に変更する。
移動先に同名の文書がある場合は、ファイル名に連番を付与する。
コピー後に削除を行う。
文書を以下の通り移動する。
|
移動元 |
{%GET(FullPathFileName)} |
|
移動先 |
{%GET_G(DemoTopFolder)}\{%GET(SettingName)}\30_エラー\読み取りエラー |
移動先に同名の文書がある場合は、ファイル名に連番を付与する。
コピー後に削除を行う。
文書を以下の通り移動する。
|
移動元 |
{%GET(FullPathFileName)} |
|
移動先 |
{%GET_G(DemoTopFolder)}\{%GET(SettingName)}\30_エラー |
移動先に同名の文書がある場合は、ファイル名に連番を付与する。
コピー後に削除を行う。