space ocr
가이드아티클요금문서
convert

스캔한 PDF를 엑셀로 변환하기: 한국어 표를 CSV로, 글자 깨짐 없이

스캔한 PDF는 이미지라서 복사가 안 되고, 엑셀에 붙여넣으면 한글이 깨지며 명세가 한 셀에 뭉개집니다. space-ocr 앱에 PDF를 드롭하면 각 페이지가 자동으로 이미지화되고, 열만 정해두면 1페이지=1행이 되어 UTF-8 BOM CSV로 출력됩니다. 엑셀에서 더블클릭으로 열어도 글자가 깨지지 않고, freee·머니포워드·야요이 등 회계 소프트웨어 CSV 가져오기도 그대로. 실패한 건은 과금되지 않습니다.

8 분 분량· 2026-08-31

스캔한 청구서나 영수증 PDF를 열었을 때 가장 먼저 깨닫는 사실은 이겁니다 ── 복사가 안 된다. 텍스트를 선택하려 해도 드래그가 되지 않고, 숫자 하나 집어낼 수 없습니다. 이유는 단순합니다. 스캔 PDF는 표 데이터가 아니라 '표가 찍힌 이미지' 이기 때문입니다. 사람 눈에는 행·열·합계가 줄지어 보여도, 컴퓨터에게는 그저 픽셀 덩어리일 뿐입니다.

그래서 많은 사람이 하는 일은 정해져 있습니다. 엑셀을 열고 PDF를 보면서 한 줄씩 손으로 입력합니다. 아니면 억지로 복사·붙여넣기를 해보고, 결과는 ── 한글이 어떻게 처럼 깨지고, 명세가 통째로 한 셀에 뭉개지며, 레이아웃이 완전히 무너집니다. '스캔 PDF 엑셀 변환', 'PDF 표 CSV', '엑셀 글자 깨짐 해결'로 검색하다 이 글에 닿았다면, 아픈 지점은 바로 여기일 겁니다 ── 결국 하고 싶은 건 회계 소프트웨어에 가져올 수 있는, 열이 가지런한 데이터를 손에 넣는 것뿐인데 말이죠.

결론: 손입력도 복붙도 필요 없다

할 일은 PDF를 그대로 space-ocr 앱에 드롭하는 것뿐입니다. 앱은 각 페이지를 자동으로 이미지화하고, 페이지 안의 값을 이름이 붙은 필드로 읽어냅니다. 열(거래처·날짜·합계·명세…)을 한 번 정해두면 1페이지=1행으로 시트에 쌓이고, 마지막에 CSV로 출력할 수 있습니다.

이 CSV가 핵심인데, UTF-8 BOM이 붙어 출력되므로 엑셀에서 더블클릭으로 열어도 한글이 깨지지 않습니다. 명세는 한 셀에 뭉개지지 않고 각각 별도의 행·열로 펼쳐집니다. 한국어 판정은 엔진이 자동으로 처리하므로 언어를 지정할 필요가 없습니다.

왜 스캔은 '그대로' 엑셀에 들어가지 않을까

종이를 스캔한 순간, 파일의 내용물은 사진과 똑같은 래스터 이미지입니다. 문자 정보가 들어 있지 않으므로 엑셀의 '데이터 가져오기'나 복붙으로는 표로 집어낼 수 없습니다. 그래서 두 단계가 필요합니다.

  1. 이미지를 읽어 구조화한다(각 페이지 → 이름이 붙은 필드의 행)
  2. 그 행을 CSV로 내보낸다(엑셀이 순순히 여는 형식으로)

space-ocr 앱에서는 PDF를 던지면 한 페이지씩 자동으로 이미지화(PNG)한 뒤 OCR합니다. 그래서 사용자가 직접 페이지를 이미지로 잘라낼 필요가 없습니다 ── PDF를 드롭하기만 하면 됩니다. 어려운 건 ①의 '읽어내기'이고, 이 부분을 정확하게 하는 것이 글자 깨짐과 명세 뭉개짐을 뿌리 뽑는 지름길입니다.

원본 이미지 → 추출 시트: 스캔이 '열'이 된다

드롭한 서류의 값은 문자의 벽이 아니라 이름이 붙은 열로 나옵니다. 열은 직접 정의해도 되고, 엔진에 제안하게 해도 됩니다(API 라면 fields 로 선언하거나 autoFields: true 로 제안받습니다). 스캔 한 장이 라벨이 달린 행으로 바뀌는 모습을 보세요.

