3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UiPath (produced with UiPath Friends)Advent Calendar 2024

Day 20

【UiPath】StudioWeb × Document Understanding 実装上のポイント2

Last updated at Posted at 2024-12-19

はじめに

  • 本記事は、StudioWeb で Document Understanding(モダンプロジェクト) を扱いたい方向けの内容です。
  • 本記事は以下の記事の続きで、細かいトピックベースの実装ポイント解説がメインです。
  • 記事の内容は、個人の見解または確認結果であり、UiPath の公式見解ではありません。
  • 製品仕様や参考画像は 24.10 バージョンのもので構成しています。

トピック一覧

# 1.パスワード付きのPDFの読み取り
# 2.ログに出力した読み取り結果の取得
# 3.特定領域の値の取得

1.パスワード付きのPDFの読み取り

「ドキュメントデータを抽出」アクティビティのプロパティにはパスワード入力欄はありません。
このため、パスワード付きのPDFのデータを抽出したい場合、先にパスワードをはずしてあげる必要があります。

(実装例)
パスワード解除.JPG

  • 「PDFのパスワードを設定」アクティビティを配置し、「新しい文書を開くパスワード」欄をNullにすることでパスワードを削除できます。
  • 出力のエクスポートPDFはILocalResource型なのでそのまま「ドキュメントデータを抽出」アクティビティの入力に利用できます。

2.ログに出力した読み取り結果の取得

StudioWeb(自動生成WF) で実行した際のログ出力(読み取り結果)をローカルに取得したいケースありますよね。

ログから読み取り結果を取得.JPG

以下にStudioで実行ログから任意の情報を取得する際の実装例を記載します。

ログから読み取り結果を取得2.JPG

まず、エンドポイントのクエリをつくります。

# 2024/12/18以上、ログのメッセージに「The following data has been extracted」を含む のクエリ例
"\odata\RobotLogs?filter=TimeStamp ge 2024-12-18T00:00:00Z and contains(Message, 'The following data has been extracted')"

「OrchestratorへのHTTP要求」アクティビティを配置し、作成したエンドポイントを実行しましょう。

ログから読み取り結果を取得3.JPG

HTTP要求の応答レスポンスを一度JSONオブジェクト化し、valueフィールドについて「JSON配列を逆シリアル化」でJSON配列を作成します。

ログから読み取り結果を取得4.JPG

繰り返し(コレクションの各要素)でJSON配列の明細レコードを取得します。
値は次の様に記述して出力できます。

# TimeStamp と Message フィールドを書き出す例
currentJToken("TimeStamp").ToString()+" "+currentJToken("Message").ToString()

以下が実行ログ(\odata\RobotLogs)で取得できるフィールドです。

  • Level
  • WindowsIdentity
  • ProcessName
  • TimeStamp
  • Message
  • JobKey
  • RawMessage
  • RobotName
  • HostMachineName
  • MachineId
  • MachineKey
  • RuntimeType
  • Id

よく使う比較演算子:

  • eq 等しい
  • ne 等しくない
  • gt より大きい
  • ge 以上
  • lt より小さい
  • le 以下

Orchestrator のWebAPIは一度に取得できるレコードは1000件までに制限されています。
このため、抽出対象レコードが多い場合は、繰り返し処理でエンドポイントのSkipオプションをインクリメントしながら実行しましょう。

ログから読み取り結果を取得5.JPG

# エンドポイント記述例
"\odata\RobotLogs?$filter=TimeStamp ge 2024-12-18T00:00:00Z&$Top=1000&$Skip="+カウンタ.ToString

3.特定領域の値の取得

先の記事でも触れましたが、StudioWeb×DUでは定型帳票用のアクティビティがありません。(IntelligentOCRパッケージが利用できないため)
ですが、次の様に座標情報をもちいた任意領域の抽出は可能です。

特定領域の値を抽出.JPG
特定領域の値を抽出2.JPG

「繰り返し(コレクションの各要素)」アクティビティを配置し、extractedResults.DocumentMetadata.DocumentObjectModel.Pages > .Sections > .WordGroups の順で currentWord オブジェクトを操作できるようにします。
currentWord は「.Text」で抽出されたワードの値を「.Box.Left」「.Box.Top」「.Box.Right」「.Box.Bottom」で座標情報を確認・出力できます。

このため、次の様な記述を条件分岐を入れておくことで、任意領域内の文字列のみ取得することが可能です。

currentWord.Box.Left >= 領域の左端のX座標 and 
currentWord.Box.Top >= 領域の上端のY座標 and 
currentWord.Box.Right <= 領域の右端のX座標 and 
currentWord.Box.Bottom <= 領域の下端のY座標

PDFの場合は、一度ワード毎の座標情報を出力し、適当に余白分を追加して決めます。
画像の場合は、次の様なHTMLをつかって手元で調べることも可能です。
(使い方:「ファイルの選択」ボタン押下=>画像選択=>任意領域をマウスで指定=>座標情報が画面下部に表示されるのでご確認ください)

(画像の任意範囲の座標を取得.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas Image ROI Selector</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            margin-top: 20px;
        }
        canvas {
            border: 1px solid black;
            cursor: crosshair;
        }
        #coordinates {
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h1>画像から選択範囲を取得</h1>
    <input type="file" id="imageLoader" accept="image/*">
    <canvas id="canvas"></canvas>
    <div id="coordinates">
        <p><strong>選択範囲:</strong></p>
        <p>Left: <span id="left">-</span>, Top: <span id="top">-</span>, Right: <span id="right">-</span>, Bottom: <span id="bottom">-</span></p>
    </div>
    <script>
        const imageLoader = document.getElementById('imageLoader');
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let image = new Image();
        let isDragging = false;
        let startX, startY, endX, endY;

        // 画像が選択されたら読む
        imageLoader.addEventListener('change', (e) => {
            const file = e.target.files[0];
            const reader = new FileReader();
            reader.onload = function(event) {
                image.src = event.target.result;
            };
            reader.readAsDataURL(file);
        });

        // 画像のロード完了時にキャンバスへ描画
        image.onload = () => {
            canvas.width = image.width;
            canvas.height = image.height;
            ctx.drawImage(image, 0, 0);
        };

        // マウスイベントで選択範囲の処理
        canvas.addEventListener('mousedown', (e) => {
            const rect = canvas.getBoundingClientRect();
            startX = e.clientX - rect.left;
            startY = e.clientY - rect.top;
            isDragging = true;
        });

        canvas.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const rect = canvas.getBoundingClientRect();
                endX = e.clientX - rect.left;
                endY = e.clientY - rect.top;

                // キャンバスをリセットして画像を再描画
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(image, 0, 0);

                // 選択範囲を描画
                ctx.strokeStyle = 'red';
                ctx.lineWidth = 2;
                ctx.strokeRect(startX, startY, endX - startX, endY - startY);
            }
        });

        canvas.addEventListener('mouseup', () => {
            isDragging = false;

            // 出力座標の計算
            const left = Math.min(startX, endX);
            const top = Math.min(startY, endY);
            const right = Math.max(startX, endX);
            const bottom = Math.max(startY, endY);
            const Height = bottom - top

            // 座標を表示
            document.getElementById('left').textContent = Math.round(left);
            document.getElementById('top').textContent = Math.round(top);
            document.getElementById('right').textContent = Math.round(right);
            document.getElementById('bottom').textContent = Math.round(bottom);
        });
    </script>
</body>
</html>

さいごに

いかがでしたでしょうか。
今後も役に立ちそうな開発Tipsをみつけたらシェアしていきたいとおもいます。
最後までお読みいただきありがとうございます(・ω・)ノ

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?