문서에 텍스트 병합

Google Docs API의 유용한 한 가지 적용 사례는 하나 이상의 데이터 소스의 정보를 문서로 병합하는 것입니다.

이 페이지에서는 외부 소스에서 데이터를 가져와 기존 템플릿 문서에 삽입하는 방법을 간략히 설명합니다.

템플릿은 템플릿에서 생성된 모든 문서에 동일한 고정 텍스트와 다른 동적 텍스트를 배치할 수 있는 지정된 자리표시자를 포함하는 특수한 유형의 문서입니다. 예를 들어 계약 템플릿에는 수신자 이름, 주소, 기타 세부정보를 입력할 수 있는 공간과 함께 고정된 콘텐츠가 포함될 수 있습니다. 그러면 앱에서 고객별 데이터를 템플릿에 병합하여 완성된 문서를 만들 수 있습니다.

이 접근 방식이 유용한 이유는 다음과 같습니다.

  • 디자이너는 Google Docs 편집기를 사용하여 문서의 디자인을 쉽게 미세 조정할 수 있습니다. 렌더링된 레이아웃을 설정하기 위해 앱에서 매개변수를 조정하는 것보다 훨씬 쉽습니다.

  • 콘텐츠와 프레젠테이션을 분리하는 것은 잘 알려진 설계 원칙으로, 여러 이점이 있습니다.

병합의 개념적 다이어그램

기본 레시피

다음은 Docs API를 사용하여 데이터를 문서에 병합하는 방법의 예입니다.

  1. 디자인과 형식을 설정하는 데 도움이 되는 자리표시자 콘텐츠를 사용하여 문서를 만듭니다. 교체하려는 텍스트 서식은 그대로 유지됩니다.

  2. 삽입할 각 요소의 경우 자리표시자 콘텐츠를 태그로 바꿉니다. 일반적으로 발생할 가능성이 낮은 문자열을 사용해야 합니다. 예를 들어 {{account-holder-name}}가 적절한 태그일 수 있습니다.

  3. 코드에서 Google Drive API를 사용하여 문서의 사본을 만듭니다.

  4. 코드에서 문서 이름과 함께 Docs API의 batchUpdate() 메서드를 사용하고 ReplaceAllTextRequest를 포함합니다.

문서 ID는 문서를 참조하며 URL에서 파생될 수 있습니다.

https://docs.google.com/document/d/documentId/edit

다음 예를 살펴보세요. 이 예에서는 템플릿의 모든 탭에 있는 2개의 필드를 실제 값으로 바꿔 완성된 문서를 생성합니다.

이 병합을 실행하려면 아래 코드를 사용하면 됩니다.

자바

String customerName = "Alice";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String date = formatter.format(LocalDate.now());

List<Request> requests = new ArrayList<>();
// One option for replacing all text is to specify all tab IDs.
requests.add(new Request()
        .setReplaceAllText(new ReplaceAllTextRequest()
                .setContainsText(new SubstringMatchCriteria()
                        .setText("{{customer-name}}")
                        .setMatchCase(true))
                .setReplaceText(customerName)
                .setTabsCriteria(new TabsCriteria()
                        .addTabIds(TAB_ID_1)
                        .addTabIds(TAB_ID_2)
                        .addTabIds(TAB_ID_3))));
// Another option is to omit TabsCriteria if you are replacing across all tabs.
requests.add(new Request()
        .setReplaceAllText(new ReplaceAllTextRequest()
                .setContainsText(new SubstringMatchCriteria()
                        .setText("{{date}}")
                        .setMatchCase(true))
                .setReplaceText(date)));

BatchUpdateDocumentRequest body = new BatchUpdateDocumentRequest();
service.documents().batchUpdate(documentId, body.setRequests(requests)).execute();

Node.js

  let customerName = 'Alice';
  let date = yyyymmdd()
  let requests = [
    // One option for replacing all text is to specify all tab IDs.
    {
      replaceAllText: {
        containsText: {
          text: '{{customer-name}}',
          matchCase: true,
        },
        replaceText: customerName,
        tabsCriteria: {
          tabIds: [TAB_ID_1, TAB_ID_2, TAB_ID_3],
        },
      },
    },
    // Another option is to omit TabsCriteria if you are replacing across all tabs.
    {
      replaceAllText: {
        containsText: {
          text: '{{date}}',
          matchCase: true,
        },
        replaceText: date,
      },
    },
  ];

  google.options({auth: auth});
  google
      .discoverAPI(
          'https://docs.googleapis.com/$discovery/rest?version=v1&key={YOUR_API_KEY}')
      .then(function(docs) {
        docs.documents.batchUpdate(
            {
              documentId: '1yBx6HSnu_gbV2sk1nChJOFo_g3AizBhr-PpkyKAwcTg',
              resource: {
                requests,
              },
            },
            (err, {data}) => {
              if (err) return console.log('The API returned an error: ' + err);
              console.log(data);
            });
      });

Python

customer_name = 'Alice'
date = datetime.datetime.now().strftime("%y/%m/%d")

requests = [
        # One option for replacing all text is to specify all tab IDs.
        {
        'replaceAllText': {
            'containsText': {
                'text': '{{customer-name}}',
                'matchCase':  'true'
            },
            'replaceText': customer_name,
            'tabsCriteria': {
                'tabIds': [TAB_ID_1, TAB_ID_2, TAB_ID_3],
            },
        }},
        # Another option is to omit TabsCriteria if you are replacing across all tabs.
        {
        'replaceAllText': {
            'containsText': {
                'text': '{{date}}',
                'matchCase':  'true'
            },
            'replaceText': str(date),
        }
    }
]

result = service.documents().batchUpdate(
    documentId=document_id, body={'requests': requests}).execute()

템플릿 관리

애플리케이션이 정의하고 소유하는 템플릿 문서의 경우 애플리케이션을 나타내는 전용 계정을 사용하여 템플릿을 만듭니다. 서비스 계정은 공유를 제한하는 Google Workspace 정책으로 인한 문제를 방지할 수 있는 좋은 방법입니다.

템플릿에서 문서 인스턴스를 만들 때는 항상 최종 사용자 사용자 인증 정보를 사용하세요. 이렇게 하면 사용자가 결과 문서를 완전히 제어할 수 있으며 Drive의 사용자당 한도와 관련된 확장 문제를 방지할 수 있습니다.

서비스 계정을 사용하여 템플릿을 만들려면 애플리케이션 사용자 인증 정보로 다음 단계를 실행합니다.

  1. Docs API에서 documents.create를 사용하여 문서를 만듭니다.
  2. Drive API에서 permissions.create를 사용하여 문서 수신자가 문서를 읽을 수 있도록 권한을 업데이트합니다.
  3. 템플릿 작성자가 Drive API에서 permissions.create를 사용하여 쓰기를 허용하도록 권한을 업데이트합니다.
  4. 필요에 따라 템플릿을 수정합니다.

문서 인스턴스를 만들려면 사용자 사용자 인증 정보로 다음 단계를 실행합니다.

  1. Drive API에서 files.copy를 사용하여 템플릿 사본을 만듭니다.
  2. Docs API에서 documents.batchUpdate를 사용하여 값을 바꿉니다.