原口 豊(はらぐち・ゆたか)
大手証券会社システム部に在籍後、1998年ベイテックシステムズ(現サテライトオフィス)を設立し、社長就任。2008年に、いち早くクラウドコンピューティングの可能性に注目し、GoogleApps(TM)導入サポートを開始。導入実績は、ガリバー、アデランス、三井倉庫などの大手企業から、中堅・中小企業まで、1,200社以上。「組織&グループカレンダー for Google Apps」など、多数のテンプレートを無償提供するなど、Google Appsの普及に尽力。Google Enterprise Day 2011ではパートナーアワードを3年連続で受賞した。

まずは書き込み対象となるスプレッドシートを用意

今回はGoogle App Engineを使って、Googleドキュメントのスプレッドシートへ書き込みを行う方法について紹介しよう。

まずは前回のメール送信と同様に、スプレッドシートへ書き込みを行うためのWebアプリケーションを登録しておく。

次に用意するのは、書き込み対象となるスプレッドシートだ。どのスプレッドシートに書き込むかは、URLから取り出した「スプレッドシートキー」で指定するので、ファイル名は自由に付けて構わないが、1行目にあらかじめ書き込むデータの項目を記載しておく。ここでは、サンプルとして、A1から順番に「取引先」「受注製品」「数量」「納期」「先方担当者」と入力した。

書き込み対象となるスプレッドシートは、1行目に書き込むデータの項目を記載しておく。ここではA1から順番に「取引先」「受注製品」「数量」「納期」「先方担当者」と入力した

Python用ライブラリなど必要なファイルを準備

ファイルとしては、前回と同じく「__init__.py」「app.yaml」「index.py」という3つのファイルと、「images」フォルダ内に収めたアイコン画像「favicon.ico」を用意する「__init__.py」と「app.yaml」はメール送信で使ったものと同じ。そして「index.py」に、スプレッドシートへ書き込むためのスクリプトを記述していく。

また、Google App Engine経由でスプレッドシートへ書き込むには、Python用のライブラリ「gdata-python-client」を入手する必要がある。これは、GoogleカレンダーやGoogleドキュメントなどGoogleが提供する各種サービス機能へ、簡単にPythonからアクセスできるようにするためのものだ。

gdata-python-clientは配布ページからダウンロードできる。zipファイルを解凍すると大量のファイルが表示されるが、今回使用するのはその中の一部。「src」フォルダ内にある「atom」および「gdata」という2つのフォルダを、「app.yaml」や「index.py」と同じ場所へコピーしておけば良い。

Python用のライブラリ「gdata-python-client」から抜き出した「atom」および「gdata」も、「app.yaml」や「index.py」と同じ場所へコピーしておく

それでは、各ファイルの詳細について見ていこう。

「__init__.py」

前回のメール送信と同様に、中身は空のままで問題ない。

「app.yaml」

こちらの内容も前回の記事と同様だ。1行目の「application:」にアプリケーションIDを入力する。

application: アプリケーションIDを入力
version: 1
runtime: python
api_version: 1
default_expiration: "4d 5h"


handlers:

- url: /favicon.ico
  static_files: images/favicon.ico
  upload: images/favicon.ico

- url: /.*
 script: index.py

「index.py」

これがスプレッドシートへの書き込みでメインとなるスクリプトだ。プログラミング講座ではないため、前回と同様に各コマンドの詳細は省略するが、これをベースにカスタマイズしたい人は書籍やWebサイトなどで調べてみていただきたい。

この中で個々の環境に応じて変更が必要なのは、スプレッドシートキーおよび、スプレッドシートを編集可能なユーザーアカウントのメールアドレスとパスワードだ。スプレッドシートのシート名を変えている場合はシート名部分も変更するが、デフォルトであれば「シート1」のままで構わない。

スプレッドシートキーは、スプレッドシートのURLに含まれている「key=」に続く文字だ。たとえばURLが「https://docs.google.com/a/domain.com/spreadsheet/ccc?key=0Abcdefg0123abcdefg0123abcdefg0123abcdefgabc&hl=ja#gid=2」の場合、「0Abcdefg0123abcdefg0123abcdefg0123abcdefgabc」がスプレッドシートキーに相当する。

書き込み内容のリストには、左から順番にスプレッドシートへ書き込まれていく。ここでは「山田商事」「パーツA」「50個」「30日後」「田中」という文字を入力してみる。

スプレッドシートキーは、スプレッドシートのURLに含まれている「key=」に続く文字だ。「key=」から「#」までの間をコピー&ペーストしよう

# coding: utf-8
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

import gdata.spreadsheet.service
import gdata.service
import gdata.alt.appengine
import atom.service
import gdata.spreadsheet
################################################

スプレッドシートのサンプルについて

・書き込みを行うスプレッドシートの1行目に項目を入力しておく必要がある