서류를 드롭하면 값이 이름 붙은 필드에 안착 ── 이것이 엑셀에 늘어서는 '행'이 됩니다.

명세 행(청구서의 품목, 영수증의 상품)처럼 반복되는 행이 있는 서류는 array 타입 필드에 자식 열을 선언합니다. 그러면 페이지 위의 각 행이 저마다 독립된 행이 되어, 엑셀에서 합계를 낼 수 있는 형태가 됩니다 ── 이것이 '명세가 한 셀에 뭉개진다'는 문제의 정체에 대한 답입니다. 명세 구성법은 청구서·납품서를 읽어 엑셀로 만들기에서도 자세히 다룹니다.

날짜나 금액 열에는 type 으로 스칼라 타입(date / number / integer)을 선언할 수 있습니다. data.values 에는 서류에 인쇄된 표기 그대로(2026年3月31日, 1,200,000)가 남고, 그와 별개로 data.normalized 층이 붙어 결정론적 파서가 해석한 값 ── 날짜는 ISO 형식, 금액은 계산에 쓸 수 있는 숫자 ── 이 들어옵니다. 해석하지 못한 리프는 null 이 되고, 사유는 data.cells[경로].normalized.error 에, 검토 대상으로는 type_mismatchdata.review.flagged 에 실립니다. type 선언은 모델에 전달되지 않으므로 읽어내는 결과 자체가 달라지지는 않습니다 ── 달라지는 것은 엑셀이나 회계 소프트웨어로 넘기기 전에 계산 가능한 값을 별도 층으로 확보한다는 점입니다.

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이 실제로 페이지에서 검출한 심볼과 한 글자씩 대조(문자 단위 대조가 주력 경로) 하여 진짜 픽셀 위치에 박스를 둡니다. 대조가 돈 값에는 그 근거로 매치율(evidence.match_ratio ── 문자의 몇 퍼센트를 페이지에서 실제로 찾아냈는지)이 남습니다. 모델이 토큰 힌트를 돌려준 경우 그것으로 일부 필드의 위치를 덮어쓰기도 하지만, 반복 행에서는 힌트가 뒤바뀔 수 있으므로 곧이곧대로 믿지 않고 열 클러스터링과 행 일관성 검사로 검증·보정합니다. 핵심은 'AI가 틀리지 않는다'가 아니라, 대조된 값에는 근거가 남고, 대조하지 못한 값은 그 자체가 검토 대상으로 드러난다는 점입니다(위치를 확정하지 못하면 nobox, 문자가 어긋나면 text_mismatch 라는 사유가 붙습니다). 좌표는 box(xmin / ymin / xmax / ymax)와 기울기를 따라가는 4점 quad 로 함께 돌아오고, 둘 다 0〜1000 정규화(픽셀이 아닙니다)입니다.

가져오기 전에 스팟 체크하기

엑셀이나 회계 소프트웨어에 넣기 전에, 읽어낸 결과를 그 자리에서 확인할 수 있습니다. 값에 커서를 올리면 원본 스캔 이미지의 해당 부분이 빛나므로, 서류 전체를 다시 읽지 않아도 시선이 한 번에 그곳으로 날아갑니다.

전부를 다시 볼 필요는 없습니다. 엔진은 걸린 값에 검토 플래그를 세워 돌려주므로, 거기부터 보면 됩니다. 앱에서는 플래그가 선 셀에 색이 들어오고 사유(text_mismatch, missing 등)가 말풍선으로 뜹니다. API 에서는 같은 목록이 data.review.flagged 에 경로와 사유 배열로 실려 옵니다 ── 검토할 건수는 이 목록의 길이입니다. 고정된 점수 임계로 걸러내는 구조가 아닙니다.

필드에 마우스를 올려 원본 스캔과 맞대어 보기 ── 이상한 읽기를 시트에 가져오기 전에 잡아냅니다.

엑셀에서 열리는 CSV로 출력하기

값이 정확하면 시트를 CSV로 출력합니다. 헤더 행에 열 이름이 늘어서고, array 필드는 열이름.자식열이름 으로 펼쳐지며, 반복되는 명세는 하위 행으로 풀립니다. 파일은 UTF-8 BOM이 붙어 ── 이것이 바로 엑셀이 더블클릭만으로 한국어·중국어·일본어를 올바르게 여는 그 핵심 한 가지입니다. 손으로 고친 셀은 출력 시 원래 OCR 값을 덮어써 반영됩니다.

