maestro/docs/tools/office.md
oss-sync 3b1645cc91
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (d31b280)
2026-06-11 11:28:40 +00:00

10 KiB
Raw Permalink Blame History

Office ファイル系ツールReadPdf / ReadExcel / ReadDocx / ReadPPTX / ReadMsg / PdfToImages / SplitExcelSheets / SplitDocxSections

ローカル workspace の Office 文書・PDF を読み込むツール群。

読み取り系

ReadPdf

// 全文抽出 (page 区切りで markdown)
ReadPdf({ path: "input/manual.pdf" })

// ページ範囲を絞る
ReadPdf({ path: "input/spec.pdf", page_range: "10-25" })

// grep -n 風検索 (query mode)
ReadPdf({ path: "input/manual.pdf", query: "保証期間" })
ReadPdf({ path: "input/manual.pdf", query: "保証期間", context_lines: 5 })
ReadPdf({ path: "input/spec.pdf", query: "第\\d+条", query_mode: "regex" })

スキャン PDFテキストレイヤなしの場合は 自動で PdfToImages + Vision OCR にフォールバック。手動で PdfToImages → ReadImage を呼ぶ必要は通常ない。query を併用すると OCR 結果にも同じフィルタが適用される。

引数

引数 デフォルト 説明
path string (required) workspace 相対の PDF パス
page_range "3" / "1-5" (全ページ) 抽出ページ範囲
max_pages number (無制限) 抽出ページ数の上限
max_chars number 50,000 返却文字数の上限
query string (なし) 一致行のみ grep -n 風で返す。trim 後 empty なら全文 mode
query_mode substring / regex / iregex substring 検索モード。substring は大小無視 + metachar auto-escape
context_lines number (0..20) 2 query マッチ前後の context 行数

query mode の出力例

# foo.pdf, query: "保証期間"

### Summary
- Total pages: 50
- Pages with match: 3
- Total matches: 5

### Matches

## Page 7 — 2 matches
   6:   商品は購入日より
>  7: 保証期間内に故障した場合、無償修理対象…
   8: ただし、消耗品は対象外です。
  …
> 22: 延長保証期間は最大 3 年まで…

> が一致行、空白マーカーが context 行。隣接マッチは context window が overlap したら 1 cluster にまとめられ context 重複を回避。

gotcha

  • MAX_MATCHES_PER_PAGE = 50: 1 ページで 50 件超のマッチは打ち切り、page header に (capped) を付与。"the" のような broad pattern を絞るシグナル
  • query_mode: "regex" の invalid patternisError: true で friendly メッセージ。substring mode は metachar をエスケープするので絶対に regex error にならない
  • OCR fallback path でも query 適用。スキャン PDF + キーワード検索 OK
  • 上記 PdfToImages の手動呼び出しは DPI / 出力ファイル個別管理 がしたい時のみ。普通の "PDF を vision で読みたい" は ReadPdf 単発で済む

ReadExcel

ReadExcel({ path: "input/data.xlsx" })
// → 全シートのセル内容をテキスト形式で返す

巨大な Excel は token を食うので、シートを絞る場合は SplitExcelSheets を使う。

include_styles — セル装飾の取得(オプション)

ReadExcel({ path: "input/report.xlsx", include_styles: true })
// → 値テーブルの後に ### Styles セクションが追記される

デフォルトは false(後方互換)。include_styles: true を指定すると、値テーブルの直後に各シートの ### Styles セクションが出力される。

出力形式 — dedup legend + range map:

### Styles — Sheet1
s1 = fill:#FFF2CC;font:bold
s2 = border:top(thin),bottom(double,#808080);numFmt:"0.00%"

s1: A1:D1,A5:D5
s2: B2
merges: B2:D4
  • legend: スタイル ID (s1, s2, ...) とそのシグネチャを列挙。シグネチャは fill / font / border / numFmt / align のうち非デフォルト部分を ; 区切りで結合した文字列。
  • range map: 同一スタイルを持つセルを矩形にまとめて A1:D3 形式で列挙。単一セルは A1
  • merges: 結合セル範囲の一覧(ws.model.merges から取得)。
  • conditionalFormatting: 条件付き書式が存在する場合 present (effective styles not evaluated) と表示(実際の表示色は評価しない)。
  • 装飾のみ・値なしセルも捕捉: スタイルスキャンは includeEmpty:true で実行するため、値がなく書式だけ設定されたセルも対象に含まれる。
  • sheet/range フィルタを尊重: include_styles は値テーブルと同じ sheet/range フィルタでスキャン範囲を限定する。指定した範囲外のセルのスタイルと、範囲に交差しない結合セルは結果に含まれない。
  • デフォルト色の省略: デフォルト色 (theme index 1 = 通常黒) に明示設定したフォント色はデフォルト扱いで省略される。同様に border の theme index 0自動色も省略される。

テーマカラーの解決(ベストエフォート):

テーマカラーはファイルの theme1.xml から読み取り、OOXML の lt/dk スワップを適用して #RRGGBB に解決する。解決できた場合は theme(N,resolved=#RRGGBB) の形式で表示し、resolved= は近似値であることに注意。テーマ XML が解析できない場合は theme(N,tint=T) のように生の参照のまま出力する。

max_style_ranges — range 数の上限:

max_style_ranges(デフォルト 250で全シートを通じた range 出力数を制限する。上限に達した場合は [styles truncated: max_style_ranges=N reached] を表示し、以降のスタイルは省略される。値テーブルが先に出力されるため、スタイルセクションがトークン上限で切り捨てられても値は失われない。

編集には python + openpyxl を推奨:

ReadExcel はスタイルを読むだけで、書き込みは行わない。既存スタイルを保持したまま値を編集する場合は Bash ツールで python + openpyxl を使うことopenpyxl は触れていないセルのスタイルを保持する)。

ReadDocx

ReadDocx({ file_path: "input/spec.docx" })
// → 本文 + 表を抽出

ReadPPTX

ReadPPTX({ file_path: "input/slides.pptx" })
// → 各スライドのテキスト・表・スピーカーノートを返す

ReadMsg

Outlook の .msgOLE2 / CFBF 複合バイナリ)メールを読む。

