2015-07-20 21 views
7

Ich habe versucht, mit Java zu programmieren, um eine Verbindung zu Google Spreadsheet herzustellen, um Daten abzurufen oder Daten in den Zellen zu ändern.Java zu Google Spreadsheet

Mein Google-Tabelle Link ist https://docs.google.com/spreadsheets/d/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA

ich am Sheets API sah und es erfordert Link wie

https://spreadsheets.google.com/feeds/worksheets/key/private/full

Ich habe verschiedene Formen der Verbindungen versucht, wie zum Beispiel:

  1. https://spreadsheets.google.com/feeds/worksheets/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA/private/full

  2. https://spreadsheets.google.com/feeds/worksheets/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA/private/full

Sie gaben mir verschiedene Arten von Fehlern jeweils:

  1. com.google.gdata.util.ParseException: Unrecognized content type:application/binary
  2. com.google.gdata.util.RedirectRequiredException: Moved Temporarily

Ich habe keine Ahnung, wie man das Googl Kalkulationstabelle mit Hilfe von Java verbinden . Bitte helfen Sie mir, wenn Sie Erfahrung dazu haben.

import com.google.gdata.client.authn.oauth.*; 
import com.google.gdata.client.spreadsheet.*; 
import com.google.gdata.data.*; 
import com.google.gdata.data.batch.*; 
import com.google.gdata.data.spreadsheet.*; 
import com.google.gdata.util.*; 
import org.testng.annotations.Test; 

import java.io.IOException; 
import java.net.*; 
import java.util.*; 

public class TestGoogleSheetsAPI { 

    @Test 
    public void testConnectToSpreadSheet() throws ServiceException, IOException { 
     SpreadsheetService service = new SpreadsheetService("google-spreadsheet"); 

     URL SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/worksheets/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA/public/full"); 
     SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class); 
     List<SpreadsheetEntry> spreadsheets = feed.getEntries(); 

     if (spreadsheets.size() == 0) { 
      // TODO: There were no spreadsheets, act accordingly. 
     } 

     SpreadsheetEntry spreadsheet = spreadsheets.get(0); 
     System.out.println(spreadsheet.getTitle().getPlainText()); 
    } 
} 

Ich habe nicht service.setUserCredentials("[email protected]", "password") verwenden, weil ich einen anderen Fehler haben, die com.google.gdata.util.AuthenticationException: Error authenticating (check service name)

+0

Haben Sie die Java-Clientbibliothek eingerichtet? Oder verwenden Sie Raw-REST-HTTPS-Anforderungen? –

+0

Ich habe Maven verwendet, um die gdata-Bibliothek zu importieren. Soll ich stattdessen die JAR-Datei herunterladen? –

+0

Ich weiß es nicht. Ich wollte nur sicherstellen, dass du die Grundlagen gemacht hast. Bitte zeigen Sie den Java-Code an, der die Anfrage stellt. –

Antwort

0

ist der Feed, den Sie von dieser URL erhalten, ist eine WorksheetFeed, kein SpreadsheetFeed. Try this:

SpreadsheetService service = new SpreadsheetService("google-spreadsheet"); 

    FeedURLFactory urlFactory = FeedURLFactory.getDefault(); 
    WorksheetFeed worksheetFeed = service.getFeed(urlFactory.getWorksheetFeedUrl("1V4jT4vSqmY4YNY1VJhariLRLbxfFWf5z8bSTpDcSBPE", "public", "full"), WorksheetFeed.class); 
    List<WorksheetEntry> worksheets = worksheetFeed.getEntries(); 
    WorksheetEntry worksheet = worksheets.get(0); 
    System.out.println(worksheet.getTitle().getPlainText()); 
3

Sie erhalten die Umleitung, weil Ihre Tabelle zugreifen müssen Sie zunächst authentifizieren. Google Tabellen verwendet die alte gdata-API, erfordert jedoch, dass Sie sich mit OAuth 2.0 authentifizieren. Daher müssen Sie sowohl die gdata und Google API-Bibliotheken importieren, wie unten dargestellt:

