2013-01-07 32 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

相关问题