2013-01-07 69 views
2

我有一個認證程序,可以獲取使用GData API的C#實現版本3的所有電子表格的列表(它遵循文檔中的the example)。我很難弄清楚如何通過它的文檔鍵來獲取單個資源。我可以在Google Documents List API中看到很多檢索文檔列表的例子,我可以看到如何通過exact name search將文檔清零,但我試圖生成一些代碼,這些代碼在重新命名的電子表格中生存。這裏是我到目前爲止已經編寫的代碼:如何使用C#GData API通過密鑰請求單個電子表格?

using System; 
using Google.GData.Client; 
using Google.GData.Spreadsheets; 
using Microsoft.VisualBasic; 

namespace q14201622 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     //OAuth 2 Stuff 
     var parameters = new OAuth2Parameters() { 
     ClientId = CLIENT_ID, 
     ClientSecret = CLIENT_SECRET, 
     RedirectUri = REDIRECT_URI, 
     Scope = SCOPE 
     }; 
     Process.Start(OAuthUtil.CreateOAuth2AuthorizationUrl(parameters)); 
     var response = Interaction.InputBox("Enter oAuth Code:", "q14201622", "", 0, 0); 
     parameters.AccessCode = response; 
     OAuthUtil.GetAccessToken(parameters); 
     var accessToken = parameters.AccessToken; 

     //Fetch Documents 
     var requestFactory = new GOAuth2RequestFactory(null, "q14201622-v1", parameters); 
     var service = new SpreadsheetsService("q14201622-v1"); 
     var query = new SpreadsheetQuery(); 
     query.Title = "Exact Title"; 
     query.Exact = true; 

     //Iterate over the results 
     var feed = service.Query(query); 
     foreach (var entry in feed.Entries) 
     { 
     Console.WriteLine(entry.Id + ":"+ entry.Title.Text); 
     } 
    } 
    } 
} 

回答

2

我沒有測試這一點,但根據本https://developers.google.com/gdata/client-cs您可以通過使用其URL請求特定條目:

FeedQuery singleQuery = new FeedQuery(); 
singleQuery.Uri = new Uri(newEntry.SelfUri.ToString()); 
AtomFeed newFeed = service.Query(singleQuery); 
AtomEntry retrievedEntry = newFeed.Entries[0];  

現在,如果您在文檔的關鍵,你也有URL(https://docs.google.com/spreadsheet/ccc?key=[insert這裏的關鍵]) 你可以使用一個簡單的

string docKey = "nice doc key"; 
string gDocsURL = "https://docs.google.com/spreadsheet/ccc?key={0}"; 
string docURL = String.Format(gDocsURL,docKey); 

然後

FeedQuery singleQuery = new FeedQuery(); 
singleQuery.Uri = new Uri(docURL); 
AtomFeed newFeed = service.Query(singleQuery); 
AtomEntry retrievedEntry = newFeed.Entries[0]; 

而且您應該能夠檢索文檔。 如果你想保存文檔到硬盤驅動器,只需添加

string docFormat ="xlsx";// or xls or csv or pdf etc. 
string gDocsDownloadURL="https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key={0}&exportFormat={1}" 
string downloadUrl = String.format(gDocsDownloadURL,docKey,docFormat); 
Stream stream = service.Query(new Uri(downloadUrl)); 
+0

我正在測試這個,但FeedQuery並沒有返回任何東西,儘管嘗試了各種排列的docsURL(我使用的是Google Apps實例,所以我嘗試了我的瀏覽器所看到的URL以及您的URL例如) –

+0

呵呵,然後用你的例子,嘗試搜索你知道你有的文件。然後簡單地console.write(entry.SelfUri.ToString()),你得到了你自己的正確的URL。替換上面的代碼中的網址,並獲利.... :) – Mihai

+0

不幸的是,這也不起作用。調用'entry.SelfUri.ToString()'返回一個如下所示的URL:'https://spreadsheets.google.com/feeds/spreadsheets/private/full/(KEY)',其中的密鑰長度小於找到的URL密鑰在瀏覽器中。將該密鑰傳遞給'singleQuery.Uri'會返回一個空的'feed.Entries' –

2

我得罪了Google.Apis.Drive.v2客戶端庫NuGet包版本1.9.2.1890測試此。但是需要注意的是,您現在需要通過Google Developer's Console發現的here,向您的應用程序註冊開發人員的帳戶並使用Google API和設置API訪問權限和憑據。

如果你只想用這個服務帳戶又名不能代表用戶,但對於自動化或內部工具訪問文件,使用這樣的:

(如果我沒有記錯的服務帳戶仍需要由通過OAuth的瀏覽器彈出一個人一次性的OAuth認證的交互的應用程序添加到服務帳戶授權的應用程序)

