Google Code Prettify

2017年3月6日 星期一

[C# + Google SpreadSheet] (三)、更新寫入Google SpreadSheet內容

寫入資料分為兩種,一種是 新增資料,另一種則為 更新 資料

今天要介紹的是 更新 資料,也就是直接在原有的資料中『新增資料』或是在『已有的資料的表格中更新內容』。




Farmer本是打算全部做完紀錄起來,但發現出現一個很頭痛的問題,等等會一一說明

前置作業參考:
[C# + Google SpreadSheet] (一)、建立Google OAuth 2.0
[C# + Google SpreadSheet] (二)、讀取Google SpreadSheet內容

更新 - 範例程式(紅字為修改地方)

private void update()
{
            string[] Scopes = { SheetsService.Scope.Spreadsheets };
            string ApplicationName = "Get Google SheetData with Google Sheets API";

            UserCredential credential;

   //輸出檔名稱Ex."client_secret.json"
            using (var stream =
                new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
            {
                string credPath = System.Environment.GetFolderPath(
                    System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json");

                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;
                Console.WriteLine("Credential file saved to: " + credPath);
            }

            var service = new SheetsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });
   //spreadsheetId,為google spreadsheet的網址 : / d / XXXXX /
            String spreadsheetId = "XXXXX";
   // update the F5 cell
            String range = "頁籤名稱!A5";

            //ValueRange response = request.Execute();
            ValueRange valueRange = new ValueRange();
   //Rows or Columns
            valueRange.MajorDimension = "COLUMNS";
         
            //update的內容
            var oblist = new List<object>() { "1234567890" };
            valueRange.Values = new List<IList<object>> { oblist };

            SpreadsheetsResource.ValuesResource.UpdateRequest update =
                service.Spreadsheets.Values.Update(valueRange, spreadsheetId, range);
            update.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.RAW;
            UpdateValuesResponse result2 = update.Execute();
}

更新最後一排

參考資料 :
Google Sheets API v4 使用 C# (2) --- 更新寫入 Google Spreadsheet

private void UpdateRow()
        {
             string[] Scopes = { SheetsService.Scope.Spreadsheets, SheetsService.Scope.Drive };
            //應用程式的名字需要英文
             string ApplicationName = "Get Google SheetData with Google Sheets API";
            //輸出檔名稱Ex."client_secret.json"
             string JsonName = "client_secret.json";
            //spreadsheetId,為google spreadsheet的網址 : / d / XXXXX /
            //Ex: https://docs.google.com/spreadsheets/d/1kLk9VslDYn0nhZpJZXd3tErt1f2gzG-2eSJWbrh2piU/edit#gid=0
             string spreadsheetId = "1kLk9VslDYn0nhZpJZXd3tErt1f2gzG-2eSJWbrh2piU";
            //頁籤名稱
             string sheetName = "test";
            //選取範圍
             string range = sheetName + "!A1:F37";

            UserCredential credential;
            using (var stream = new FileStream(JsonName, FileMode.Open, FileAccess.Read))
            {
                string credPath = Path.Combine
                    (System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal),
                     ".credentials/sheets.googleapis.com-dotnet-quickstart.json");

                //存儲憑證到credPath
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    Scopes,
                    "user",
                    CancellationToken.None,
                    new FileDataStore(credPath, true)).Result;
                Console.WriteLine("Credential file saved to: " + credPath);
            }

            //建立一個API服務,設定請求參數
            var service = new SheetsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            });

            ValueRange rVR;
            String Range;
            int rowNumber = 0;

            //設定讀取A欄最後一行位置
            Range = String.Format("{0}!A:A", sheetName);
            SpreadsheetsResource.ValuesResource.GetRequest getRequest
                = service.Spreadsheets.Values.Get(spreadsheetId, Range);
            //到Google sheet讀取內容
            rVR = getRequest.Execute();
            //最後一行位置
            IList<IList<Object>> values = rVR.Values;

            //寫入新資料
            if (values != null && values.Count > 0) rowNumber = values.Count + 1; //添加一行
            Range = String.Format("{0}!A{1}:B{1}", sheetName, rowNumber);  //指定寫入位置

            //設定寫入
            ValueRange valueRange = new ValueRange();
            valueRange.Range = Range;
            //ROWS或COLUMNS
            valueRange.MajorDimension = "ROWS";

            //取得當前時間
            DateTime dt = new DateTime();
            dt = DateTime.Now;
            List<object> oblist = new List<object>() { String.Format("{0}", rowNumber), dt.ToString("HH:mm:ss") };

            //寫入
            valueRange.Values = new List<IList<object>> { oblist };
            Console.WriteLine("{0}, {1}", oblist[0], oblist[1]);

            //執行寫入動作
            SpreadsheetsResource.ValuesResource.UpdateRequest updateRequest
                = service.Spreadsheets.Values.Update(valueRange, spreadsheetId, Range);
            updateRequest.ValueInputOption
                = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED;
            UpdateValuesResponse uUVR = updateRequest.Execute();
        }

注意事項

Farmer出現一個問題,最後 updateRequest.Execute(); 這邊會出錯

原因:
類型 'Google.GoogleApiException' 的未處理例外狀況發生於 Google.Apis.dll
其他資訊: Google.Apis.Requests.RequestError
Request had insufficient authentication scopes. [403]
Errors [
Message[Request had insufficient authentication scopes.] Location[ - ] Reason[forbidden] Domain[global]

]


後來去找Google大嬸幫助下,才發現幾個問題


參考資料:
Request had insufficient authentication scopes. [403] c#
Google spreadsheet api Request had insufficient authentication scopes

  1. 在一開始 string[] Scopes = { SheetsService.Scope.Spreadsheets };
    若為 
    SheetsService.Scope.SpreadsheetsReadonly,則會不能寫入
  2. 這是我發生的問題,好不容易找到原因,就是因為在一開始授權的部分,導致驗證有問題,所以將授權的檔案刪除再重新授權一次即可。
    授權的資料在"電腦"內,Farmer是在 文件->.credentials 裡的資料夾刪除即可

    建議 直接使用尋找功能,找 『.credentials』 or 『sheets.googleapis.com』再將sheets.googleapis.com-XXX.json資料夾刪除即可

3 則留言:

  1. 感謝!! 重點2個!
    static string[] Scopes = { SheetsService.Scope.Spreadsheets };

    還有debug 資料夾內全刪,重新授權!

    回覆刪除