وظيفة السحابة الإلكترونية لاستيراد بيانات ملفات CSV إلى "جداول بيانات Google" بشكل تلقائي

1. مقدمة

يهدف هذا الدرس التطبيقي إلى فهم كيفية كتابة دالة Cloud للتفاعل مع تحميل ملف CSV إلى Cloud Storage، وقراءة محتواه واستخدامه لتعديل جدول بيانات Google باستخدام Sheets API.

e9c78061022a6760.png

ويمكن النظر إلى ذلك على أنّه عملية "استيراد كملف CSV" يدويًّا. . يضمن ذلك قدرتك على تحليل البيانات (ربما من إنتاج فريق آخر) في جدول البيانات بمجرد توفرها.

في ما يلي طريقة التنفيذ :

52df703605ae4bd3.png

2. الإعداد والمتطلبات

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Cloud Console وأنشِئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. (إذا لم يكن لديك حساب على Gmail أو G Suite، عليك إنشاء حساب.)

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

يُرجى تذكُّر رقم تعريف المشروع، وهو اسم فريد في جميع مشاريع Google Cloud (سبق أن تم استخدام الاسم أعلاه ولن يكون مناسبًا لك). ستتم الإشارة إليها لاحقًا في هذا الدرس التطبيقي حول الترميز باسم PROJECT_ID.

  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.

إنّ تنفيذ هذا الدرس التطبيقي حول الترميز لن يكون مكلفًا أو مكلفًا على الإطلاق. احرص على اتّباع أي تعليمات في قسم "الحذف سريعًا". الذي يقدم لك نصائح حول كيفية إيقاف تشغيل الموارد حتى لا تتكبّد أي فواتير خارج نطاق هذا البرنامج التعليمي. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج الفترة التجريبية المجانية التي تبلغ قيمتها 300 دولار أمريكي.

3- إنشاء جدول بيانات Google وضبطه وتفعيل واجهة برمجة التطبيقات

أولاً، لنقم بإنشاء مستند جديد في "جداول بيانات Google" (يمكن أن تنتمي هذه الورقة إلى أي مستخدم). بعد إنشائها، تذكر معرّفها؛ سيتم استخدامه كمتغير بيئة للدالة التي سنكتبها :

dd77d5fc1364ad3e.png

من وحدة تحكم Google Cloud Platform، يمكنك تفعيل Google Sheets API في المشروع الذي تم إنشاؤه حديثًا من خلال الانتقال إلى "واجهات برمجة التطبيقات والخدمات". ثم "مكتبة واجهة برمجة التطبيقات" القسم :

c64e2e98b8b55f16.png

في قسم "إدارة الهوية وإمكانية الوصول المشرف" انتقِل إلى "حسابات الخدمة" ودوِّن البريد الإلكتروني لحساب خدمة App Engine التلقائي. ويجب أن يكون بالصيغة your-project-id@appspot.gserviceaccount.com. وبالطبع، يمكنك أيضًا إنشاء حساب خدمة مخصّص لهذا الإجراء.

6e279d7e07d4febf.png

وأخيرًا، ما عليك سوى منح امتيازات تعديل حساب الخدمة هذا لجدول البيانات باستخدام الزر "مشاركة" الزر :

c334062465ddf928.png

من خلال هذا الإعداد، يمكننا الآن كتابة دالة السحابة الإلكترونية وضبطها لاستخدام حساب الخدمة هذا. ستتمكن من الكتابة في مستند جدول البيانات هذا الذي أنشأناه للتو.

4. إنشاء حزمة تخزين

لنُنشئ الحزمة التي ستراقبها دالة السحابة الإلكترونية للعثور على ملفات CSV الجديدة.

في وحدة التحكّم، استخدِم القائمة على يمين الصفحة للانتقال إلى "مساحة التخزين"... :

2ddcb54423979d25.png

... وأنشئ حزمة جديدة باسم csv2sheet-POSTFIX (استبدِل POSTFIX بشيء فريد) مع ضبط جميع الإعدادات الأخرى على قيمها التلقائية :

