はじめに
- 本記事は、StudioWeb で Document Understanding(モダンプロジェクト) を扱いたい方向けの内容です。
- 本記事は以下の記事の続きで、細かいトピックベースの実装ポイント解説がメインです。
- 記事の内容は、個人の見解または確認結果であり、UiPath の公式見解ではありません。
- 製品仕様や参考画像は 24.10 バージョンのもので構成しています。
トピック一覧
# 1.パスワード付きのPDFの読み取り
# 2.ログに出力した読み取り結果の取得
# 3.特定領域の値の取得
1.パスワード付きのPDFの読み取り
「ドキュメントデータを抽出」アクティビティのプロパティにはパスワード入力欄はありません。
このため、パスワード付きのPDFのデータを抽出したい場合、先にパスワードをはずしてあげる必要があります。
- 「PDFのパスワードを設定」アクティビティを配置し、「新しい文書を開くパスワード」欄をNullにすることでパスワードを削除できます。
- 出力のエクスポートPDFはILocalResource型なのでそのまま「ドキュメントデータを抽出」アクティビティの入力に利用できます。
2.ログに出力した読み取り結果の取得
StudioWeb(自動生成WF) で実行した際のログ出力(読み取り結果)をローカルに取得したいケースありますよね。
以下にStudioで実行ログから任意の情報を取得する際の実装例を記載します。
まず、エンドポイントのクエリをつくります。
# 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要求」アクティビティを配置し、作成したエンドポイントを実行しましょう。
HTTP要求の応答レスポンスを一度JSONオブジェクト化し、valueフィールドについて「JSON配列を逆シリアル化」でJSON配列を作成します。
繰り返し(コレクションの各要素)で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 以下
3.特定領域の値の取得
先の記事でも触れましたが、StudioWeb×DUでは定型帳票用のアクティビティがありません。(IntelligentOCRパッケージが利用できないため)
ですが、次の様に座標情報をもちいた任意領域の抽出は可能です。
「繰り返し(コレクションの各要素)」アクティビティを配置し、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をみつけたらシェアしていきたいとおもいます。
最後までお読みいただきありがとうございます(・ω・)ノ