يوضّح هذا الدليل كيفية استخدام Google Docs API لدمج المعلومات من مصدر أو أكثر من مصادر البيانات الخارجية في مستند نموذج حالي.
القالب هو نوع من المستندات يحتوي على نص ثابت وعناصر نائبة للمحتوى الديناميكي. على سبيل المثال، قد يحتوي نموذج عقد على نص ثابت مع عناصر نائبية لاسم المستلم وعنوانه. بعد ذلك، يدمج التطبيق البيانات الخاصة بالمستخدم في النموذج لإنشاء المستند النهائي.
هناك عدة أسباب تجعل هذا النهج مفيدًا:
يمكن للمصمّمين تحسين تصميم المستند باستخدام "مستندات Google". وهذه الطريقة أبسط من ضبط المَعلمات في تطبيقك لتحديد التنسيق المعروض.
إنّ فصل المحتوى عن طريقة عرضه هو أحد مبادئ التصميم المعروفة التي تتضمّن العديد من المزايا.
طريقة عمل دمج المستندات
في ما يلي مثال على كيفية استخدام Docs API لدمج البيانات في مستند:
أنشئ مستندك باستخدام محتوى عناصر نائبة لمساعدتك في التصميم والتنسيق. يتم الاحتفاظ بأي تنسيق نص تريد استبداله.
لكل عنصر ستدرجه، استبدِل المحتوى النائب بعلامة احرص على استخدام سلاسل من غير المحتمل أن تحدث بشكل طبيعي. على سبيل المثال، قد تكون
{{account-holder-name}}علامة جيدة.في الرمز البرمجي، استخدِم Google Drive API لإنشاء نسخة من المستند.
في الرمز البرمجي، استخدِم طريقة
batchUpdateفي Docs API مع اسم المستند، وأدرِجReplaceAllTextRequest.
تشير معرّفات المستندات إلى مستند ويمكن استخراجها من عنوان URL:
https://docs.google.com/document/d/DOCUMENT_ID/edit
إدارة النماذج
بالنسبة إلى مستندات النماذج التي يحدّدها التطبيق ويمتلكها، أنشئ النموذج باستخدام حساب مخصّص يمثّل التطبيق. حسابات الخدمة هي خيار جيد وتتجنّب التعقيدات المتعلقة بسياسات Google Workspace التي تقيّد المشاركة.
عند إنشاء نُسخ من المستندات من النماذج، استخدِم دائمًا بيانات اعتماد المستخدم النهائي. ويمنح ذلك المستخدمين تحكّمًا كاملاً في المستند الناتج ويمنع حدوث مشاكل في التوسّع مرتبطة بالحدود القصوى المسموح بها لكل مستخدم في Google Drive.
لإنشاء نموذج باستخدام حساب خدمة، اتّبِع الخطوات التالية باستخدام بيانات اعتماد التطبيق:
- أنشئ مستندًا باستخدام
documents.createفي Docs API. - عدِّل الأذونات للسماح للمستلمين بقراءة المستند باستخدام
permissions.createفي Drive API. - عدِّل الأذونات للسماح لمؤلفي النماذج بالكتابة إليها باستخدام
permissions.createفي Drive API. - عدِّل النموذج حسب الحاجة.
لإنشاء نسخة من المستند، اتّبِع الخطوات التالية باستخدام بيانات اعتماد المستخدم:
- أنشِئ نسخة من النموذج باستخدام
files.copyفي Drive API. - استبدِل القيم باستخدام
documents.batchUpdateفي Docs API.
مثال: دمج البيانات في نموذج
يوضّح نموذج الرمز التالي كيفية استبدال حقلَين في جميع علامات تبويب أحد النماذج بقيم حقيقية لإنشاء مستند مكتمل:
لإجراء عملية الدمج هذه، استخدِم الرمز التالي:
جافا
String customerName = "Alice"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); String date = formatter.format(LocalDate.now()); // Make a copy of the template document using the Drive API. String copyTitle = "Merged Document"; File copyMetadata = new File().setName(copyTitle); File documentCopyFile = driveService.files().copy(DOCUMENT_ID, copyMetadata).execute(); String documentCopyId = documentCopyFile.getId(); Listrequests = 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(documentCopyId, 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, }, }, ]; // Make a copy of the template document using the Drive API. let copyTitle = 'Merged Document'; driveService.files.copy({ fileId: '1yBx6HSnu_gbV2sk1nChJOFo_g3AizBhr-PpkyKAwcTg', resource: { name: copyTitle, }, }, (err, driveResponse) => { if (err) return console.log('The Drive API returned an error: ' + err); let documentCopyId = driveResponse.data.id; 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: documentCopyId, 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") # Make a copy of the template document using the Drive API. copy_title = 'Merged Document' body = { 'name': copy_title } drive_response = drive_service.files().copy( fileId=DOCUMENT_ID, body=body).execute() document_copy_id = drive_response.get('id') 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_copy_id, body={'requests': requests}).execute()
التعامل مع القوائم والجداول الديناميكية
تستخدم عملية دمج المستندات العادية ReplaceAllTextRequest لاستبدال العناصر النائبة الفردية التي تُستخدَم لمرة واحدة (مثل {{customer-name}} أو {{date}}). ومع ذلك، إذا كانت بياناتك تتضمّن قائمة ديناميكية بالعناصر (مثل الأسطر في فاتورة أو قائمة بالمنتجات المطلوبة أو جدول ديناميكي)، لا يمكنك استخدام عملية استبدال النص العادية لأنّ عدد العناصر غير معروف أثناء تصميم النموذج.
للتعامل مع محتوى القائمة الديناميكية، استخدِم إحدى الاستراتيجيات التالية.
الخيار 1: إلحاق صفوف بجدول نموذج
إذا كان مستند النموذج يحتوي على جدول منسَّق (على سبيل المثال، مع صف عناوين وصف عنصر نائب واحد)، يمكنك إنشاء نسخ مكرّرة من الصفوف وتعبئتها بشكل ديناميكي لكل عنصر في قائمتك:
- قراءة بنية النموذج: استخدِم طريقة
documents.getلتحديد موقع الجدول وتحديد الفهرس لصف النموذج. - إدراج صفوف جديدة: لكل عنصر في قائمة بيانات الجمهور (باستثناء العنصر الأول الذي يمكنه إعادة استخدام صف القالب الحالي)، استدعِ الدالة
InsertTableRowRequestلإدراج صف جديد أسفل صف القالب. - ملء بيانات الخلايا: املأ الخلايا في صف النموذج عن طريق استبدال العناصر النائبة. بالنسبة إلى الصفوف التي تم إنشاؤها حديثًا، استخدِم
InsertTextRequestلإدراج النص المعنيّ في الموقع الجغرافي لكل خلية.
للاطّلاع على أمثلة حول كيفية إدراج صفوف في جدول، يُرجى الاطّلاع على العمل مع الجداول.
الخيار 2: استبدال علامة بجدول تم إنشاؤه
إذا أردت إنشاء الجدول من البداية آليًا، اتّبِع الخطوات التالية:
- وضع علامة عنصر نائب: استخدِم علامة واحدة (مثل
{{invoice-table}}) في مستند النموذج لتحديد المكان الذي يجب أن تظهر فيه القائمة. - تحديد موقع العنصر النائب: استخدِم عملية بحث للعثور على الفهرس الأوّلي للعلامة.
- حذف العنصر النائب: استخدِم
DeleteContentRangeRequestلإزالة النص{{invoice-table}}. - إدراج الجدول: أرسِل
InsertTableRequestفي فهرس البداية هذا، مع تحديد عدد الصفوف والأعمدة استنادًا إلى مصدر البيانات. - كتابة القيم: املأ كل خلية في الجدول بالتسلسل.
للاطّلاع على أمثلة حول إدراج الجداول آليًا، يُرجى الاطّلاع على العمل مع الجداول.