space ocr
ガイド記事料金ドキュメント
convert

スキャンしたPDFをExcelに変換する:日本語の表をCSVへ、文字化けなしで

スキャンしたPDFは画像なのでコピーできず、Excelに貼ると日本語が文字化けし、明細が1セルに潰れます。space-ocrのアプリにPDFをドロップすれば各ページが自動で画像化され、列を決めておけば1ページ=1行になり、UTF-8 BOMのCSVで出力。Excelで開いても文字化けせず、freee・マネーフォワード・弥生へのCSV取り込みもそのまま。失敗時は無課金。

8 分で読了· 2026-08-31

スキャンした請求書や領収書のPDFを開いて、まず気づくのはこれです ── コピーができない。テキストを選択しようとしてもドラッグできず、数字ひとつ拾えない。理由は単純で、スキャンPDFは表のデータではなく、「表が写っている画像」 だからです。人間の目には行・列・合計が並んで見えても、コンピュータにとってはただのピクセルです。

そこで多くの人がやることは決まっています。Excelを開いて、PDFを見ながら一行ずつ手入力する。あるいは無理やりコピペしてみて、結果は ── 日本語が 譁�蟄怜喧 のように文字化けし、明細がまるごと1セルに潰れ、レイアウトは完全に崩れる。「スキャン PDF Excel 変換」「PDF 表 CSV」「Excel 文字化け 対策」で検索してこの記事にたどり着いたなら、痛みはここにあるはずです ── 結局やりたいのは、会計ソフトに取り込める、列のそろったデータを手に入れることだけなのに。

結論:手入力もコピペもいらない

やることは、PDFをそのまま space-ocr のアプリにドロップする だけです。アプリは各ページを自動で画像化し、ページの中の値を名前のついたフィールドとして読み取ります。列(取引先・日付・合計・明細…)を一度決めておけば、1ページ=1行としてシートに積み上がり、最後に CSVで出力できます。

このCSVが肝心で、UTF-8 BOM付きで書き出されるので、Excelでダブルクリックして開いても日本語が文字化けしません。明細は1セルに潰れず、ちゃんと別々の行・列に展開されます。日本語の判定はエンジンが自動で行うので、言語の指定は不要です。

なぜスキャンは「そのまま」Excelに入らないのか

紙をスキャンした時点で、ファイルの中身は写真と同じラスター画像です。文字情報は埋め込まれていないので、Excelの「データの取得」やコピペでは表として拾えません。だから必要なのは2段階です。

  1. 画像を読んで構造化する(各ページ → 名前付きフィールドの行)
  2. その行をCSVに書き出す(Excelが素直に開ける形式で)

space-ocr のアプリでは、PDFを投げると 1ページずつ自動で画像化(PNG)してからOCRします。だから利用者の側でページを画像に切り出す手間はありません ── PDFをドロップするだけです。難しいのは ① の「読み取り」で、ここを正確にやることが、文字化けや明細潰れを根絶する近道になります。

元画像 → 抽出シート:スキャンが「列」になる

ドロップした書類の値は、文字の壁ではなく名前のついた列として出てきます。列は自分で定義しても、エンジンに提案させても構いません(APIなら fields で宣言するか、autoFields: true で提案させます)。スキャン1枚がラベル付きの行に変わる様子を見てください。

書類をドロップすると、値が名前付きフィールドに着地 ── これがExcelに並ぶ「行」になります。

明細行(請求書の品目、領収書の商品)のように繰り返す行がある書類は、array 型のフィールドに子列を宣言します。すると、ページ上の各行がそれぞれ独立した行になり、Excelで合計を取れる形になります ── これが「明細が1セルに潰れる」問題の正体への答えです。明細の組み方は 請求書・納品書を読み取ってExcel化する でも詳しく触れています。

日付や金額の列には、type にスカラー型(date / number / integer)を宣言できます。data.values には書類に印字されたままの表記2026年3月31日1,200,000 など)が残り、それとは別に data.normalized という層が付いて、決定論的なパーサが解釈した値 ── 日付ならISO形式、金額なら計算に使える数値 ── が入ります。解釈できなかったリーフは null になり、その理由は data.cells[パス].normalized.error に、検討対象としては type_mismatch として data.review.flagged に載ります。なお type の宣言はモデルには渡らないので、読み取りそのものの結果が変わるわけではありません ── 変わるのは、Excelや会計ソフトに渡す前に計算できる形の値が別の層で手に入ることです。

