【问题标题】:What is the easiest way to import excel/google sheet spreadsheet to a Cloud Firestore database?将 excel/google 工作表电子表格导入 Cloud Firestore 数据库的最简单方法是什么?
【发布时间】:2019-05-08 03:55:20
【问题描述】:

我需要一次性将一张大型数据表导入我的数据库。我目前将其作为 Excel 文件保存,但我很乐意将其复制到 Google 表格等。

到目前为止,我已经直接通过 cloud firestore 手动添加了一些条目。

是否已经有解决方案来实现这一目标?

【问题讨论】:

    标签: google-cloud-firestore


    【解决方案1】:

    我认为将表格数据导出到 Firestore 的最简单方法是使用 Google Apps 脚本库(用于 Google 表格)。

    步骤 1

    复制我作为示例创建的THIS example Google Spreadsheet

    第二步

    从步骤 1 中的示例 Google 电子表格副本的菜单中,单击 Tools > Script Editor。这应该会打开与示例电子表格关联的示例 Google App 脚本。

    第三步

    按照安装this library 的步骤操作,然后使用以下内容更新脚本:

    • 电子邮件
    • 项目ID

    这些变量是通过转到Google Service Accounts page 生成的。这将要求您已经有 Firebase 或 Google Cloud 帐户设置。我不会重复aforementioned Github writeup 中已经迭代的所有步骤。仔细跟随他们,并意识到 private_key 是整个密钥,以 -----BEGIN PRIVATE KEY-----\n 开头,介于两者之间,以 \n-----END PRIVATE KEY-----\n 结尾

    第四步

    在您的电子表格中插入一个包含您的数据的页面,然后编辑脚本以使用您的新工作表名称和数据。我已经对脚本进行了大量评论,因此几乎每一行代码都在做什么非常清楚。对于那些只想查看spreadsheet 背后的 Google 应用脚本的人,代码如下:

    // Note this Script uses an external library as per this page: 
    // https://github.com/grahamearley/FirestoreGoogleAppsScript
    // This solution requires a Google Spreadhseet and a Firebase Account
    // FOLLOW THE INSTRUCTIONS ON THAT GITHUB REPO TO SETUP NEEDED API KEYS!!!
    
    //Global Variables
    const ss = SpreadsheetApp.getActiveSpreadsheet(); // Gets the active "workbook"
    const sheet = ss.getSheetByName('Restaurants'); // CHANGE TO YOUR SHEET NAME
    const headerRowNumber = 1; // If you have more than one row for your header, then change this value to number of header rows
    
    // If you want to mark modified cells, then set up a trigger for the following function:
    // Edit > Current Project Triggers > (+ Add Trigger) > On Edit Spreadsheet etc
    function onEdit(e) {
      var cell = ss.getActiveCell(); //This will also effectively get our row
      var dataRange = sheet.getDataRange(); //This checks for all rows/columns with data
      var modifiedCol = dataRange.getLastColumn()-1; //Our "modified" column should be the second to last
      if (cell.getColumn() < modifiedCol && cell.getRow() > headerRowNumber) { //If we edit any cells to the left of our modified column and below our header...
        var celltoMark = sheet.getRange(cell.getRowIndex(),modifiedCol)   //Get the R/C cordinates of cell to place modified time
        celltoMark.setValue(new Date()); //write timestamp to that cell
      }
    };
    // This will parse any comma separated lists you create in any of your fields (useful for search words, or attributes, etc)
    function listToArray(list) {
      var ogArray = list.split(","); //Input is a comma separated list
      let trimmedArr = ogArray.map(string => string.trim()); //Let's strip out the leading/trailing whitespaces if any
      return trimmedArr; //return the cleaned array
    }
    
    function writeToFireStore() {
      const email = 'sheets@yourprojectid.iam.gserviceaccount.com'; // CHANGE THIS!!!
      const key = '-----BEGIN PRIVATE KEY-----\nYOURPRIVATEKEY\n-----END PRIVATE KEY-----\n'; // CHANGE THIS!!!
      const projectID = 'yourprojectid'; // CHANGE THIS!!!
      var firestore = FirestoreApp.getFirestore(email, key, projectID);
      const collection = "MySpreadsheetData"; // Name of your Firestore Database "Collection"
    
      var dataRange = sheet.getDataRange().offset(headerRowNumber, 0, sheet.getLastRow() - headerRowNumber); //this is your data range
      var data = dataRange.getValues(); // this is an array of your datarange's values
      var lastCol = dataRange.getLastColumn(); // this is the last column with a header
      var newDoc = {}; // Instantiate your data object. Each one will become the data for your firestore documents
    
      // r = row number in this case
      for (let r = 0; r <= dataRange.getLastRow(); r++) {
        //Logger.log("R = ",r);
        var cellMod = dataRange.getCell(r+1, lastCol-1);
        var cellFS = dataRange.getCell(r+1, lastCol);
        var cellModVal = cellMod.getValue();
        var cellFSVal = cellFS.getValue();
        //
        // IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS IMPORTANT READ THIS!!!
        // Well, read the line below...
        if (r > 2) break; //Comment Out this line after you're done testing otherwise you'll write all your rows to firestore after every run
        newDoc[r] = {
          name : data[r][1],
          category : data[r][2],
          cuisine : data[r][3],
          address: {
            add1: data[r][4],
            add2: data[r][5],
            city: data[r][6],
            state: data[r][7],
            zip: data[r][8]
          },
          tel: data[r][9],
          searchterms: listToArray(data[r][10]) //Let's turn a csv list into an array
        }
    
        // For the sake of efficiency and to save $, we WON'T create documents that have already been created...
        // ...and we won't update documents that have a fireStore Timestamp that's newer than a Modified Timestamp
    
          // If there's not firestore timestamp in our spreadsheet, then let's create firestore document and update firestore stamp:
        if (!cellFSVal) {
          var now = new Date(); //Generate timestamp right now
          try {
            firestore.createDocument(collection + "/" + data[r][0], newDoc[r]); // To Use Your Own Document ID
            //Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been added to Firestore
            cellFS.setValue(now);
            Logger.log("Row ",r,"(",data[r][1],") is NEW and was added to FireStore Successfully");
          } catch (e) {
            Logger.log("Error: ",e," : Document with same name already existed in Firestore."); 
          }
        }
        //var if FS Timestamp exists but, the modified time stamp is greater, let's update the Firstore Document
        else if ((cellFSVal) && (cellModVal > cellFSVal)) {
          try {
            firestore.updateDocument(collection + "/" + data[r][0], newDoc[r]);
            //Now let's insert a timestamp in our Firestore TS column of the sheet so we know it's been updated to Firestore
            cellFS.setValue(now);
            Logger.log("Row ",r,"(",data[r][1],") updated/edited.");
          } catch (e) {
            Logger.log("Error: ",e," : Document existed, we tried updating it, but jack shit happened.");
          }
        }
        else {
          Logger.log("Row ",r,"(",data[r][1],") Already in Firestore & hasn't been modified. Skipped.");
        }
      }
    }
    

    第 5 步

    根据您的需要修改脚本后,就可以运行该脚本了。只需保存它 (File &gt; Save),然后从菜单栏中的“选择功能”下拉选择器中选择功能“writeToFireStore”(在错误图标之间)和灯泡),然后点击播放图标(在错误图标的左侧)。此时,可能会提示您接受运行脚本的权限(如果要运行脚本,您需要接受)。接受权限后,如果尚未运行“writeToFireStore”函数,请再次运行它,瞧!

    注意事项:

    我创建了一个函数,该函数自动将修改后的时间戳写入目标工作表中倒数第二列,当您运行该函数时,会写入一个 Firestore 时间戳(这样您就知道哪些行已成功导出到 Firestore)。这样,如果您再次运行 firestore 函数,并且您没有更改工作表上的数据,它就不会费心用相同的数据更新数据库(并且会为您节省金钱和/或服务器资源)。要使此功能正常工作,您必须设置项目触发器(在 cmets 的脚本中进行了说明)。

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2010-10-06
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      相关资源
      最近更新 更多