ZIPの圧縮解凍をしたい
Google Drive上にあるファイルを固めてZIPで圧縮したいだとか、逆にZIPで固めてあるファイルを解凍したいといった時に、Google Drive上では閲覧することはできますが、ZIPで作成はできません。また、それらをスクリプトからコントロールするとなると予め、ユーザに解凍してもらっておくだとか、圧縮しておいてもらうなどの作業を手動で行わせる必要性があります。これは面倒。ということで、どうにかならないかと考えていたのですが、非常にネット上で資料が少なく、しかもリファレンスも実に不親切ながら、いくつかの情報を得たので、実際にやってみることに。
ZIP圧縮をするコード
function doGet(){
//圧縮するファイルが入ってるフォルダを指定
var folder = DocsList.getFolderById('0BzN10lCzkUqkRERYVDJtM2xGZms');
//圧縮するファイルの準備
var filelist = folder.getFiles();
//zip圧縮を行う
var zipman = Utilities.zip(filelist, 'test.zip');
folder.createFile(zipman).rename(folder.getName());
}
今回は、とあるフォルダにあるファイル群をzipで固めて、フォルダ名と同じファイル名をつけて、その対象のフォルダの中にzipを保存するというスクリプトです。
複雑そうに見えたのですが、リファレンスよりもStack Overflowのサイトのほうが遥かに役に立ちました。お陰で、複雑なことをせずに簡単に作ることができました。doGet()にしている理由はスプレッドシートにスクリプトを作るのではなく、単体のスクリプトとして作成したからです。
一旦test.zipというファイル名でファイルを作成して、その後にrenameにて名称を変更しています。
ZIP解凍をするコード
function doGet(){
//解凍する対象のファイルを取得
var zipfile = DocsList.getRootFolder().find('pinpon');
var zipblob = zipfile[0].getBlob();
//ファイル解凍の準備
var unzipfile = Utilities.unzip(zipblob);
//フォルダを作成してその中にunzipファイルを入れる
var newFolder = DocsList.createFolder('zipmelt');
for(i=0;i<unzipfile.length;i++){
newFolder.createFile(unzipfile[i]);
}
}
今回は、zipmeltというフォルダを作成し、pinponという名前のzipファイルの中身を全部取り出して見ました。
ZIP作成のように、全部を一気に解凍とか出来るのかと思ったのですが、unzipで取り出されるのはBlobとなってる配列であって、一個一個取り出す必要性がありました。そこで、unzipfileに配列を格納して、lengthで個数を取り出してループでひとつひとつcreatefileで作るという作業で全部のファイルの解凍を行っています。なんとなく気持ちの悪いコードです。
必ず、対象となるzipファイルをただ単純にgetfileするのではなく、getBlobで格納してからunzipしてやらないとうまくいかないという点で相当はまっていました。
ポイント
今回、スクリプトを作成するにあたって、嵌ってました。
ループで回して、配列として用意した変数に[]を加えて、pushしていたのですが、この方法はダメみたいです。外部URLのファイルをそれぞれURLとして変数に格納しての場合には、この方法でうまく行っていたのが良くなかったようです。実際に、zipファイルを作成するにあたって、リファレンスにあるように配列で渡して挙げなければいけないという点もそうなのですが、Utilities.zip([faviconBlob, logoBlob], "google_images.zip"); といった具合ではなく、ずっと変数で渡してあげてたのですが、配列がおかしかったことに気が付きませんでした。
今回は適当に作ってますが、メールに添付や特定のフォルダに保存など、もう一工夫付け加えるとなお、活用できるのではと思います。特にメール添付の場合、例えば、リファレンスにあるように外部URLのファイルをZIPできるので、DropBoxの公開URLを元に圧縮して、送りつけるなんて芸当も可能です。