MENU

GASで複数ファイルをZIPにまとめる

当ページのリンクには広告(PR)が含まれていることがあります。
GASで複数ファイルをZIPにまとめる。関連する資料、名前を確認、一つのZIPへの処理例。

報告文と明細CSVを1つにまとめて渡すなら、GASのUtilities.zipで複数のBlobをZIPへ入れられます。Blobはファイルの中身を扱うデータです。DriveのファイルIDだけを並べるのではなく、それぞれの中身を取得して渡します。

まずは小さなテキストとCSVだけを使います。Googleドキュメントの変換や、フォルダごとの圧縮、暗号化は含めません。ファイル数・名前・容量を確認してから、練習用フォルダへ保存する例です。

目次

ZIP内の名前が重ならないようにする

別のDriveファイルでも名前が同じなら、展開したときに区別できない場合があります。入力ファイルのIDだけでなく、ZIPに入れる名前も重複していないかを確認します。パスを含む名前はこの例では受け付けません。

練習用にreport.txtとitems.csvを用意します。例の命名は半角小文字・数字・ハイフン・アンダースコアと拡張子に限定します。これは展開先まで確認しやすくするためのサンプルの制約で、GASが日本語名を扱えないという意味ではありません。

公式のUtilities.zipは、Blobの配列とZIPの名前を受け取り、新しいBlobを返します。Drive上の元ファイルをZIPへ変換して置き換える操作ではありません。

1〜5件の小さなファイルをまとめるコード

元データの合計はこの例独自の上限として50000バイトまでにします。ファイルのMIMEタイプはtext/plainまたはtext/csvだけを認め、Driveの文書形式を自動で別形式へ変換しません。

function buildPracticeZip(files, utilities) {
  if (!Array.isArray(files) || files.length < 1 || files.length > 5) {
    throw new Error('入力ファイルは1〜5件です');
  }
  const names = new Set();
  let total = 0;
  const blobs = files.map(function (file) {
    const name = file.getName();
    if (!/^[a-z0-9_-]+\.(txt|csv)$/.test(name) ||
        /^(con|prn|aux|nul|com[1-9]|lpt[1-9])\./.test(name)) {
      throw new Error('練習用のファイル名を確認してください');
    }
    if (names.has(name)) throw new Error('ZIP内の名前が重複しています');
    names.add(name);
    if (!['text/plain', 'text/csv'].includes(file.getMimeType()) || file.getSize() > 50000) {
      throw new Error('種類か容量を確認してください');
    }
    const blob = file.getBlob().copyBlob().setName(name);
    total += blob.getBytes().length;
    if (total > 50000) throw new Error('元データの合計が50000バイトを超えました');
    return blob;
  });
  return utilities.zip(blobs, 'practice-bundle.zip');
}

function previewPracticeZip() {
  const SAVE = false;
  const ids = ['練習テキストID', '練習CSVのID'];
  const archive = buildPracticeZip(ids.map(id => DriveApp.getFileById(id)), Utilities);
  console.log(JSON.stringify({name: archive.getName(), zipBytes: archive.getBytes().length}));
  if (SAVE) DriveApp.getFolderById('練習用保存先ID').createFile(archive);
}

SAVE:falseではZIPのBlobを作るところまでで、Driveへ新しいファイルを保存しません。保存を試す場合だけtrueへ変えます。出力名はpractice-bundle.zip、容量は実際の入力に応じて変わるので、固定のバイト数を期待値にしません。

コピーしたBlobを使う理由

Blobの公式資料のcopyBlobとsetNameで、圧縮用のデータへ名前を付けています。元のDriveファイルの名前を書き換える処理ではありません。ZIPの中身と元ファイルの対応を確認するための名前です。

保存した練習用ZIPを手元で開き、2件の名前と内容が元のテキスト・CSVに一致するかを確かめます。ZIPを作れたことだけでは、展開先での文字や内容の確認までは済んでいません。

同じ保存処理を繰り返すと、同じ名前のZIPが増える場合があります。結果不明のときは、保存先に既にファイルがあるかを見てから判断します。自動で以前のZIPを削除して置き換える処理は入れません。

配布先と容量の確認

ZIPへまとめても閲覧範囲の判断は必要です。このコードはパスワード付きの圧縮や暗号化をしないため、まとめたことで機密情報が保護されたとは考えないようにします。入力2件のうち一方だけ外部配布できない場合も、ZIP全体の配布先を見直します。

ローカルでは代用ファイルとzip関数で、入力数、名前の重複、パス、形式、容量、Blobのコピーと受け渡しを確認しました。Google上のZIP生成や実際の展開は未実行です。Drive整理の基本とCSVの書き出しを基に、小さな練習データから確認してください。

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次