<dependencies> 
    <dependency> 
     <groupId>com.google.gdata</groupId> 
     <artifactId>core</artifactId> 
     <version>1.47.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.google.api-client</groupId> 
     <artifactId>google-api-client-java6</artifactId> 
     <version>1.20.0</version> 
    </dependency> 
</dependencies> 

Der folgende Code zeigt, wie Sie mit Google mit OAuth authentifizieren kann. Sie müssen follow the instructions for creating a service account and downloading the P12 key first. Nach dem Erstellen Ihres Dienstkontos kopieren Sie die E-Mail-Adresse in das Feld CLIENT_ID unten, fügen Sie Ihre P12-Datei zu Ihrem Klassenpfad und chante P12FILE, um auf Ihre P12-Datei verweisen.

Ich konnte dies mit der folgenden SPREADSHEET_FEED_URL "https://spreadsheets.google.com/feeds/worksheets/:worksheetId/private/basic" arbeiten, wobei ": worksheetId" Ihre Arbeitsblatt-ID ist. Das ist etwas anders als das, das du benutzt hast.

Stellen Sie sicher, dass Ihr Dienstkonto berechtigt ist, die Tabelle zu lesen oder in die Tabelle zu schreiben, indem Sie sie zuerst mit der E-Mail-Adresse des Dienstkontos teilen.

public class GoogleSheetsApiTest { 

// Generate a service account and P12 key: 
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount 
private final String CLIENT_ID = "<your service account email address>"; 
// Add requested scopes. 
private final List<String> SCOPES = Arrays 
     .asList("https://spreadsheets.google.com/feeds"); 
// The name of the p12 file you created when obtaining the service account 
private final String P12FILE = "/<your p12 file name>.p12"; 


@Test 
public void testConnectToSpreadSheet() throws GeneralSecurityException, 
     IOException, ServiceException, URISyntaxException { 

    SpreadsheetService service = new SpreadsheetService(
      "google-spreadsheet"); 
    GoogleCredential credential = getCredentials(); 
    service.setOAuth2Credentials(credential); 

    URL SPREADSHEET_FEED_URL = new URL(
      "https://spreadsheets.google.com/feeds/worksheets/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA/private/basic"); 
    SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, 
      SpreadsheetFeed.class); 
    List<SpreadsheetEntry> spreadsheets = feed.getEntries(); 

    if (spreadsheets.size() == 0) { 
     // // TODO: There were no spreadsheets, act accordingly. 
    } 
    // 
    SpreadsheetEntry spreadsheet = spreadsheets.get(0); 
    System.out.println(spreadsheet.getTitle().getPlainText()); 

} 

private GoogleCredential getCredentials() throws GeneralSecurityException, 
     IOException, URISyntaxException { 
    JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); 
    HttpTransport httpTransport = GoogleNetHttpTransport 
      .newTrustedTransport(); 

    URL fileUrl = this.getClass().getResource(P12FILE); 
    GoogleCredential credential = new GoogleCredential.Builder() 
      .setTransport(httpTransport) 
      .setJsonFactory(JSON_FACTORY) 
      .setServiceAccountId(CLIENT_ID) 
      .setServiceAccountPrivateKeyFromP12File(
        new File(fileUrl.toURI())) 
      .setServiceAccountScopes(SCOPES).build(); 

    return credential; 
} 

} 
+0

Hallo Brian, vielen Dank. Ich habe die Google-Entwicklerkonsole durchlaufen und ein Dienstkonto erstellt. CLIENT_ID sollte die längere in der Entwicklerkonsole oder meine echte E-Mail sein? –

+0

Mein Code funktioniert jetzt gut, hinzugefügt 'credential.refreshToken();' nach '.setServiceAccountScopes (SCOPES) .build();'. Ich schätze deine Hilfe, Brian! –

+0

@TimLai Akzeptieren Sie die Antwort, wenn sie funktioniert. Andere mit dem gleichen Problem werden wissen, auf welche Antwort sie achten müssen. – Teja

0

Ich fühle mich wie dies ein Fehler ist. Als Workaround können Sie unten die Getfeed-Anfrage aufrufen und dann beginnen Ihre Feed-Anfragen zu arbeiten.unten ist ein modifizierter Code zum besseren Verständnis