POST /ocr/fields → リクエストボディ(列=スキーマの宣言例)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "image": "https://example.com/scan-invoice-p01.png",
  "imageType": "url",
  "fields": [
    { "name": "vendor",       "type": "string" },
    { "name": "invoice_date", "type": "date" },
    { "name": "total",        "type": "number" },
    {
      "name": "line_items", "type": "array",
      "children": [
        { "name": "description", "type": "string" },
        { "name": "unit_price",  "type": "number" },
        { "name": "qty",         "type": "integer" }
      ]
    }
  ]
}
✓ Verified

座標はAIが想像で作っているのではありません。 言語モデルが返すのは値のテキストと「どの語トークンを使ったか」というヒントだけで、ボックスそのものは返しません。エンジンはまず、その値の文字を ビジョンOCRが実際にページ上で検出したシンボルと1文字ずつ照合(文字単位の照合が主力の経路) し、本物のピクセル位置にボックスを置きます。照合が走った値には、その根拠として マッチ率evidence.match_ratio ── 文字の何割をページ上で実際に見つけられたか)が残ります。モデルがトークンのヒントを返した場合はそれで一部のフィールドの位置を上書きすることもありますが、繰り返し行ではヒントの取り違えが起こり得るため鵜呑みにせず、列クラスタリングや行の一貫性チェックで検証・補正します。要点は「AIが間違えない」ではなく、照合できた値には根拠が残り、照合できなかった値はそれ自体が検討対象として表に出ることです(位置を確定できなければ nobox、文字が合わなければ text_mismatch という理由が付きます)。座標は boxxmin / ymin / xmax / ymax)と、傾きに沿う4点の quad の両方で返り、いずれも 0〜1000 正規化(ピクセルではありません)です。

取り込み前にスポットチェックする

Excelや会計ソフトに入れる前に、読み取り結果をその場で確認できます。値にカーソルを合わせると、元のスキャン画像の該当箇所が光るので、書類全体を読み直さなくても目が一発でそこに飛びます。

全部を見直す必要はありません。エンジンは引っかかった値に検討フラグを立てて返すので、そこから先に見ます。アプリではフラグの付いたセルに色が入り、理由(text_mismatchmissing など)が吹き出しで出ます。APIでは同じものが data.review.flagged に、パスと理由の配列として並びます ── 検討すべき件数はこのリストの長さです。固定のスコアしきい値で足切りする作りにはなっていません。

フィールドにホバーして元スキャンと突き合わせ ── おかしな読み取りをシートに取り込む前につかまえます。

Excelで開けるCSVを出力する

値が正しければ、シートを CSVで出力します。ヘッダ行に列名が並び、array フィールドは 列名.子列名 に展開されて、繰り返しの明細はサブ行に開きます。ファイルは UTF-8 BOM付き ── これが、Excelがダブルクリックだけで日本語・中国語・韓国語を正しく開ける、まさにその一点です。手作業で直したセルは、出力時に元のOCR値を上書きして反映されます。

ワンクリックで UTF-8 BOM のCSV を出力 ── ダブルクリックすればExcelが列のそろった行で開きます。

Excelで開く手順はシンプルです ── .csvダブルクリックするだけ。BOMのおかげでExcelはUTF-8として自動認識し、テキストインポートウィザードも文字化けもありません。ネイティブのブックが必要なら、そこから 名前を付けて保存 → .xlsx にすればOKです。

そのまま会計ソフトへ持っていく場合も、出口は同じCSVです。freee・マネーフォワード・弥生 などは、それぞれのCSV取り込み機能で読み込ませる形になります(公式APIでの自動連携ではなく、CSVファイルの取り込みです)。領収書だけをCSVにする流れは 領収書をCSVにする で個別にまとめています。

まとめて処理する:APIで大量のスキャンを回す

スキャンのフォルダをまるごと処理したいときは、列スキーマを持つシートを一度作り、そこへページ画像をアップロードします。各画像はそのスキーマに沿って読み取られ、行として追記され、最後にひとつのCSVとして出力できます。リクエスト/レスポンスの詳しい形は APIドキュメント にあります。

