將掃描 PDF 轉成 Excel
把掃描 PDF 轉成 Excel:將每一頁影像讀成結構化欄位,對照原稿抽查後,匯出 Excel 能直接開啟的 UTF-8 BOM CSV 檔。
掃描 PDF 並不是檔案裡偷偷藏著一張試算表——它其實就是一張文件的圖片。每一頁都是由資料列、欄位和合計組成的影像,在人眼看來「像」一張表格,但對電腦來說只是一堆像素而已。這就是為什麼掃描檔通常沒有「匯出到 Excel」的按鈕:根本沒有儲存格可以匯出,有的只是一張圖。想拿到真正的資料列,你得先把整頁重新讀成結構化的欄位,再把這些欄位寫成 Excel 能開啟的檔案。
本文要做的正是這套流程。你拿到一張文件影像(掃描頁、手機拍的照片、傳真來的收據),把上面的數值抽成具名欄位,再匯出一個能直接在 Excel 開啟的 CSV——採用帶位元組順序記號(BOM)的 UTF-8 編碼,這樣日文、韓文、中文都會落在正確的欄位裡,而不會變成亂碼。「掃描 PDF 轉 Excel」最終想要的,就是那一份 CSV。
為什麼掃描檔不能直接變成 Excel
當你掃描一張紙本發票,得到的是一張點陣圖——和 JPEG 照片是同一類檔案。space-ocr 直接接受這些點陣格式:JPEG、PNG、GIF、BMP、TIFF 和 WebP。如果你的來源是多頁的 PDF,有兩條路可走:直接把 PDF 丟進 space-ocr 應用程式,它會自動幫你把每一頁算繪成影像;或者——如果你是直接呼叫 REST API——先把每一頁匯出成影像(PNG 或 TIFF)再送出。不管哪一種方式,OCR 都是在頁面影像上執行的。
引擎會讀取每一張影像、找出上面的數值,並在能定位的範圍內一併回傳這些數值來自頁面哪個位置的來源座標:一個 0–1000 正規化的軸對齊 box,以及跟著紙面傾斜走的四點 quad。定位不到來源區塊的數值,或字元和紙面印刷對不起來的數值,不會悄悄通過,而是被標記為待複核。一旦整頁被結構化成欄位,要變成 Excel 只剩下載一份 CSV 而已。真正困難、也最值得做對的部分是「讀取」,而不是「匯出」。
從文件影像到結構化欄位
上傳一張文件影像——或乾脆丟一張照片或一個 PDF——數值就會以具名欄位的形式輸出,而不是一整片文字牆。最快的方式是讓應用程式幫你提議欄位:把整頁丟進去,它就會自動提出一套結構,不必設定。如果你已經知道要哪些欄,也可以自行定義欄位(結構):把欄位名稱和型別定下來,之後丟進這張表的每一頁都會照同一套定義讀取。看一張掃描檔如何變成帶標籤的欄位:
對於有重複列的文件——發票明細、收據商品——請宣告一個 array 欄位並帶上子欄位。頁面上的每一行都會變成獨立的一列,當試算表需要加總時,這正是你要的結果。如果你正好要專門處理這種重複列,欄位規格的細節請參考從發票抽取明細列。
{
"image": "https://example.com/scanned-page-01.png",
"imageType": "url",
"fields": [
{ "name": "vendor", "type": "string" },
{ "name": "invoice_date", "type": "string" },
{ "name": "total", "type": "string" },
{
"name": "line_items", "type": "array",
"children": [
{ "name": "description", "type": "string" },
{ "name": "unit_price", "type": "string" },
{ "name": "qty", "type": "string" }
]
}
]
}數值不會由我們代為正規化。 印在紙上的 7,855 回傳的仍然是 7,855——逗號、小數點、全形字元都照讀到的寫法保留,不會被改寫成某種標準數字,這樣你的合計才能和紙面對得起來。你在應用程式裡看到的貨幣符號只是 UI 裝飾,並不屬於數值本身。在欄位描述裡怎麼寫都改變不了這件事——數值要貼著印刷時的寫法,座標和比對才有意義。不過 values 是模型讀出來的文字,需要逐字嚴格比對時請改用 evidence.printed_text,也就是該座標上的原始 OCR 字元。如果你需要一個可以拿來計算的數字,API 會把它放在印刷值旁邊一併回傳:把欄位的 type 宣告為 number、integer 或 date,回應就會帶上與 values 結構相同、已解析的 normalized。
先抽查,再匯出到 Excel
在把任何東西匯入 Excel 之前,先確認讀取結果是否正確。把滑鼠移到某個數值上,原始影像上對應的來源區塊就會亮起來,讓你的視線直接落在那個位置,而不必把整張掃描檔重看一遍。
你也不必逐筆用眼睛掃過去,因為讀取結果本身就附了一份待辦清單。data.review.flagged 裡,每個需要複核的數值都帶著它的 path 和被標記的 reasons:字元和紙面對不起來是 text_mismatch,找不到來源區塊是 nobox,宣告為必填的欄位卻回傳空值是 missing。儲存格的 verified 就是這個判定,只要有任何一個理由被標記就是 false。處理這份清單就好,其餘的不必動。evidence.match_ratio 是掛在儲存格上的輔助佐證,不是拿來卡門檻用的數字。
匯出能在 Excel 開啟的 CSV
當欄位看起來都沒問題,就匯出整張表。你會得到一個 <sheetName>.csv,第一列是你的欄位名稱標題列;array 欄位會展開成 column.child 欄,重複的明細列則展開成子列。這個檔案是帶 BOM 的 UTF-8,正是這個細節讓 Excel 在你雙擊時能乾淨地開啟 CJK 文字。你做過的任何手動修正,在匯出時都會覆蓋掉原本的 OCR 數值。
匯出本身在 Free 與用多少付多少方案會消耗 1 點數,Starter 與 Pro 方案下載免費。相同資料重複下載,在任何方案下都不計費。
要在 Excel 開啟它:直接雙擊那個 .csv 就好。因為有 BOM,Excel 會自動把它當成 UTF-8 來讀——不用跑文字匯入精靈,也不會出現亂碼。接著如果你需要一個原生活頁簿,就另存新檔 → .xlsx。如果你的最終目標只是一條單純的 CSV 流程,而不是非 Excel 不可,姊妹篇把掃描文件轉成 CSV 從頭到尾完整講解了同一套匯出流程。
透過 API 大量處理
面對一整個資料夾的掃描檔,先用你的欄位結構建立一張表,然後把頁面影像上傳到那張表。每張影像都會依照那套結構被讀取,並附加成資料列,之後可以一次匯出成一份 CSV。
POST /upload 的上限是每次請求最多 20 個檔案、單檔 20MB、整個請求 28MB,超過會回 413。費用是每頁 1 點數($0.05,含稅)。呼叫預設是非同步的:回應會帶回一個 jobs[],結果透過 ocr.completed webhook 或輪詢 GET /jobs/{jobId} 取得。像下面這樣加上 wait=true 就改成同步等待,每張影像最多等 30 秒,來不及的項目會以 status: "pending" 回傳,稍後再取。需要重試時帶上 Idempotency-Key,重複的請求會直接回放已快取的回應,不會重複掃描。完整的請求/回應格式都在 API 文件裡。
curl -X POST https://api.space-ocr.com/upload \
-H "Authorization: Bearer $SPACE_OCR_API_KEY" \
-F "path=/Invoices 2026" \
-F "files=@scan-page-01.png" \
-F "files=@scan-page-02.png" \
-F "wait=true"如何將掃描 PDF 轉成 Excel
- 加入你的 PDF 或頁面影像在 space-ocr 應用程式裡,直接把 PDF 丟進去就好——每一頁都會自動算繪成影像,所以沒有什麼需要轉換的。如果你是直接呼叫 REST API,請先把每一頁匯出成點陣影像,因為引擎讀的是點陣影像(JPEG、PNG、GIF、BMP、TIFF、WebP),而不是 PDF 的位元組。
- 把整頁讀成欄位把數值抽成具名欄位。最快的方式是讓應用程式從頁面自動提議欄位;如果你已經知道要哪些欄,也可以自行定義欄位結構。重複的明細列請宣告一個 array 欄位。
- 抽查數值把滑鼠移到欄位上,標示出它在原始掃描檔上的讀取位置。只需要複核被標記的數值——API 會把它們連同理由放在 data.review.flagged 裡,其餘的維持原樣即可。
- 匯出 CSV把整張表匯出成 CSV。它是帶 BOM 的 UTF-8,會把 array 明細列展開成子列,而且任何手動修正都會覆蓋原本的 OCR 數值。
- 在 Excel 開啟雙擊那個 CSV——Excel 會讀取 BOM,打開你的資料列,欄位對齊、CJK 文字完整無誤。如果你需要原生活頁簿,再另存成 .xlsx。