用收據 OCR 轉成 CSV,再匯入會計軟體
收據、發票一張張手動輸入、Excel 開啟亂碼、明細全擠進一格、PDF 無法複製 ── 把這些月底的苦差事,換成「拍照→定義欄位→一張=一列→匯出 CSV→匯入 freee/Money Forward/弥生」的實務做法。明細以陣列欄位展開成一項商品=一列,採 UTF-8 BOM 解決亂碼,每個值都附 bbox+match_ratio 對照原件。每張 ¥10、失敗不計費、每月 100 張免費額度。
月底到了。從錢包和抽屜裡翻出來的一疊收據和發票。請想像把它們一張張手動輸入會計軟體的那種畫面:打店名、打日期、打金額,然後換下一張。只要有 30 張,專注力就會斷掉,少打或多打一個位數也不會察覺。「手動輸入收據」之所以是地獄,不在於量,而在於它「明明很單純卻又不能出錯」的本質。
想用掃描貼到 Excel 嗎?這時又會撞上另一道牆。打開 CSV,中文(日文)變成亂碼。收據上的明細(買了哪些商品的清單)連同換行被擠進同一格。用 PDF 寄來的收據連複製都辦不到。最後還是把原件擺在螢幕旁邊,邊用眼睛追邊重打一遍 ── 這樣到底數位化是為了什麼?
這篇文章就是要把這件事換成 「拍下收據 → 一次決定欄位 → 上傳後一張=一列 → 匯出 CSV 並匯入 freee/Money Forward/弥生」 的流程,是一份實務操作指南。請別把它當成產品說明書,而當成「月底那疊收據要怎麼收尾」的解法來讀。
先動手試試(免上傳・10 秒)
下面這組範例,是把兩張真實收據實際跑過 OCR 的結果。把游標移到各欄位(店名・日期・合計・明細)上,它從圖片的哪個位置讀到這個值就會在原件上高亮顯示出來。不用上傳、也不用登入。先確認一下「讀到的值,是不是真的指向原件上的那個位置」。