シートにスキャンのページ画像をアップロード
1
2
3
4
5
6
curl -X POST https://api.space-ocr.com/upload \
  -H "Authorization: Bearer $SPACE_OCR_API_KEY" \
  -F "path=/請求書 2026" \
  -F "files=@scan-p01.png" \
  -F "files=@scan-p02.png" \
  -F "wait=true"
Why it matters

料金は明朗です。 1クレジット ¥10 の従量課金、毎月 100クレジットの無料枠(クレジットカード不要)、チーム向けの定額 Pro ¥8,980/月。そして 読み取りに失敗した分は無課金 ── 結果が出なければ課金されません。CSVの書き出しは、無料枠と従量課金では 1クレジット(同じデータの再ダウンロードは無料)、Starter・Proではダウンロード無料です。費用が読みやすいので、まず手元のスキャンで試してから判断できます。

スキャンPDFをExcelに変換する手順

  1. PDFをアプリにドロップする
    space-ocr のアプリにスキャンPDFをドロップします。アプリが各ページを自動で画像化(PNG)してからOCRするので、利用者がページを画像に切り出す必要はありません。
  2. 列(スキーマ)を決める
    取引先・日付・合計などの列を、自分のフィールド定義かエンジンの自動提案で決めます。日付は date、金額は number のようにスカラー型を宣言しておくと、data.normalized に決定論的に解析した値が別途付きます。請求書の品目など繰り返す明細は array 型に子列を宣言すると、各行が独立した行になります。
  3. 値をスポットチェックする
    フィールドにホバーすると、元スキャンの該当箇所が光ります。エンジンが引っかかった値には検討フラグと理由(text_mismatch、missing など)が付いて返るので、全件を読み直す代わりにそこから確認します。
  4. CSVを出力する
    シートをCSVで出力します。UTF-8 BOM付きで、array の明細はサブ行に展開され、手作業の修正は元のOCR値を上書きして反映されます。
  5. Excelまたは会計ソフトで開く
    CSVをダブルクリックするとExcelがBOMをUTF-8と認識し、日本語が文字化けせず列のそろった行で開きます。ネイティブ形式が必要なら名前を付けて保存で .xlsx に。freee・マネーフォワード・弥生へは各ソフトのCSV取り込みで読み込ませます。
日本語のスキャンにも対応していますか?
はい。言語の判定はエンジンが自動で行うので、言語の指定は不要です。日本語・韓国語・中国語・英語を1つのエンジンで扱います。スマホで撮った写真は、EXIFの回転情報がピクセルに反映された状態で読み取られます。傾きの補正(deskew)は行わないので、斜めに写った書類では quad の座標がその傾きに沿って返ります。
PDFに直接対応していますか?それとも画像に変換が必要ですか?
アプリはPDFに対応しています。PDFをドロップすると各ページが自動で画像化(PNG)されてからOCRされるので、利用者が手動でページを画像に切り出す必要はありません。なお公開APIへ直接送る場合は、入力はラスター画像(JPEG・PNG・GIF・BMP・TIFF・WebP)です。
出力したCSVは、Excelで日本語が文字化けせずに開けますか?
はい。CSVは UTF-8 BOM付きで書き出されます。これがExcelがエンコーディングを自動判別するための要点で、ダブルクリックするだけで日本語・中国語・韓国語が正しい列に入ります。テキストインポートウィザードを通す必要はありません。
freee やマネーフォワード、弥生に取り込めますか?
出力はExcelで開けるCSVなので、各会計ソフトのCSV取り込み機能で読み込ませる形になります。これは公式APIでの自動連携ではなく、CSVファイルの取り込みです。列名や明細の展開はシート側で整えてから出力できます。
精度はどう確認できますか?個人情報は大丈夫ですか?
返ってきた値には、ページ上の位置(box と、傾きに沿う quad)と照合の根拠が付きます。フィールドにホバーすれば元スキャンの該当箇所が光るので、原本と突き合わせて確認できます。見直したい値は理由付きで検討リスト(APIでは data.review.flagged)にまとまり、位置を確定できなかった値もそこに出るので、全件を目で追う必要はありません。個人情報については、公開APIの POST /ocr/* は画像を保存しません。アプリのマイスペースにアップロードした画像は、削除すると保存された原本も一緒に消えます。料金面では、読み取りに失敗した分は無課金です。
関連記事