把扫描文档转成 CSV 的完整方法
教你如何把扫描文档转成 CSV:列只需定义一次,上传照片或扫描件,每份文档自动填入一行。导出为带 BOM 的 UTF-8 CSV,Excel 和中日韩文字都能正常打开。
你手头堆着一摞纸——发票、收据、送货单——要把它们变成电子表格里的一行行数据。手动重新录入又慢又容易出错,而普通的 OCR 工具只会吐出一大坨原始文本,还得自己费劲拆成一列列。其实你真正想做的事情更具体、也更有用:把一份文档的照片或扫描件,变成一行干净的 CSV,每个值都落在正确的列里,每次都如此。
这篇指南讲的正是这件事。你只需把列定义一次,把图片交给 space-ocr,每份文档就会自动填好一行。做完之后,把整张表导出为 CSV——带字节序标记(BOM)的 UTF-8,因此 Excel 和中日韩文字都能正常打开。无需重新录入,而且每个值都能追溯到它在页面上的位置。
整个流程长什么样
把扫描文档转成 CSV,可以拆成四步:
- 拍照或扫描你的文档——栅格图像(JPEG、PNG、TIFF 等)。手机随手拍就行;歪着拍也没关系,会自动旋转校正。
- 把列定义一次——给你关心的字段起好名字(
vendor、date、total、明细行……)。这就成了之后每份文档都对照读取的列结构。 - 上传——每张图片被读取,值落入你那些列下面的新一行。无需逐份配置。
- 导出 CSV——把整张表下载为
<sheetName>.csv,到哪儿都能打开。
好处在于一致:因为列在一开始就固定下来,第十张收据落进来的形状跟第一张完全一样。
先看证据:每个值都知道自己从哪来
讲步骤之前,先说说为什么它值得信赖。把鼠标移到下面任意一个字段上——收据上的方框会标出这个值是从哪个位置读出来的,每个字段还带有一个匹配率(match ratio)。一份 CSV,只有当里面的数字都经得起核对时才真正有用,而这里每个单元格都能追溯回原始像素。

