문서 내 텍스트로 필드 자동 배치하기

개요

POST /documents API로 서명을 요청할 때, 참여자 필드(서명란, 텍스트 입력란 등)의 위치를 지정하는 방법은 두 가지입니다.

좌표 기반 배치 (기존)

position 객체로 페이지 번호와 절대 좌표(x, y)를, size 객체로 크기(width, height)를 직접 지정합니다. 레이아웃이 고정된 정형 문서에 적합합니다.

Anchor 기반 배치 (신규)

position.anchor 객체로 문서 내 특정 텍스트를 기준점으로 지정합니다. 내용에 따라 레이아웃이 달라지는 비정형 문서에 적합합니다.

기존 좌표 기반 방식(position)에서는 페이지 내 정확한 위치를 직접 계산해야 합니다. 참여 인원이나 항목 수에 따라 페이지 구조가 달라지는 비정형 문서에서는 매번 좌표를 다시 계산해야 하므로, 최종 문서를 확인할 수 없는 상태에서 서명 위치를 "감으로 잡아야" 하는 문제가 있었습니다.

Anchor 기반 배치(position.anchor)를 사용하면 문서 내 텍스트(예: "서명란", "근로자 이름")를 기준점으로 지정하여 필드가 해당 위치에 자동으로 배치됩니다. 문서 레이아웃이 변경되더라도 기준 텍스트의 위치만 유지되면 필드가 올바르게 배치됩니다.

📘

기존 연동에 영향 없음

Anchor 기능은 기존 position + size 기반 필드 배치를 대체하지 않습니다. 기존 연동 코드는 변경 없이 그대로 동작합니다.


적용 API

엔드포인트메서드설명
/documentsPOST서명 요청

Anchor 기반 배치는 서명 요청 API의 participants[].fields 배열 내 각 필드 객체에서 사용할 수 있습니다.


동작 방식

Anchor 기반 배치는 다음과 같은 순서로 동작합니다.

  1. 문서 업로드 — 서명 요청 시 PDF, DOCX, HWP 등 텍스트 정보가 포함된 문서 파일을 업로드합니다.
  2. 텍스트 검색 — 서버에서 업로드된 문서를 파싱하여 anchor.text에 지정된 텍스트의 위치를 검색합니다. 동일한 텍스트가 여러 번 등장하면 매칭된 개수만큼 필드가 자동 생성됩니다.
  3. 필드 배치 — 검색된 텍스트 위치를 기준으로, anchor.offset만큼 이동한 좌표에 anchor.size 크기의 필드를 자동 생성합니다.
📘

페이지 자동 감지

좌표 기반 방식에서는 position.page로 페이지를 직접 지정해야 하지만, Anchor 기반 방식에서는 기준 텍스트가 위치한 페이지를 자동으로 감지합니다. 문서의 내용이 늘어나 텍스트가 다음 페이지로 밀리더라도 필드가 따라갑니다.


사용 방법

필드 생성 시 기존 positionx, y, page 대신 position.anchor 속성을 사용하여 텍스트 기반 위치를 지정합니다.

문서 내 텍스트를 기준으로 필드 위치를 자동 지정합니다. 기존 position에서 x, y, page 대신 anchor 객체를 사용합니다.

    {
      "type": "TEXT",
      "position": {
        "anchor": {
          "text": "근로자 이름",
          "offset": {
            "x": 0.01,
            "y": 0.005
          }
        }
      },
      "size": {
        "width": 0.2,
        "height": 0.05
      }
    }

지원 필드 타입

현재 Anchor 기반 배치를 지원하는 필드 타입은 다음과 같습니다.

필드 타입설명비고
TEXT텍스트 입력 필드textStyle, format 등 기존 옵션 사용 가능
SIGNATURE서명 필드signatureTypes, enableOneClick 등 기존 옵션 사용 가능
📘

CHECKBOX, SIGNING_DATE, IMAGE 등 기타 필드 타입은 기존 좌표 기반(position) 방식으로 배치합니다.


Anchor 파라미터

position.anchor 객체의 구조는 다음과 같습니다.

