Google Spreadsheetで特定のシートに直リンクする

こんにちは

昨日からGoogle Spreadsheet APIで作成したシートに直リンクするURLを生成したくて色々調べてました。

「API使うならそれくらい簡単にできるんじゃないの?」って思うでしょ?えぇ、僕もそう思いました。

しかし、これが。。。(--

一応最終的にはできたんですが、その方法が「マジですか?!」とかなり愕然とするものだったのでここにメモとして残しておきます。

 

★Google SpreadsheetのURL

実際にシートを作ってみながらブラウザのアドレスバーを確認するとすぐにわかりますが、GoogleSpreadsheetのURLは以下のような形式となっています。

 

https://docs.google.com/spreadsheet/ccc?key=xxxxxxxx#gid=1

 

アカウントが組織に属している場合は若干URLのパスが変わりますが、ここで重要なのは

  • URLパラメータの「key」がスプレッドシートを特定するキーとなっている
  • URLパラメータの「gid」がワークシートを特定するキーとなっている

という点です。ちなみにgidはおそらく単純にシートの作成順による連番です。途中でワークシートの削除や移動があった場合でもgidが振り直されることはなく単純なインクリメントで生成されます。

要するにAPIでこのkeyとgidが取得できれば、URLを組み立てることができるわけです。楽勝です。

 

★Google Spreadsheet APIを使う

今回アプリはPlay2で作成しているのでJavaのAPIを使用しました。Google Spreadsheet APIの使い方については良記事がたくさんあるので割愛しますが、スプレッドシート、ワークシートの情報はそれぞれ、

  • SpreadsheetEntry
  • WorksheetEntry

というクラスから取得できます。

これらのAPIリファレンスを眺めると目的とする情報はそれぞれ

  • SpreadsheetEntry#getSpreadsheetLink
  • WorksheetEntry#getId

というメソッドから取得できそうです。楽勝です。

 

★gidが取れないことに気がつく

さて、ここまで来たら後は試すだけですがまず、SpreadsheetEntry#getSpreadsheetLinkは完全に目的にマッチするものでした。keyだけでなくスキームから始まる完全なURLとして取得できます。楽勝楽勝(^^v

が、WorksheetEntry#getIdの方はgidではなく、こちらも「https://...」で始まるURIでした。そもそもgetIdメソッドはWorksheetEntryクラスのメソッドではなく、その基底クラスであるBaseEntryクラスのメソッドなのでSpreadsheetだけでなく他のGoogle Appsオブジェクトまで全部含めたIdentifierになっているわけです。同一のスプレッドシート内でのみユニークとなるgidとは意味合いが異なります。

それではgidはどうやって取得するのかと言うと。。。これはいろいろと試行錯誤したんですが、どうもそのためのメソッドは無いようでした。(--

最終的にはRESTのレスポンスXMLの中にそれっぽい値が入っていないことから、どうやら本当に無いらしいと結論しました。

 

★シート名でのリンクを試みる

APIでgidが取れないとなると、どうやって直リンクすれば良いのでしょうか?シートの削除や移動があるのでgidは単純な連番とはなりません。世の中にGoogleSpreadsheetの特定シートに直リンクしたい人は山ほどいるはずです。

。。。と、あおってはみたものの実際のところはここまでにさんざん検索をかけているのでシート名でリンクする( = URLパラメータに「sheet=xxxxx」を指定する)方法があるらしいことはわかってはいたんです。

が、これ途中でも試してたんですが何故かうまく動きません。検索結果にも「動かねー」という怨嗟の声が山ほどあるし、公式ドキュメントにもそれができるという記述が見つけられないので結局この方向もあきらめました。。。(--

 

★できないはずがないとあがく

手詰まりです。

絶対に必要と言う機能でもないし、もうあきらめようかとも思ったんですがこんな簡単なことができないということがどうしても信じられず検索を続けました。

そして。。。ついに、見つけた解答がこれです。

http://stackoverflow.com/questions/11290337/how-to-convert-google-spreadsheets-worksheet-string-id-to-integer-index-gid

一番最後にコード例が載っていますが、要約するとこうです。

 

  1. WorksheetEntry#getIdから最後の「/」以降の3桁を取得する
  2. その文字列を36進数として数値に変換する
  3. その数値と31578のXORを取るとgidが取得できる

 

。。。(--

。。。。。(--;;;

。。。できた。。。できたけどっ!

36進数って何だよ?!31578は一体どこから出てきた???

長くこの業界にいるけど、こんなの初めて見たよ!!!

動きはしたけどなんだか全然釈然としない。誰かこのアルゴリズムの根拠の分かる人がいたら教えてください。m(_ _)m

コメント(5)