원클릭으로 UTF-8 BOM CSV 를 출력 ── 더블클릭하면 엑셀이 열이 가지런한 행으로 엽니다.

엑셀에서 여는 방법은 간단합니다 ── .csv더블클릭하기만 하면 됩니다. BOM 덕분에 엑셀은 UTF-8 로 자동 인식하므로, 텍스트 가져오기 마법사도 글자 깨짐도 없습니다. 네이티브 통합 문서가 필요하면 거기서 다른 이름으로 저장 → .xlsx 로 하면 됩니다.

그대로 회계 소프트웨어로 가져갈 때도 출구는 똑같은 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크레딧 ₩100 의 종량 과금, 매월 100크레딧 무료 한도(신용카드 불필요), 팀용 정액 Pro ₩69,800/월. 그리고 읽기에 실패한 건은 과금되지 않습니다 ── 결과가 나오지 않으면 청구되지 않습니다. CSV 내보내기는 무료 한도·종량 과금에서 1크레딧(같은 데이터를 다시 내려받는 것은 무료), Starter·Pro 에서는 다운로드가 무료입니다. 비용이 한눈에 들어오니, 우선 가지고 있는 스캔으로 시험해 보고 판단할 수 있습니다.

스캔 PDF를 엑셀로 변환하는 절차

  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. 엑셀 또는 회계 소프트웨어에서 열기
    CSV를 더블클릭하면 엑셀이 BOM을 UTF-8로 인식해, 한글이 깨지지 않고 열이 가지런한 행으로 엽니다. 네이티브 형식이 필요하면 다른 이름으로 저장으로 .xlsx 로. freee·머니포워드·야요이에는 각 소프트웨어의 CSV 가져오기로 읽어들입니다.
한국어 스캔도 지원하나요?
네. 언어 판정은 엔진이 자동으로 처리하므로 언어를 지정할 필요가 없습니다. 한국어·일본어·중국어·영어를 하나의 엔진으로 다룹니다. 스마트폰 사진은 EXIF 회전 정보가 픽셀에 반영된 상태로 읽힙니다. 기울기 보정(deskew)은 하지 않으므로, 비뚤게 찍힌 서류에서는 quad 좌표가 그 기울기를 따라 돌아옵니다.
PDF를 직접 지원하나요, 아니면 이미지로 변환해야 하나요?
앱은 PDF를 지원합니다. PDF를 드롭하면 각 페이지가 자동으로 이미지화(PNG)된 뒤 OCR되므로, 사용자가 직접 페이지를 이미지로 잘라낼 필요가 없습니다. 다만 공개 API로 직접 보낼 경우 입력은 래스터 이미지(JPEG·PNG·GIF·BMP·TIFF·WebP)입니다.
출력한 CSV를 엑셀에서 한글이 깨지지 않고 열 수 있나요?
네. CSV는 UTF-8 BOM이 붙어 출력됩니다. 이것이 엑셀이 인코딩을 자동 판별하게 하는 핵심으로, 더블클릭만 하면 한국어·중국어·일본어가 올바른 열에 들어갑니다. 텍스트 가져오기 마법사를 거칠 필요가 없습니다.
freee나 머니포워드, 야요이에 가져올 수 있나요?
출력물은 엑셀에서 열리는 CSV이므로, 각 회계 소프트웨어의 CSV 가져오기 기능으로 읽어들이는 방식입니다. 이는 공식 API 자동 연동이 아니라 CSV 파일 가져오기입니다. 열 이름이나 명세 펼침은 시트 쪽에서 정리한 뒤 출력할 수 있습니다.
정확도는 어떻게 확인하나요? 개인정보는 괜찮나요?
돌아온 값에는 페이지 위의 위치(box, 그리고 기울기를 따라가는 quad)와 대조 근거가 붙습니다. 필드에 마우스를 올리면 원본 스캔의 해당 부분이 빛나므로 원본과 맞대어 확인할 수 있습니다. 다시 봐야 할 값은 사유와 함께 검토 목록(API 에서는 data.review.flagged)에 모이고, 위치를 확정하지 못한 값도 거기에 드러나므로 전 항목을 눈으로 훑을 필요가 없습니다. 개인정보 쪽은, 공개 API 의 POST /ocr/* 는 이미지를 저장하지 않습니다. 앱의 마이스페이스에 올린 이미지는 삭제하면 저장된 원본까지 함께 지워집니다. 비용 면에서는 읽기에 실패한 건은 과금되지 않습니다.
관련 글