dd637080ade62e81.png

5- إنشاء دالة السحابة الإلكترونية

يمكننا الآن إنشاء دالة Cloud تُسمى csv2sheet التي يتم تشغيلها عند تحميل الملفات إلى حزمة معيّنة على Cloud Storage. ستتم كتابة الرمز في Node.js 8 مع دوال غير متزامنة باستخدام المحرِّر المضمّن مباشرةً في Cloud Console :

6ee1a5ce63174ae8.png

تأكَّد من ضبط "المشغّل" على "Cloud Storage" ولضبط اسم الحزمة على اسم الحزمة التي أنشأتها في الخطوة السابقة.

عدِّل أيضًا نقطة الدخول للدالة التي نحن بصدد كتابتها في csv2sheet :

446e7c7c992c2d8a.png

الآن قم بتغيير نص الدالة إلى :

  1. استخدام واجهات برمجة تطبيقات Cloud Storage و"جداول بيانات Google"
  2. وضع علامة async على الدالة csv2sheet
  3. الحصول على fileName من البيانات الوصفية لحدث Cloud Storage والحصول على اسم لورقة البيانات الجديدة التي سننشئها :
const {google} = require("googleapis");
const {Storage} = require("@google-cloud/storage")

exports.csv2sheet = async (data, context) => {
  var fileName = data.name;
  // basic check that this is a *.csv file, etc...
  if (!fileName.endsWith(".csv")) {
    console.log("Not a .csv file, ignoring.");
    return;
  }
  // define name of new sheet  
  const sheetName = fileName.slice(0, -4);

  // TODO!
};

يجب استخدام async هنا لاستخدام await كما سنرى بعد قليل.

هناك خياران مهمان أثناء إنشاء هذه الدالة يتضمنان (انقر فوق رابط "المزيد" في الجزء السفلي من الشاشة) :

  • استخدِم القائمة المنسدلة لاختيار حساب الخدمة المذكور أعلاه.
  • حدِّد متغيّر بيئة يُسمى SPREADSHEET_ID والذي يجب أن يتطابق مع مستند ورقة البيانات الذي أنشأته سابقًا :

fd22d1873bcb8c66.png

كخطوة إعداد أخيرة، في ما يلي محتوى package.json مع Cloud Storage وGoogle Sheet APIs كمستندَين مستقلَّين سنستخدمهما (استخدِم علامة التبويب PACKAGE.JSON للمحرّر المضمّن في وحدة التحكّم) :

{
    "name": "csv2sheet",
    "version": "0.0.42",
    "dependencies": {
        "googleapis": "^51.0.0",
        "@google-cloud/storage": "^5.0.1"
    }
}

بعد الانتهاء من ضبط كل شيء كما هو موضّح، انقر على "إنشاء" ! بعد دقيقة قصيرة، يجب إنشاء الدالة ونشرها.

6- عملية إعداد المصادقة وواجهة Google Sheets API

قبل أن نكتب أي رمز آخر في دالة Google Cloud باستخدام المحرِّر المضمّن، علينا حظر إنشاء Google Client API باستخدام نطاقَي "مساحة التخزين" و"جداول بيانات Google" المناسبَين (تذكّر أنّ هذا جزء من إحدى الدوال async).

في محرر الدوال بوحدة التحكم، انقر على "EDIT" وأضِف الرمز التالي إلى نص الدالة csv2sheet :

// block on auth + getting the sheets API object
const auth = await google.auth.getClient({
  scopes: [
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/devstorage.read_only"
  ]
});

من هناك، يمكننا إنشاء عميل Sheets API :

const sheetsAPI = google.sheets({version: 'v4', auth});

7. استخدام Sheets API لإنشاء ورقة بيانات فارغة

