GASでExcelファイルをSpreadsheetに変換する (再)

この記事はGoogle Apps Script Advent Calendar 2013の5日目の穴埋め記事です。
穴埋めなので、後日書いてます。

# 忙しい人のために、オチ

前に書いた、[ExcelからSpreadsheetに変換するスクリプトの記事](http://qiita.com/soundTricker/items/ea4cacde5dce6fac4e0e)があまりにも不真面目過ぎたので
ちゃんと書きたいと思います。

今回の記事を読むと、
Gmailに添付されたExcelをSpreadsheetに変換したり、
Sites内にあるExcelをSpreadsheetに変換できる用になります。

使うコードは以下で、https://code.google.com/apis/console/ でAPI KEYを取得して、Google Drive APIを有効にしてください

```javascript:excel2Spreadsheet.js
var KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //developer key , https://code.google.com/apis/console/ で取得します。 

/**
 * ExcelファイルからSpreadsheetへの変換
 * @param {Blob} excelFile Excelファイル
 * @param {String} filename Driveへアップロードする際のファイル名
 * @return {SpreadsheetApp.Spreadsheet} Spreadsheetインスタンス
 **/
function convert2Spreadsheet(excelFile, filename) {
  var oauthConfig = UrlFetchApp.addOAuthService('drive');
  
  //OAuthの設定
  var scope = 'https://www.googleapis.com/auth/drive';
  oauthConfig.setConsumerKey('anonymous');
  oauthConfig.setConsumerSecret('anonymous');
  oauthConfig.setRequestTokenUrl('https://www.google.com/accounts/OAuthGetRequestToken?scope='+scope);
  oauthConfig.setAuthorizationUrl('https://accounts.google.com/OAuthAuthorizeToken');    
  oauthConfig.setAccessTokenUrl('https://www.google.com/accounts/OAuthGetAccessToken');  
  
  var uploadParams = {
    method:'post',
    oAuthServiceName: 'drive',
    oAuthUseToken: 'always',
    contentType: 'application/vnd.ms-excel',
    contentLength: excelFile.getBytes().length,
    payload: excelFile.getBytes()
  };
  
  //Google Driveのルートフォルダへ対象ファイルを変換しつつアップロード
  var uploadResponse = UrlFetchApp.fetch('https://www.googleapis.com/upload/drive/v2/files/?uploadType=media&convert=true&key='+KEY, uploadParams);
    
  //JSONで帰ってくる 細かい話は→ https://developers.google.com/drive/v2/reference/files#resource
  var fileDataResponse = JSON.parse(uploadResponse.getContentText());

  //ファイル名を更新
  var updateParams = {
    method:'put',
    oAuthServiceName: 'drive',
    oAuthUseToken: 'always',
    contentType: 'application/json',
    payload: JSON.stringify({ title: filename })
  };
  
  //更新
  UrlFetchApp.fetch('https://www.googleapis.com/drive/v2/files/'+fileDataResponse.id+'?key='+KEY, updateParams);
  
  //Spreadsheetインスタンス取得して返却
  return SpreadsheetApp.openById(fileDataResponse.id);
}


```


# ExcelとSpreadsheet

未だにExcelはなくなりませんね。
業務にがっちり組み込まれたり、
Appsを導入している企業でもExcelの添付ファイルがバンバン飛んでいることはよく有ります。

Spreadsheetに置き換えたいという要望もあるのですが、なかなか100%の再現は不可能なため、
移行が進まなかったりします。

```text:コラム
ExcelでやっていたことをSpreadsheetで100%再現しようとすること自体が、失敗だと思っている派です。
思想や、目指しているところが違う気がするので、Excelで積み上げてきたものはあくまで参考に、
Spreadsheetに置き換えるべきだと思っていたりするのです。
```

でも、Excelの中に入っているデータ自体は利用したりしたかったりします。
例えば、グラフ化してSitesに乗っけたかったりとか、集計したかったりとか。

そこで必要になってくるのがExcelファイルからSpreadsheetへの変換です。

# 標準のGAS APIでは...

GASで用意されている標準APIではExcelからSpreadsheetへは変換___できません___。
年間___20___回ぐらい聞かれるので、もう一回書きます。
標準APIではExcelからSpreadsheetへは変換___できません___。

# じゃあどうする?

そこで登場するのが、Google Drive APIです。
Google Drive APIはGoogle DriveをもにょもにょするためのAPIですが、
各種Officeファイルから、Googleファイルへの変換処理も実施できます。

# 実践

## コード

まず以下のコードをコピーします。
コピペがめんどくさい方は、以下のライブラリキーを使ってください。

ライブラリキー: `M6pEfy4aabsPj55EUIGX21-Mffa6w-w2J`

```javascript:excel2Spreadsheet.js
var KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; //developer key , https://code.google.com/apis/console/ で取得します。 

/**
 * ExcelファイルからSpreadsheetへの変換
 * @param {Blob} excelFile Excelファイル
 * @param {String} filename Driveへアップロードする際のファイル名
 * @return {SpreadsheetApp.Spreadsheet} Spreadsheetインスタンス
 **/
function convert2Spreadsheet(excelFile, filename) {
  var oauthConfig = UrlFetchApp.addOAuthService('drive');
  
  //OAuthの設定
  var scope = 'https://www.googleapis.com/auth/drive';
  oauthConfig.setConsumerKey('anonymous');
  oauthConfig.setConsumerSecret('anonymous');
  oauthConfig.setRequestTokenUrl('https://www.google.com/accounts/OAuthGetRequestToken?scope='+scope);
  oauthConfig.setAuthorizationUrl('https://accounts.google.com/OAuthAuthorizeToken');    
  oauthConfig.setAccessTokenUrl('https://www.google.com/accounts/OAuthGetAccessToken');  
  
  var uploadParams = {
    method:'post',
    oAuthServiceName: 'drive',
    oAuthUseToken: 'always',
    contentType: 'application/vnd.ms-excel',
    contentLength: excelFile.getBytes().length,
    payload: excelFile.getBytes()
  };
  
  //Google Driveのルートフォルダへ対象ファイルを変換しつつアップロード
  var uploadResponse = UrlFetchApp.fetch('https://www.googleapis.com/upload/drive/v2/files/?uploadType=media&convert=true&key='+KEY, uploadParams);
    
  //JSONで帰ってくる 細かい話は→ https://developers.google.com/drive/v2/reference/files#resource
  var fileDataResponse = JSON.parse(uploadResponse.getContentText());

  //ファイル名を更新
  var updateParams = {
    method:'put',
    oAuthServiceName: 'drive',
    oAuthUseToken: 'always',
    contentType: 'application/json',
    payload: JSON.stringify({ title: filename })
  };
  
  //更新
  UrlFetchApp.fetch('https://www.googleapis.com/drive/v2/files/'+fileDataResponse.id+'?key='+KEY, updateParams);
  
  //Spreadsheetインスタンス取得して返却
  return SpreadsheetApp.openById(fileDataResponse.id);
}


```

## api keyの準備

https://code.google.com/apis/console/からAPI KEYを取得してください。
でコードをコピペした方は一番上のKEYの中身を直してください。

ライブラリーを使ってる方は第一引数にぶち込んでください。

## 使う

今回は外部サイトから取得したExcelをSpreadsheetに変える処理と、Gmailに添付されたファイルをSpreadsheetに変える処理を書いて見ました。

```javascript

//外部サイトから 
function fromExternalSite() {
  
  var blob = UrlFetchApp.fetch("http://datameti.go.jp/data/ja/storage/f/2013-06-12T125258/13-ipa.xls").getBlob();
  
  
  var ss = Excel2Sheets.convert2Spreadsheet(UserProperties.getProperty("apiKey"), blob, "hoge");
  
}

//Gmailから
function fromGmail() {
  var threads = GmailApp.search("has:attachment xls", 1 ,1);
  
  for(var i = 0; i < threads.length; i++) {
    var thread = threads[i];
    
    var messages = thread.getMessages();
    
    for(var j = 0; j < messages.length; j++) {
      var message = messages[j];
      var attachments = message.getAttachments();
      
      for(var k = 0; k < attachments.length; k++) {
        var attachment = attachments[k];
        Excel2Sheets.convert2Spreadsheet(UserProperties.getProperty("apiKey"), attachment, attachment.getName());
      }
    }
  }
}
```

# まとめ

いかがでしたでしょうか？
ExcelからSpreadsheet変換はGASでは使うシーンが結構多く、
覚えておくと、色々幅が広がります。

ぜひ使ってみてください。