private const string SERVICE_ACCOUNT_EMAIL = "YOUR_SERVICE_ACCOUNT_EMAIL_HERE"; //looks like [email protected]count.com; 

static DriveService BuildServiceAccountService() 
{ 
    var certificate = new X509Certificate2(PATH_TO_YOUR_X509_CERT, 
     "notasecret", X509KeyStorageFlags.Exportable); 
    var credential = new ServiceAccountCredential(
     new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL) 
     { 
      Scopes = new[] { DriveService.Scope.Drive }, 
      User = "ACTUAL_EMAIL_ADDRESS" // this should be the normal [email protected] account that has the google drive files 
     }.FromCertificate(certificate)); 

    // Create the service. 
    var service = new DriveService(new BaseClientService.Initializer() 
    { 
     HttpClientInitializer = credential, 
     ApplicationName = "Drive API Service Account Sample", 
    }); 

    return service; 
} 

public static void DownloadSpreadsheetAsXlsx(string spreadsheetName, string filePath) 
{ 
    var service = BuildServiceAccountService(); 
    var request = service.Files.List(); 
    request.Q = String.Format("title = '{0}'", spreadsheetName); 
    var files = request.Execute(); 
    var file = files.Items.FirstOrDefault(); 

    var dlUrl = String.Format("https://docs.google.com/spreadsheets/d/{0}/export?format=xlsx&id={0}", file.Id); 

    File.WriteAllBytes(filePath, service.HttpClient.GetByteArrayAsync(dlUrl).Result); 
} 

要訪問代表用戶的文件,你會需要像這可以建立您的服務:

static DriveService BuildUserAccountService(string userEmail) 
{ 
    UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
    new ClientSecrets 
    { 
    ClientId = "YOUR_CLIENT_ID", // your client Id 
    ClientSecret = "YOUR_CLIENT_SECRET", // Your client secret 
    }, 
    new[] { DriveService.Scope.Drive }, 
    userEmail, 
    CancellationToken.None).Result; 

    // Create the service. 
    var service = new DriveService(new BaseClientService.Initializer() 
    { 
     HttpClientInitializer = credential, 
     ApplicationName = "Drive API User Account Sample", 
    }); 

    return service; 
} 

老答案留給後人的緣故(老谷歌的GData API已被棄用,下面這點東西不再是相關的,不應該被預期工作):

我有同樣的問題找到文檔密鑰。我最終在AlternateUri中找到了它。這裏是我做了什麼(這已被編譯並確認一個新的項目工作,並添加GData.Spreadsheets用的NuGet):

//Use your authentication method here:  
SpreadsheetsService service = new SpreadsheetsService("DownloadSpreadsheet"); 
service.setUserCredentials("your username", "your password"); 

SpreadsheetQuery query = new SpreadsheetQuery(); 
SpreadsheetFeed feed = service.Query(query); 
SpreadsheetEntry fileEntry = feed.Entries.Cast<SpreadsheetEntry>().FirstOrDefault(entry => entry.Title.Text == "Name of spreadsheet"); 

//This is the good part 
string key = fileEntry.AlternateUri.Content.Substring(fileEntry.AlternateUri.Content.IndexOf("?key=")); 
string dlUrl = "https://docs.google.com/feeds/download/spreadsheets/Export" + key + "&exportFormat=xlsx&format=xlsx"; 
Stream stream = service.Query(new Uri(dlUrl)); 
using (FileStream fstream = new FileStream("something.xlsx", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) 
{ 
    stream.CopyTo(fstream); 
    fstream.Flush(); 
} 

我應該指出,這需要LINQ(.NET Framework 3.5或更高版本),由於到.Cast<SpreadsheetEntry>().FirstOrDefault()一行。這可以在沒有LINQ的情況下完成,您只需手動枚舉電子表格並找到您正在查找的電子表格,而不是使用一行代碼執行此操作。我只是想確保在他們開始報告它不起作用之前,每個人都知道。

+0

使用服務下載是一種絕佳的方式。下載工作表的另一種方式是使用WebClient或其他下載方式構建URL並下載;但這會導致Google的權限頁面要求您先登錄。 Josh的這種方法並沒有要求,因爲服務已經對用戶進行了認證。 –

+0

另外,您可以添加「&gridlines = false」,以便在導出爲PDF格式時禁止顯示網格線。默認情況下,Google會在PDF中顯示工作表中的網格線。 –

+0

我面臨同樣的問題,但由於某種原因,您的代碼不適合我。它會拋出異常,說'執行導致重定向從..' – Tweety01

相關問題