ReadMsg({ file_path: "input/inquiry.msg" })
// → 件名・差出人・宛先・CC・日時・本文テキストと添付一覧を返す

返却テキストの構成:

Subject: 見積もりのご依頼
From: 山田太郎 <taro@example.com>
To: sales@example.com
Date: ...

(本文テキスト)

Attachments (2):
- 見積書.pdf (20480 bytes) -> input/見積書.pdf
- data.xlsx (8192 bytes) -> input/data.xlsx

ポイント:

  • 本文は plain text を優先。HTML メールはタグを除去して整形。どちらも取れない場合は (no text body)
  • 添付は input/ に自動保存される。保存後は種別ごとのツールで開くPDF → ReadPdf、Excel → ReadExcel、画像 → ReadImage など)
  • ファイル名は basename に正規化し、パス区切りや制御文字を除去(ディレクトリトラバーサル防止)。同名衝突時は連番を付与
  • 添付に埋め込まれた .msg(メール in メール)は保存せず一覧に注記のみ。必要なら個別に扱う
  • 不正な .msgCFBF シグネチャ不一致)は中身を読まずエラーを返す。バイナリがそのまま出力に混ざることはない

変換・分割系

PdfToImages

PdfToImages({ file_path: "input/scan.pdf", dpi: 200 })
// → output/ReadPdf/page-001.png, page-002.png, ... に保存

スキャン PDF を ReadImage で扱うときの前段。

SplitExcelSheets

SplitExcelSheets({ file_path: "input/big.xlsx" })
// → output/excel/{sheetname}.md と manifest.json を生成

シート単位で別ファイルにすることで、Read で必要なものだけ取り出せる。

SplitDocxSections

SplitDocxSections({ file_path: "input/long-spec.docx" })
// → 見出しベースで分割した .md と manifest.json を生成

長い Word 文書を構造化して Read で取り回しやすくする。

ファイル選択の指針

ファイル 第一選択 フォールバック
PDFテキストあり ReadPdf -
PDFスキャン画像 ReadPdf自動 OCR フォールバック) 手動 PdfToImages → ReadImage
PDF 内をキーワード検索 ReadPdf + query Read → GrepReadPdf で出力保存後)
Excel小〜中 ReadExcel -
Excel巨大 SplitExcelSheets → Read -
Word短〜中 ReadDocx -
Word長文・章構成 SplitDocxSections → Read -
PowerPoint ReadPPTX -

注意

  • すべて workspace 内のローカルファイル(input/ または output/)が対象
  • URL 指定不可 → DownloadFile で先にローカル保存
  • 全ツール read-only書き込まない

ファイルサイズ上限

Read 系ツールは悪意あるファイル / リソース枯渇対策として入力サイズを検証する。デフォルトは以下の通りで、config.yamltools セクション、または Settings UI の「Tools → Office ファイルサイズ上限」から変更可能。

ツール デフォルト config キー
ReadExcel 10 MB tools.office_excel_max_size_mb
ReadDocx 10 MB tools.office_docx_max_size_mb
ReadPdf 10 MB tools.office_pdf_max_size_mb
ReadPPTX 50 MB tools.office_pptx_max_size_mb
ReadPPTX 展開後 200 MB tools.office_pptx_max_uncompressed_mb

PPTX の「展開後」は ZIP bomb 検知用で、ZIP 内の全エントリの非圧縮合計サイズに対する閾値。超過時は ZIP bomb detected: ... エラーとなる。

マクロ付きファイル(.xlsm / .docm / .pptm / .xlsb)は警告付きで読み込まれる(実行はされない)。