باستخدام برنامج Sheets API، يمكننا إنشاء ورقة بيانات جديدة وبسيطة في المستند، ولكن قبل أن ننتقل إلى مزيد من التفاصيل، إليك ملاحظة سريعة حول المفردات:

  • جدول البيانات هو المستند الفعلي وتتم الإشارة إليه من خلال معرّفه (تمت مناقشته أعلاه وظاهر في عنوان URL للمستند)
  • الورقة هي إحدى علامات التبويب في المستند ويمكن الإشارة إليها باسمها (اسم علامة التبويب) أو المعرّف الذي يتم إنشاؤه عند إنشاء الورقة.

مع وضع ذلك في الاعتبار، إليك دالة تستخدم برنامج Sheets API لإنشاء ورقة فارغة في الموضع 2 (عادةً بعد "Sheet1" الافتراضي)، مع 26 عمودًا، 2000 صف، مع تجميد الصف الأول (إضافته إلى الدالة باستخدام المحرِّر المضمّن) :

function addEmptySheet(sheetsAPI, sheetName) {
  return new Promise((resolve, reject) => {
    const emptySheetParams = {
      spreadsheetId: process.env.SPREADSHEET_ID,
      resource: {
        requests: [
          {
            addSheet: {
              properties: {
                title: sheetName,
                index: 1,
                gridProperties: {
                  rowCount: 2000,
                  columnCount: 26,
                  frozenRowCount: 1
                }
              }
            }
          }
        ]
      }
    };
    sheetsAPI.spreadsheets.batchUpdate( emptySheetParams, function(err, response) {
        if (err) {
          reject("The Sheets API returned an error: " + err);
        } else {
          const sheetId = response.data.replies[0].addSheet.properties.sheetId;
          console.log("Created empty sheet: " + sheetId);
          resolve(sheetId);
        }
      }
    );
  });
}

يُرجى العِلم أنّنا نعتمد على متغيّر بيئة SPREADSHEET_ID الذي تم إنشاؤه سابقًا بدلاً من إجراء ترميز ثابت للمرجع إلى جدول البيانات.

نحتاج إلى تذكُّر sheetId للطلبات الإضافية التي يتم إجراؤها على ورقة البيانات هذه بالتحديد. يجب أيضًا أن يكون اسم الورقة فريدًا ولن تتمكّن من إنشائه إذا سبق أن توفّرت ورقة باسم sheetName.

الدالة batchUpdate في Sheets API هي طريقة شائعة للتفاعل مع المستندات، وهي موضحة هنا.

8. قراءة البيانات من ملف CSV للتخزين

وبعد أن أصبح لدينا مكان لتفريغ بياناتنا، يمكننا مواصلة تطوير دالة السحابة الإلكترونية في المحرِّر المضمّن واستخدام Cloud Storage API للحصول على البيانات الفعلية من الملف الذي تم تحميله للتو وتخزينها في سلسلة:

function readCSVContent(sheetsAPI, file, sheetName) {
  return new Promise((resolve, reject) => {
    const storage = new Storage();
    let fileContents = new Buffer('');
    storage.bucket(file.bucket).file(file.name).createReadStream()
    .on('error', function(err) {
      reject('The Storage API returned an error: ' + err);
    })
    .on('data', function(chunk) {
      fileContents = Buffer.concat([fileContents, chunk]);
    })  
    .on('end', function() {
      let content = fileContents.toString('utf8');
      console.log("CSV content read as string : " + content );
      resolve(content);
    });
  });
}

9. تعبئة ورقة البيانات التي تم إنشاؤها حديثًا

حان الوقت الآن لملء ورقة البيانات التي أنشأناها باستخدام واجهة برمجة تطبيقات Sheet client نفسها والبيانات التي جمعناها للتو. سنغتنم هذه الفرصة لإضافة بعض الأنماط إلى أعمدة الورقة (تغيير حجم الخط في الصف العلوي وجعله غامقًا) :

