מיזוג טקסט למסמך

אחד השימושים המועילים ב-Google Docs API הוא מיזוג מידע ממקור נתונים אחד או יותר במסמך.

בדף הזה מוסבר איך אפשר לקחת נתונים ממקור חיצוני ולהוסיף אותם למסמך תבנית קיים.

תבנית היא סוג מיוחד של מסמך שמכיל את אותו טקסט קבוע לכל המסמכים שנוצרו מהתבנית, יחד עם placeholders ייעודיים שאפשר להציב בהם טקסט דינמי אחר. לדוגמה, תבנית חוזה יכולה לכלול תוכן קבוע, וגם מקומות לשם הנמען, לכתובת ולפרטים אחרים. לאחר מכן האפליקציה יכולה למזג נתונים ספציפיים ללקוח בתבנית כדי ליצור מסמכים מוכנים.

יש כמה סיבות לכך שהגישה הזו שימושית:

  • מעצבים יכולים בקלות לשפר את העיצוב של מסמך באמצעות כלי העריכה של Google Docs. השיטה הזו הרבה יותר פשוטה מאשר כוונון פרמטרים באפליקציה כדי להגדיר את הפריסה המעובדת.

  • הפרדה בין התוכן לבין אופן ההצגה היא עיקרון עיצובי מוכר עם יתרונות רבים.

דיאגרמה מושגית של מיזוג.

מתכון בסיסי

הנה דוגמה לאופן שבו אפשר להשתמש ב-Docs API כדי למזג נתונים במסמך:

  1. יוצרים את המסמך באמצעות תוכן Placeholder כדי לעצב אותו ולשנות את הפורמט שלו. כל עיצוב טקסט שרוצים להחליף נשמר.

  2. לכל רכיב שמוסיפים, מחליפים את תוכן ה-placeholder בתג. חשוב להשתמש במחרוזות שסביר להניח שלא יופיעו בדרך כלל. לדוגמה, {{account-holder-name}} יכול להיות תג טוב.

  3. בקוד, משתמשים ב-Google Drive API כדי ליצור עותק של המסמך.

  4. בקוד, משתמשים בשיטה batchUpdate() של Docs API עם שם המסמך וכוללים ReplaceAllTextRequest.

מזהי מסמכים מפנים למסמך, ואפשר להפיק אותם מכתובת ה-URL

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

דוגמה

בדוגמה הבאה, שני שדות בכל הכרטיסיות של תבנית מוחלפים בערכים אמיתיים כדי ליצור מסמך מוכן.

כדי לבצע את המיזוג הזה, אפשר להשתמש בקוד שלמטה.

Java

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. יוצרים מסמך באמצעות documents.create ב-Docs API.
  2. מעדכנים את ההרשאות כדי לאפשר לנמעני המסמך לקרוא אותו באמצעות permissions.create ב-Drive API.
  3. מעדכנים את ההרשאות כדי לאפשר ליוצרי התבניות לכתוב אליו באמצעות permissions.create ב-Drive API.
  4. עורכים את התבנית לפי הצורך.

כדי ליצור מופע של המסמך, מבצעים את השלבים הבאים עם פרטי הכניסה של המשתמש:

  1. יוצרים עותק של התבנית באמצעות files.copy ב-Drive API.
  2. החלפת ערכים באמצעות documents.batchUpdate ב-Docs API.