GASでG Driveに保存されているExcelをGoogle スプレッドシートに一括変換する仕組みを作った。
実現したいこと
G Driveに保存されている大量のExcelファイルを一括でGoogleスプレッドシートに変換する。
要件は以下。
- 何ヶ所かのディレクトリに分かれているのでディレクトリはパラメタ化する
- 出力先のディレクトリは任意の場所を指定できるようにする
- ディレクトリ配下のExcelを全部まとめてワンオペで変換する
- 入力はExcelファイル(.xlsx)のみとし、他のファイルがあっても変換しない
- すでに同名のスプレッドシートが出力先にある場合は処理をskipする
ソースコードと解説
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
function convert_main() { // idをもとにディレクトリを取得 var folder = DriveApp.getFolderById('hogehogehogehoge'); // ディレクトリ配下のファイルを全て取得 var excel_files = folder.getFiles(); // 後でExcelかどうか判定するための正規表現 var name = /.*\.xlsx/; // 変換されたファイルが格納される出力ディレクトリをidによって取得 var dest_folder = DriveApp.getFolderById('hogehogehogehoge'); // filesをイテレートしてExcelをスプレッドシートに変換 while(excel_files.hasNext()) { var file = excel_files.next(); var excel_filename = file.getName(); // Excelファイルかどうかの判定 if(name.test(excel_filename)) { // 出力先ディレクトリにすでに同名のスプレッドシートがあるかの判定 if(checkDestFiles(excel_filename.substr(0,excel_filename.length-5),dest_folder)){ Logger.log('already Exist'); }else{ convertToSpreadsheet(file, dest_folder); } } } } // 出力先ディレクトリにfilenameのスプレッドシートがあるかを判定する関数 function checkDestFiles(filename, dest_folder){ // filenameと同名のファイル一覧を取得 var dest_files = dest_folder.getFilesByName(filename); // リターンフラグの初期化(0の場合は同名ファイルなしとしてfalseを返す) var rtn_flg = '0'; // dest_filesをイテレートして同名かつスプレッドシート形式かの判定を行う while(dest_files.hasNext()){ var file = dest_files.next(); if(file.getName() == filename && file.getMimeType() == 'application/vnd.google-apps.spreadsheet'){ rtn_flg = '1' } } if(rtn_flg == '1'){ return true; }else{ return false; } } // スプレッドシートに変換する関数 function convertToSpreadsheet(file, folder) { // 各種オプションを設定 // mimeTypeの指定によりスプレッドシートに変換される options = { title: file.getName(), mimeType: MimeType.GOOGLE_SHEETS, parents: [{id: folder.getId()}] }; // Drive APIへfileをPOSTする Drive.Files.insert(options, file.getBlob()) } |
だいたいコメントの通りだがいくつかポイントだけ。
本当は、
var excel_files = folder.getFiles();
の時点でExcelファイルだけに絞りたかった。
var name = /.*\.xlsx/;
の正規表現をgetFilesByName()
の引数に与えて取得しようと思ったが、どうやらgetFilesByName()は正規表現の引数をサポートしてない?っぽいので諦めた。
「できない」ってのを調べるのに時間がかかってここでハマった。うまくやればできるのか??
name.test(excel_filename)
testメソッドは正規表現オブジェクト(正式には何て言うんだ?)のメソッドで、引数の配列(多分。ちゃんとリファレンスみてない)の中に1件でも正規表現にマッチするものがあればTRUEが返る。
Drive.Files.insert(options, file.getBlob())
ここでDrive APIを使っているので、GASエディターの[リソース]メニューからAPIを有効化しておく必要がある。
何を隠そう、「何ヶ所かのディレクトリに分かれているのでディレクトリはパラメタ化する」「出力先のディレクトリは任意の場所を指定できるようにする」とか言っておきながらソースコード直書きという乱暴さだが、もうめんどくなったのでこのまま使います。
気が向いたらチョロ作業なのでスプレッドシートから値取得するように作り替えます。気が向いたら。