Every value carries a verified on-page location — bbox + 4-point vertices + match_ratio — on a 0–1000 normalized grid (0,0 top-left → 1000,1000 bottom-right), the same shape the live API returns. Hover a field to trace it back to the pixels it came from.
從收據 OCR 到 CSV,實際就 4 步
要做的事不多。我們依序用影片來看。
- 上傳原始圖片 ── 把拍好或掃描好的收據,灌進事先定好的欄位(店名・日期・合計・明細…)。
- 在抽取表中確認 ── 一張變成一列,欄位自動填好。
- 用 bbox 對照原件 ── 看到可疑的值就點一下儲存格,原件上對應的位置會亮起來,肉眼立刻核對。
- 匯出成 CSV ── 直接輸出成可匯入會計軟體的 CSV。
先看步驟 1,上傳拍好/掃好的收據後,每張圖片都會依照你定義的欄位被結構化。
欄位(schema)只要決定一次就好
關鍵是一開始把欄位定義好這一次就夠了。只要先定義好你想要的項目,像「店名・分店名・日期・合計・明細」,那之後上傳的所有收據都會以相同形態(同一個 schema)整理成一列。就算每家店的版面各不相同,輸出的列結構都一樣。正因如此,最後才能彙整成一份 CSV。
「明細擠進一格」問題的真正成因
手動 Excel 最痛苦的,就是收據的明細(買了哪些商品的清單)。一張收據上有 10 行商品,你要嘛把它塞進一格,要嘛用手拆成 10 列。
在 space-ocr 裡,明細是定義成陣列(array)型的欄位。匯出 CSV 時,這個陣列欄位會 展開成 明細.商品名 明細.單價 明細.數量 這樣的子欄位,一項商品=一列縱向展開。也就是說,它不是「擠進一格」,而是一開始就以會計或統計能直接處理的列形態輸出。
{
"columns": [
{ "name": "店舗名", "type": "string" },
{ "name": "支店名", "type": "string" },
{ "name": "日付", "type": "string" },
{ "name": "合計", "type": "string" },
{
"name": "明細",
"type": "array",
"children": [
{ "name": "商品名", "type": "string" },
{ "name": "単価", "type": "string" },
{ "name": "数量", "type": "string" }
]
}
]
}可疑的值,點一下跳到原件去確認
讀取完成後,你不必照單全收。點一下在意的儲存格,原件圖片上「從這裡讀到的」位置就會高亮。視線會一口氣跳到那個位置,所以抽查整疊收據很快。
之所以有效,是因為每個值都會連同**讀取位置(bbox)與一致度(match_ratio)**一起回傳。這個值是從圖片的哪裡來的,人和系統事後都能追溯 ── 也就是說,它可以被稽核。
這個座標,不是 AI 回答「應該在這裡」的數字。 語言模型回傳的只有值的文字,以及它參考的單詞 token 提示(wid),座標本身並不是它生出來的。引擎會先把這個值的文字,和 Vision OCR 實際在頁面上偵測到的字元(symbol)逐字比對,再把框放到找到的真實像素位置上。在此之上,每個值都會附上 match_ratio(一致度・0〜1.0)。1.0 表示所有字元都在原件上找到了,而 0.85 以上視為確信匹配。語言模型的 token 提示,有時會用來輔助覆寫找到的 token 的位置,但不會照單全收 ── 尤其同一個值反覆出現的欄位裡提示容易飄移,因此會以欄位的整體與列的一致性來檢查,一旦偏掉就退回逐字比對的結果。座標以 xmin / ymin / xmax / ymax 的 0〜1000 正規化網格(0,0=左上、1000,1000=右下)回傳,所以不依賴圖片解析度。一句話:重點不是「AI 不會錯」,而是「把每個值都對照原件,並以數值呈現它匹配到什麼程度」。
匯出成 CSV,再匯入會計軟體
確認完畢後,把這份表匯出成 CSV。表頭由純量欄位+陣列的子欄位(像 明細.商品名 那樣展開)組成,明細則一項商品=一列縱向展開。如果你手動改過某些儲存格,會以你修改後的值為優先。
再來是防亂碼。輸出的 CSV 是 附 UTF-8 BOM 的,所以用 Excel 開也不會讓中文(日文)變亂碼。這就是它從根本上不會「在 Excel 出現亂碼」的原因。
匯入 freee/Money Forward/弥生
匯出的 CSV,可以從各會計軟體的**「CSV 匯入」功能**讀進去。這不是官方 API 串接,而是通用的 CSV 匯入。正因如此,比較不會被會計軟體的版本或方案綁住,只要把欄位的對應(mapping)對好,就能直接匯入。
月底累積的收據,拍照 → 一張表 → 一份 CSV → 一次匯入軟體。原本花在手動輸入的時間,就變成了確認的時間。
如果你手上不是圖片而是掃描 PDF,可以一併參考把掃描 PDF 轉成 Excel 的步驟。想用 API 自動處理發票、送貨單的話,發票、送貨單 OCR API 的文章會很有幫助。
PDF 的收據,也能直接處理
用 email 收到的收據是 PDF,連複製都不行 ── 這也是常見的卡關點。只要把 PDF 拖進 App,每一頁都會先自動轉成圖片再跑 OCR。所以「PDF 不能複製」這道牆,你這邊根本不必去在意。多頁的 PDF 會逐頁處理,結果一筆筆堆疊到表裡。
收費透明,失敗不計費
- 每張 ¥10 的用量計費(以 call/image 為單位)。
- 失敗不計費 ── 沒出結果的圖片不收費,引擎錯誤會自動退款。
- 免費額度每月 100 張(免信用卡,每月重置)。
- 想固定金額使用的話,Pro 方案 $39/月。
如果你只是想「先試試這個月的收據」,在免費額度的範圍內就能直接跑。
收據、發票的電子化,在配合インボイス制度(發票制度)與電子帳簿保存法建立作業流程的實務上很有幫助。每個值是從原件哪裡讀來的、還附帶 match_ratio 可事後追溯,這一點有助於內部核對與確認。不過本文並非會計或法務建議,不保證滿足法律要件或取得認證。制度因應的最終判斷,請務必向顧問稅理士等專業人士確認。
月底的收據,拍一拍就搞定
- 把欄位(schema)一次定義好除了店名、分店名、日期、合計之外,明細定義成陣列(array)型欄位,在子欄位裡放入「商品名・單價・數量」。這樣之後所有的收據都會以相同形態整理成一列。
- 拍照或掃描收據後上傳用手機拍或用掃描都可以。PDF 只要拖進來,每一頁就會先自動轉成圖片再做 OCR。讀取時一張=一列,欄位自動填好。
- 對可疑的值用原件確認點一下儲存格,原件圖片上讀取該值的位置(bbox)就會高亮。match_ratio 低於 0.85 的值是匹配偏弱的訊號,請優先確認、修改。手動改過的值會和原始 OCR 值分開保存。
- 匯出成 CSV把表匯出成 CSV。明細等陣列欄位會展開成「明細.商品名」這樣,並一項商品=一列縱向展開。輸出附有 UTF-8 BOM,所以用 Excel 開也不會讓中文(日文)變亂碼。
- 用會計軟體的 CSV 匯入功能讀進去從 freee、Money Forward、弥生等的「CSV 匯入」功能讀進去。這不是官方 API 串接,而是通用的 CSV 匯入,所以只要把欄位的對應對好就能直接匯入。