Each value with a box 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.
手把手:怎么把扫描文档转成 CSV
1. 把文档拍成图片
space-ocr 读取的是栅格图像——JPEG、PNG、GIF、BMP、TIFF 和 WebP。把收据摆在桌上拍照、把发票扫成 PNG,或者从扫描软件里导出页面都行。扫描版 PDF 也可以直接丢进应用,每一页都会自动转成图片。手机歪着拍也没问题:引擎会读取 EXIF 方向信息并校正旋转,所以即使是侧着拍的照片也能正立读取,值依然能锚定到正确的位置。
2. 把列定义一次
正是这一步,把 OCR 变成了一张整洁的表格。建一张表,给它定好列结构——也就是你想作为 CSV 表头的那些字段。标量列是简单的单值(vendor、invoice_date、total);数组列用来装会重复出现的明细行。这个只定义一次,之后你上传的每份文档都会对照同样的列来读取。
vendor (string)
invoice_date (string)
total (string)
items (array) → name, unit_price, qty
如果你不想手动搭这套结构,内置模板(invoice、receipt、business_card 等)会为常见文档类型提供好字段和提示词。专门针对发票的情况,可以看从发票中提取明细行。
3. 上传——行自己填好
列就位之后,把图片上传到这张表。每份文档变成一行:引擎读取页面,把每个值放进对应的列下。丢进二十张收据,你就得到二十行,形状完全一致。明细行数组会作为该行的结构化子项保留下来,导出时随时可以展开。
值是原样返回的——7,855 里的逗号保留、全角字符和敬称也一并保留——所以你的 CSV 反映的是页面上印的内容,而不是被重新格式化过的猜测。
4. 导出为 CSV
点击导出,表会下载为 <sheetName>.csv。表头行直接由你的列结构生成:
- 开头一列
#(行号)。 - 每个标量列名按原样列出。
- 每个数组子字段展平为
colName.childName——所以一个带name和unit_price的items数组会生成items.name和items.unit_price两列。
包含明细行数组的行会展开成多个子行——父级的标量值出现一次,每条明细行在其下面各占一行,于是一张有八条明细的发票就变成八行 CSV,共享同一个供应商和日期。文件以带字节序标记(BOM)的 UTF-8 写出,正是这个 BOM 让 Excel——以及日文、韩文、中文——打开时不会出现乱码。
如果你手动改过某个单元格,导出时你手填的值会覆盖原始 OCR 值,所以修正会一路体现到 CSV 里。
CSV 是按你的列生成的,不是猜出来的。 表头来自你的列结构(# + 标量列名 + 明细行的 array.child),数组行展开成子行,文件以 带 BOM 的 UTF-8 输出,所以 Excel 和中日韩文字都能正常打开。导出时手动修改会覆盖 OCR 值——列的形状在你定义它的那一刻就固定了,正因如此每次下载都是可预期的。
用 API 来做
同样的流程也可以无界面地跑。先建一张带列的表,往里上传图片,再用 GET /view 把结构化的行拉出来——在服务端完成,不重跑 OCR,也不计费。从这里你可以自己写出 CSV,或者直接获取这张表的 CSV 导出。GET /view 还允许你在导出前筛选(where)、排序、挑选列,这样就只输出你需要的那些行。
# 1. Create a sheet with the columns you want as CSV headers
curl -X POST https://api.space-ocr.com/create \
-H "Authorization: Bearer $SPACE_OCR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"path": "/invoices",
"type": "sheet",
"name": "june-invoices",
"columns": [
{ "name": "vendor", "type": "string" },
{ "name": "invoice_date", "type": "string" },
{ "name": "total", "type": "string" },
{ "name": "items", "type": "array",
"children": [
{ "name": "name", "type": "string" },
{ "name": "unit_price", "type": "string" }
] }
]
}'
# 2. Upload document images — each one fills a row
curl -X POST https://api.space-ocr.com/upload \
-H "Authorization: Bearer $SPACE_OCR_API_KEY" \
-F "path=/invoices/june-invoices" \
-F "files=@invoice-01.png" \
-F "files=@invoice-02.jpg"行就位之后,GET /view 会把它们以结构化 JSON 返回,你可以直接写成 CSV——或者交给你的会计系统。想完整了解提取端点和字段规格,可以看发票数据提取 API 指南和 API 文档。
扫描版 PDF,以及关于输入的一点说明
space-ocr 的引擎处理的是栅格图像,而不是 PDF 字节——不过在应用里你不用操心这件事:把扫描版 PDF 丢进来,每一页都会在 OCR 之前自动栅格化成图片。只有当你直接调用公开 API 时,才需要先把每一页渲染成图片(PNG 或 JPEG)再上传。如果你的目标明确是 Excel 而不是 CSV,同样这套流程照样适用——具体步骤见把扫描版 PDF 转成 Excel。CSV 是阻力最小的目标:哪儿都能打开,而带 BOM 前缀的 UTF-8 导出意味着不会有编码上的意外。
- 把文档拍成图片把每份文档拍照或扫描成栅格图像(JPEG、PNG、TIFF 等)。手机照片就行——EXIF 自动旋转会校正侧拍的照片。扫描版 PDF 也行:把 PDF 丢进 space-ocr 应用,每一页都会自动栅格化(只有直接调用 API 时才需要先把每一页渲染成图片)。
- 把列定义一次建一张表并定好列结构:像 vendor、date、total 这样的标量列,外加用于装重复明细行的数组列。这会成为 CSV 表头,并对每份文档复用。
- 上传图片把你的文档图片上传到这张表。每张图片被读取,值自动填入你那些列下面的新一行——无需逐份设置,而且值会原样保留。
- 导出为 CSV导出这张表。它会下载为 <sheetName>.csv,表头是 # 加上标量列名,再加上展平为 colName.childName 的数组子字段。明细行会展开成子行,文件是带 BOM 的 UTF-8,所以 Excel 和中日韩文字都能正常打开。