파라미터타입필수설명
textstring문서 내에서 찾을 기준 텍스트 (1~200자, 특수문자 허용, 영어 대소문자 구분)
offsetobject | null기준 텍스트로부터의 오프셋. null이면 텍스트 위치에 바로 필드를 배치합니다.
offset.xnumberX축 오프셋 (양수: 오른쪽, 음수: 왼쪽, 문서 너비 대비 비율)
offset.ynumberY축 오프셋 (양수: 아래쪽, 음수: 위쪽, 문서 높이 대비 비율)
📘

크기 지정

필드 크기(size)는 기존 좌표 기반 방식과 동일하게 position과 같은 레벨의 size 객체로 지정합니다. Anchor 사용 시에도 size.width, size.height는 필수입니다.


전체 요청 예시

아래는 하나의 서명 요청에서 Anchor 기반 필드와 기존 좌표 기반 필드를 함께 사용하는 예시입니다.

{
  "title": "근로계약서",
  "file": {
    "base64": "JVBERi0xLjQK...",
    "extension": "pdf"
  },
  "participants": [
    {
      "name": "김모두",
      "signingOrder": 1,
      "signingMethod": {
        "type": "EMAIL",
        "value": "[email protected]"
      },
      "fields": [
        {
          "type": "SIGNATURE",
          "required": true,
          "signatureTypes": ["SIGN"],
          "position": {
            "anchor": {
              "text": "근로자 서명",
              "offset": {
                "x": 0.01,
                "y": 0.005
              }
            }
          },
          "size": {
            "width": 0.15,
            "height": 0.05
          }
        },
        {
          "type": "TEXT",
          "required": true,
          "position": {
            "anchor": {
              "text": "근로자 이름",
              "offset": {
                "x": 0.08,
                "y": 0.0
              }
            }
          },
          "size": {
            "width": 0.2,
            "height": 0.04
          },
          "textStyle": {
            "size": 12,
            "font": "NOTO_SANS",
            "align": "LEFT"
          }
        },
        {
          "type": "CHECKBOX",
          "position": {
            "x": 0.05,
            "y": 0.8,
            "page": 1
          },
          "size": {
            "width": 0.03
          }
        }
      ]
    }
  ]
}
📘

한 문서 내 혼용 가능

위 예시처럼 서로 다른 필드에 대해 Anchor 기반과 좌표 기반을 혼용할 수 있습니다. Anchor를 지원하지 않는 필드 타입(CHECKBOX 등)은 기존 좌표 기반 방식을 사용하면 됩니다.


활용 시나리오

인사 문서 — 참여 인원에 따라 표 행이 늘어나는 계약서

참여 연구 수에 따라 표의 행이 늘어나는 계약서에서, 표 하단의 "서명란" 텍스트를 기준으로 서명 필드를 배치합니다. 행이 추가/삭제되어도 "서명란" 텍스트 위치에 맞춰 필드가 자동으로 이동합니다.

회의록 — 참석자·내용에 따라 길이가 달라지는 문서

참석자 수와 회의 내용에 따라 문서 길이가 달라지는 회의록에서, 각 참석자 이름 옆에 서명 필드를 배치합니다. 참석자가 추가되어 페이지가 넘어가더라도 이름 텍스트 기준으로 필드가 자동 배치됩니다.

계약서 — 조항 추가/삭제에 따라 서명 위치가 바뀌는 문서

계약 조건에 따라 항목이 추가/삭제되는 계약서에서, 마지막 페이지의 "갑" / "을" 텍스트를 기준으로 서명 필드를 배치합니다. 조항이 늘어나 서명 위치가 다음 페이지로 이동해도 자동으로 대응됩니다.


주의사항

⚠️

좌표와 Anchor는 상호 배타적입니다

하나의 필드에서 position에 좌표(x, y, page)와 anchor를 동시에 지정하거나, 둘 다 지정하지 않으면 400 오류가 발생합니다.

응답 예시:

{
  "statusCode": 400,
  "message": "Position must have either (x, y, page) or anchor, not both or neither"
}
// ❌ 잘못된 예시 — 좌표와 anchor 동시 지정
"position": {
  "x": 0.5,
  "y": 0.4,
  "page": 1,
  "anchor": {
    "text": "(인)"
  }
}

FAQ

400 Position must have either (x, y, page) or anchor 오류가 발생합니다.

