JavaScript
GoogleAppsScript

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

More than 5 years have passed since last update.

この記事はGoogle Apps Script Advent Calendar 2013の5日目の穴埋め記事です。

穴埋めなので、後日書いてます。


忙しい人のために、オチ

前に書いた、ExcelからSpreadsheetに変換するスクリプトの記事があまりにも不真面目過ぎたので

ちゃんと書きたいと思います。

今回の記事を読むと、

Gmailに添付されたExcelをSpreadsheetに変換したり、

Sites内にあるExcelをSpreadsheetに変換できる用になります。

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


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%の再現は不可能なため、

移行が進まなかったりします。


コラム

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


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に変える処理を書いて見ました。


//外部サイトから
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では使うシーンが結構多く、

覚えておくと、色々幅が広がります。

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