import com.google.gdata.client.authn.oauth.*; 
import com.google.gdata.client.spreadsheet.*; 

import com.google.gdata.data.*; 
import com.google.gdata.data.batch.*; 
import com.google.gdata.data.spreadsheet.*; 
import com.google.gdata.util.*; 
import org.testng.annotations.Test; 

import java.io.IOException; 
import java.net.*; 
import java.util.*; 

public class TestGoogleSheetsAPI { 

    @Test 
    public void testConnectToSpreadSheet() throws ServiceException, IOException { 
     SpreadsheetService service = new SpreadsheetService("google-spreadsheet"); 

     URL SPREADSHEET_FEED_URL = new URL("https://spreadsheets.google.com/feeds/worksheets/1UXoGD2gowxZ2TY3gooI9y7rwWTPBOA0dnkeNYwUqQRA/public/full"); 
     //added new line ******************************* 
     service.getFeed(new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full?xoauth_requestor_id=test"),WorksheetFeed.class); 
     //************************ 
     SpreadsheetFeed feed = service.getFeed(SPREADSHEET_FEED_URL, SpreadsheetFeed.class); 
     List<SpreadsheetEntry> spreadsheets = feed.getEntries(); 

     if (spreadsheets.size() == 0) { 
      // TODO: There were no spreadsheets, act accordingly. 
     } 

     SpreadsheetEntry spreadsheet = spreadsheets.get(0); 
     System.out.println(spreadsheet.getTitle().getPlainText()); 
    } 
} 

Habe auch ein Debugging gemacht. Scheint, wenn wir versuchen, das Arbeitsblatt mit dem Schlüssel aufzurufen, dann scheint die Antwort den Inhaltstyp "application/binary" zu haben, der in der gdata library regeciert wird, aber wenn wir versuchen, alle Feeds zuerst zu bekommen, dann hat die Antwort den richtigen Inhaltstyp und diesen Typ wird in nächsten Anfragen verwendet. so fängt der Fluss an zu arbeiten

1

Ich bekam auch den com.google.gdata.util.ParseException: Unrecognized content type:application/binary Fehler, aber ich scheine auf einen Workaround für diesen merkwürdigen Fehler gestolpert zu haben. Der Code in Alex R's answer kann als Ausgangspunkt verwendet werden.

  1. Zuerst habe ich versucht, um die Sichtbarkeit zu "public" ändern, nur um zu sehen, was passieren würde. Da das Dokument nicht veröffentlicht ist, habe ich die erwartete Fehlerantwort erhalten, die Folgendes enthält:

    Es tut uns leid. Dieses Dokument wurde nicht veröffentlicht.

  2. Also änderte ich die Sichtbarkeit zurück zu "private", und versuchte es erneut nur zum Spaß ...

    Lo, und siehe; es funktionierte!

Es arbeitet entweder mit dem Antrieb oder Tabellen-Feed Umfang (beide eingeschlossen werden können, wenn Sie bevorzugen):

Ich bin nicht sicher, wenn es ein Faktor ist, aber ich verwende nicht OAuth 2.0, sondern eine Credential erstellt von einer PrivateKey (PKCS12-Datei), wie in Brian Chapman's answer.

Fazit

Also, auch wenn es kludgy ist, habe ich meine Bewerbung an modifizierte immer einen "public" Antrag stellen (eingewickelt in einem try Block die resultierenden Exception zu absorbieren), bevor sie die "private" Anfrage nur. Nur so konnte ich das korrekte Ergebnis deterministisch erhalten.

0

1 Grund für den Erhalt com.google.gdata.util.RedirectRequiredException: Vorübergehend verschoben ist, wenn wir vergessen, das Dokument/die Tabelle zu veröffentlichen. Stellen Sie sicher, dass Sie Ihr Dokument nach dem Erstellen veröffentlicht haben, indem Sie Menü> Datei> Veröffentlicht in das Web aufrufen. Dies ist nur einmal und nicht nach jeder Bearbeitung erforderlich.

Verwandte Themen