function populateAndStyle(sheetsAPI, theData, sheetId) {
  return new Promise((resolve, reject) => {
    // Using 'batchUpdate' allows for multiple 'requests' to be sent in a single batch.
    // Populate the sheet referenced by its ID with the data received (a CSV string)
    // Style: set first row font size to 11 and to Bold. Exercise left for the reader: resize columns
    const dataAndStyle = {
      spreadsheetId: process.env.SPREADSHEET_ID,
      resource: {
        requests: [
          {
            pasteData: {
              coordinate: {
                sheetId: sheetId,
                rowIndex: 0,
                columnIndex: 0
              },
              data: theData,
              delimiter: ","
            }
          },
          {
            repeatCell: {
              range: {
                sheetId: sheetId,
                startRowIndex: 0,
                endRowIndex: 1
              },
              cell: {
                userEnteredFormat: {
                  textFormat: {
                    fontSize: 11,
                    bold: true
                  }
                }
              },
              fields: "userEnteredFormat(textFormat)"
            }
          }       
        ]
      }
    };
        
    sheetsAPI.spreadsheets.batchUpdate(dataAndStyle, function(err, response) {
      if (err) {
        reject("The Sheets API returned an error: " + err);
      } else {
        console.log(sheetId + " sheet populated with " + theData.length + " rows and column style set.");
        resolve();
      }
    });    
  });
}

يجب إضافة هذا الرمز إلى دالة السحابة التي اكتمل استخدامها بنسبة% 99 الآن.

لاحِظ كيفية دمج كل من البيانات والنمط على هيئة requests متعددة في طلب batchUpdate واحد لواجهة Sheets API. ويساعد ذلك في إجراء تحديث أكثر فعالية وسلاسة.

لاحظ أيضًا أننا نحدد نطاق تعديل يتطابق مع حجم الورقة التي أنشأناها. يعني ذلك أنّ المحتوى الذي يتجاوز 26 عمودًا (القيمة columnCount المستخدَمة عند إنشاء ورقة البيانات) لن يتضمّن هذا الرمز تحديدًا.

إذا سارت الأمور على ما يرام، يمكنك في هذه المرحلة:

  1. حفظ الدالة المحدّثة
  2. إفلات ملف CSV في الحزمة
  3. ترى البيانات المقابلة تظهر في جدول البيانات!

10. إن وضع كل شيء معًا واختبار التدفق

يمكن إجراء استدعاءات للدوال التي ناقشناها للتو كاستدعاءات حظر متتالية في دالة csv2sheet الأصلية:

  const sheetId = await addEmptySheet(sheetsAPI, sheetName);
  const theData = await readCSVContent(sheetsAPI, data, sheetName);
  await populateAndStyle(sheetsAPI, theData, sheetId);

إذا كنت بحاجة إلى رمز المصدر الكامل للدالة، يمكنك الاطّلاع عليه هنا (ربما يكون من الأسهل الحصول عليه في مجموعة واحدة).

بمجرد وضع كل شيء في مكانه الصحيح، ما عليك سوى تحميل ملف CSV إلى الحزمة المناسبة ومشاهدة تحديث جدول البيانات بورقة جديدة تشتمل على محتوى الملف. إليك نموذج لملف CSV إذا لم يكن متوفرًا لديك.

1efae021942e64fa.png

يُرجى محاولة تحميل عدة ملفات إلى الحزمة لمعرفة ما سيحدث.

11. هذا كل شيء! حان الوقت لهدم البنية التحتية

أمزح، ولا توجد بنية تحتية يمكن التخلص منها، وقد تم كل ذلك دون الحاجة إلى خوادم.

يمكنك، إن أردت، حذف الدالة السحابية والحزمة التي أنشأتها أو حتى المشروع بأكمله.

12. ما هي الخطوات التالية؟

وبهذا نكون قد انتهينا من هذا الدرس التطبيقي الذي يرشدك إلى خطوات الاستماع إلى عمليات التحميل إلى حزمة Cloud Storage في إحدى الدوال بالسحابة الإلكترونية لتعديل جدول بيانات Google باستخدام واجهة برمجة التطبيقات المناسبة.

في ما يلي بعض خطوات المتابعة :

إذا واجهت مشاكل في هذا الدرس التطبيقي حول الترميز، يمكنك الإبلاغ عن أي مشكلة باستخدام الرابط في أسفل يمين الصفحة.

ونحن نُقدِّر ملاحظاتك.