position에 좌표(x, y, page)와 anchor를 동시에 지정하거나, 둘 다 지정하지 않았을 때 발생하는 오류입니다.

응답 예시:

  {
    "statusCode": 400,
    "message": "Position must have either (x, y, page) or anchor, not both or neither"
  }

다음 항목을 확인해 보세요.

  • 하나의 필드에서 x, y, pageanchor동시에 지정하고 있지 않은지 확인하세요.
  • position 객체에 좌표(x, y, page) 또는 anchor하나도 지정하지 않은 경우에도 동일한 오류가 발생합니다.
  • 반드시 둘 중 하나의 방식만 사용하세요.
404 AnchorTextNotFoundException 오류가 발생합니다.

anchor.text에 지정한 텍스트가 문서 내에 존재하지 않을 때 발생하는 오류입니다.

응답 예시:

  {
    "statusCode": 404,
    "error": "AnchorTextNotFoundException",
    "message": "Anchor text not found in PDF"
  }

다음 항목을 확인해 보세요.

  • 업로드한 문서에 anchor.text 값과 동일한 텍스트가 실제로 포함되어 있는지 확인하세요.
  • 대소문자, 공백, 특수문자가 정확히 일치하는지 확인하세요.
  • 스캔된 이미지 PDF의 경우, 텍스트 레이어가 없어 텍스트를 인식할 수 없습니다. OCR 처리된 PDF 또는 텍스트 기반 PDF를 사용하세요.
  • PDF 생성 시 폰트 임베딩 이슈로 텍스트가 깨질 수 있습니다. 표준 폰트를 사용하거나 폰트를 임베딩하여 PDF를 생성하세요.
한 문서 안에서 좌표 기반 필드와 Anchor 기반 필드를 함께 사용할 수 있나요?

네, 가능합니다. 서로 다른 필드에 대해 좌표 기반과 Anchor 기반을 혼용할 수 있습니다. 예를 들어, 서명 필드는 Anchor로, 체크박스 필드는 좌표 기반으로 배치하는 것이 가능합니다. 단, 하나의 필드 내에서 둘을 동시에 사용할 수는 없습니다.

이미지 파일(JPG, PNG 등)에서도 Anchor를 사용할 수 있나요?

아니요. bmp, gif, jpg, jpeg, png, tiff 등 이미지 파일은 텍스트 정보가 없으므로 Anchor 기반 배치를 지원하지 않습니다. 이미지 파일에는 기존 좌표 기반 방식을 사용하세요.

문서에 동일한 텍스트가 여러 번 등장하면 어떻게 되나요?

anchor.text와 일치하는 텍스트가 문서 내에 여러 번 등장할 경우, 매칭된 개수만큼 필드가 자동 생성됩니다. 예를 들어 "(인)" 텍스트가 문서에 3번 등장하면, 동일한 설정의 필드가 3개 생성됩니다.

이때 dataLabel이 지정되어 있으면 자동으로 넘버링됩니다.

  • 첫 번째 매칭: 개인정보 동의 서명 (1)
  • 두 번째 매칭: 개인정보 동의 서명 (2)
  • N번째 매칭: 개인정보 동의 서명 (N)
⚠️

자동 생성된 dataLabel이 다른 필드의 dataLabel과 중복되면 오류가 발생합니다. dataLabel 값을 설정할 때 넘버링 패턴과 충돌하지 않도록 주의하세요.

생성할 수 있는 필드 수에 제한이 있나요?

네, 다음 제한이 적용됩니다.

  • Anchor로 자동 생성되는 필드를 포함하여 전체 필드 수는 최대 2,000개입니다.
  • 서명/도장 필드는 최대 100개까지 생성할 수 있습니다.

제한을 초과하면 서명 요청이 실패하며 오류가 반환됩니다. 매칭되는 텍스트 수가 많을 경우, Anchor 텍스트를 더 구체적으로 지정하여 매칭 수를 조절하세요.

필드가 문서 페이지 영역을 벗어나면 어떻게 되나요?

anchor.offset 값이 너무 크거나 필드 크기가 문서 경계를 넘어서면, 페이지 영역을 벗어났다는 오류가 발생하며 서명 요청이 생성되지 않습니다. offsetsize 값을 조정하여 필드가 문서 영역 내에 위치하도록 설정하세요.