################################################
class Page(webapp.RequestHandler):
    def get(self):
        try:
        # スプレッドシートキーを設定
        spreadsheet_key = 'ここにスプレッドシートキーを入力'

        # スプレッドシートを編集可能なユーザーアカウントを設定
        email = 'ここにメールアドレスを入力'
        # ユーザーアカウントのパスワードを設定
        password = 'ここにパスワードを入力'

        # 書き込み先のシート名を設定
        # ''の前に u を付けることでユニコードに変換
        # 変換を行わない場合、エラーが発生する
        spreadsheet_name = u'シート1'

        # 書き込み内容のリストを設定
        # ''の前に u を付けてユニコードに変換
        # 変換を行わない場合、エラーが発生する
        values = [u'山田商事' ,u'パーツA' ,u'50個' ,u'30日後' ,u'田中']


        # SpreadsheetsServiceを取得
        service = gdata.spreadsheet.service.SpreadsheetsService()
        gdata.alt.appengine.run_on_appengine(service, store_tokens=True,single_user_mode=True)

        # 編集に使用するユーザーアカウントの情報を設定
        service.email = email
        service.password = password
        # 設定したユーザーアカウントでログインを実行
        service.ProgrammaticLogin()

        # スプレッドシートIDを取得
        spreadsheet_id = self.getSpreadsheetIdByName(service, spreadsheet_key, spreadsheet_name)

        # ワークシートIDが取得出来なかった場合、メッセージを表示して処理を終了
        if spreadsheet_id == '':
            self.response.out.write('Spreadsheet not found.')
            return

        # ワークシートIDが取得できた場合、書き込み処理の実行
        self.addSpreadsheetRecord(service, spreadsheet_key, spreadsheet_id, values)

        self.response.out.write('success.')
        return
    except BaseException, e:
        self.response.out.write('error<br/>')
        self.response.out.write(e)
        return


def getSpreadsheetIdByName(self, service, spreadsheet_key, Spreadsheet_name):
    u'''スプレッドシートIDを取得'''

    # keyを使ってスプレッドシートを取得
    feed = service.GetWorksheetsFeed(spreadsheet_key)
    spreadsheet_entry = None
    spreadsheet_id = ''

    if not feed:
        # 取得出来なかった場合、空欄を返却
        return ''

    # スプレッドシートが取得できた場合、書き込み先のシートを取得
    for entry in feed.entry:
        # 取得したいシート名と一致した場合、そのシートを取得
        if(entry.title.text == Spreadsheet_name):
            spreadsheet_entry = entry
            break
    # 取得したシートからスプレッドシートIDを取得
    if spreadsheet_entry:
        id_parts = spreadsheet_entry.id.text.split('/')
        spreadsheet_id = id_parts[-1]
    else:
        # 取得出来なかった場合、空欄を返却
        return ''
    # 取得したスプレッドシートIDを返却
    return spreadsheet_id


def addSpreadsheetRecord(self, service, spreadsheet_key, spreadsheet_id, values):
    u'''スプレッドシートへ書き込み処理を実行'''
    try:
        data={}
        # スプレッドシートのタイトル一覧(一列目の項目)を取得
        titles = self.getSpreadsheetTitleList(service, spreadsheet_key, spreadsheet_id)

        # 書き込み内容と、タイトル一覧を対応付ける
        for i,value in enumerate(values):
            if i < len(titles):
                key = titles[i]
                data[key] = value
            else:
                break
        # スプレッドシートキー、スプレッドシートIDを使ってスプレッドシートへの書き込みを実行
        return service.InsertRow(data, spreadsheet_key, spreadsheet_id)

    except Exception, e:
        raise e



def getSpreadsheetTitleList(self, service, spreadsheet_key, spreadsheet_id):
    u'''スプレッドシートのタイトル一覧を取得'''
    first_row_contents = []
    #スプレッドシートの一行目(タイトル)を取得
    query = gdata.spreadsheet.service.CellQuery()
    query.max_row = '1'
    query.min_row = '1'
    feed = service.GetCellsFeed(spreadsheet_key, spreadsheet_id, query=query)

    # 取得できた場合、タイトルのリストを作成
    for entry in feed.entry:
        first_row_contents.append(entry.content.text)

    # タイトル一覧を格納したリストを返却
    return first_row_contents

def main():
    run_wsgi_app(webapp.WSGIApplication([(r'.*', Page)]))
if __name__ == "__main__":
    main()

「atom」フォルダ内の「__init__.py」

今回は文字コードをUnicode指定で書き込むため、72行目・73行目を下記のように変更する。

  • 変更前

    MEMBER_STRING_ENCODING = 'utf-8'

    MEMBER_STRING_ENCODING = unicode

  • 変更後

    MEMBER_STRING_ENCODING = 'utf-8'

    MEMBER_STRING_ENCODING = unicode

各ファイルの準備が整ったら、これまでと同じくGoogle App Engine Launcherの「Create New Application」でアプリケーションの追加とフォルダ指定を実行。あとはローカル環境での実行もしくはデプロイ後にブラウザでアクセスする

ブラウザ上に「success.」の文字が表示されたら成功だ

スプレッドシートを確認すると、「index.py」内の書き込み内容リストに入力した文字が書き込まれている

各ファイルの準備が整ったら、これまでと同じくGoogle App Engine Launcherの「Create New Application」でアプリケーションの追加とフォルダ指定を実行。あとはローカル環境での実行もしくはデプロイ後にブラウザでアクセスし、「success.」の文字が表示されたらスプレッドシートを確認しよう。

今回はGoogle App Engine経由でスプレッドシートへ書き込む方法をご紹介した。スプレッドシートはビジネスで頻繁に使われるだけでなく、書き込み機能だけを見てもアンケートの自動集計などWebアプリケーションの一部に盛り込まれるケースは多い。こうした機能を組み合わせることで、さまざまなWebアプリケーションが作られるわけだ。