Googleスプレッドシートから好きなシートのみを選択して一括でエクセルにダウンロードする方法【GAS活用】

業務やプロジェクトでGoogleスプレッドシートを使っていると、こんな悩みを抱えることがあります。

  • スプレッドシートでエクセル保存すると全てのシートが保存される
  • 必要なシートだけまとめてエクセルに変換したい
  • マイドライブに不要なファイルが残るのは避けたい

こうした悩みを解消するために、Google Apps Script(GAS)を活用して、複数のシートをチェックボックスで選び、Excel形式(.xlsx)で一括ダウンロードできる仕組みを作りました。


手間をゼロにする、シンプルな操作画面

今回の仕組みでは、スプレッドシートを開くと「カスタムツール」というメニューが追加されます。そこから「シートをExcelでダウンロード」を選ぶと、以下のような画面が表示されます。

  • 各シートがチェックボックス付きで一覧表示
  • ダウンロードしたいシートにチェック
  • 関数も含めるか、関数をクリアして値だけにするかを選択
  • 任意のファイル名を入力して「ダウンロード」ボタンをクリック

これだけで、複数のシートがまとめて1つのExcelファイルに変換され、PCに直接保存されます。マイドライブには一切ファイルが残らない仕様のため、ストレージの整理も不要です。


Google Apps Scriptで実現した機能の仕組み

今回の機能は、以下のような流れで動作しています:

  1. スプレッドシートのシート一覧を取得
  2. HTMLダイアログにチェックボックス形式で表示
  3. 選ばれたシートを一時スプレッドシートにコピー
  4. Googleのエクスポート機能を使って .xlsx ファイルを取得
  5. ファイルをBase64形式に変換して、ユーザーのブラウザ経由で直接ダウンロード
  6. 一時スプレッドシートは自動的にゴミ箱へ移動(クリーン)

開発のポイントは、Drive APIなどの高度な設定を一切使っていないこと。Google Apps Scriptと標準機能だけで完結するため、初心者でもすぐに導入できます。


UI(動作メニュー)の内容

実際のUIは以下のような構成です:

  • シート名ごとのチェックボックス
  • ファイル名の入力欄(拡張子不要)
  • エクスポート方法(関数を含めるか、値だけにするかを選択)
  • 「キャンセル」「ダウンロード」ボタン

迷わず使える、シンプルなデザイン、メニューにしました。


実務での活用シーン

この機能は、以下のようなシーンで特に効果を発揮します。

活用例効果
月別レポートの一括出力月ごとのシートをまとめてExcelに変換
チーム別タブの抽出必要な担当者のシートだけを選んで出力
会議資料の配布前加工関数を含まない「値だけ」のExcelを生成

スプレッドシートが大規模になるほど、手動での処理にかかる時間とリスクが増えます。今回の仕組みを導入することで、その課題を根本から解決できます。


まとめ

Googleスプレッドシートを使う機会が増える中で、複数シートを手軽にExcel形式でダウンロードできる仕組みは業務効率を大きく改善してくれます。

今回紹介した方法は、

  • ノーコードで導入可能
  • UI付きで操作も簡単
  • Driveを汚さずクリーンに管理可能

という点で非常に実用的です。


💻 コード全公開:GASとHTMLで構築

以下の2つのファイルをGoogle Apps Scriptに貼り付けるだけで、複数シートをExcel形式でダウンロードできる仕組みが完成します。(期間限定で無料公開中)

/**
 * メニューに「カスタムツール」を追加し、
 * ダイアログを呼び出す
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu("カスタムツール")
    .addItem("シートをExcelでダウンロード", "showExportDialog")
    .addToUi();
}

/**
 * HTML ダイアログ(ExportDialog.html)を表示
 */
function showExportDialog() {
  const html = HtmlService.createHtmlOutputFromFile("ExportDialog")
    .setWidth(400)
    .setHeight(460);  // ボタンが隠れないように調整
  SpreadsheetApp.getUi().showModalDialog(html, "シートをExcelでダウンロード");
}

/**
 * アクティブなスプレッドシートの全シート名を配列で返す
 */
function getSheetNames() {
  return SpreadsheetApp.getActiveSpreadsheet()
    .getSheets()
    .map(sheet => sheet.getName());
}

/**
 * 選択されたシート群を一時シートにコピーし、
 * Excel (.xlsx) としてエクスポートしたBlobを
 * Base64文字列で返却する
 *
 * @param {{sheetNames: string[], exportFormulas: boolean}} payload
 */
function exportSheetsAsBase64WithOption(payload) {
  const { sheetNames, exportFormulas } = payload;
  const original = SpreadsheetApp.getActiveSpreadsheet();
  const tempSS = SpreadsheetApp.create("temp_export");

  // 各シートを値 or 関数込みでコピー
  sheetNames.forEach((name, idx) => {
    const src = original.getSheetByName(name);
    if (!src) return;

    let dest;
    if (idx === 0) {
      dest = tempSS.getSheets()[0];
      dest.setName(name);
    } else {
      dest = tempSS.insertSheet(name);
    }

    const range = src.getDataRange();
    const numRows = range.getNumRows();
    const numCols = range.getNumColumns();

    if (exportFormulas) {
      // 関数があるセルはそのまま、ないセルは値をコピー
      const formulas = range.getFormulas();
      const values   = range.getValues();
      const finalData = [];
      for (let r = 0; r < numRows; r++) {
        finalData[r] = [];
        for (let c = 0; c < numCols; c++) {
          finalData[r][c] = formulas[r][c] !== ""
            ? formulas[r][c]
            : values[r][c];
        }
      }
      dest.getRange(1, 1, numRows, numCols).setValues(finalData);
    } else {
      // 値のみコピー
      const values = range.getValues();
      dest.getRange(1, 1, values.length, values[0].length).setValues(values);
    }
  });

  // 書き込みを確定
  SpreadsheetApp.flush();

  // Export API 経由で xlsx を取得
  const exportUrl = `https://docs.google.com/spreadsheets/d/${tempSS.getId()}/export?format=xlsx`;
  const token = ScriptApp.getOAuthToken();
  const response = UrlFetchApp.fetch(exportUrl, {
    headers: { Authorization: `Bearer ${token}` },
    muteHttpExceptions: true
  });

  // 一時ファイルはゴミ箱へ
  DriveApp.getFileById(tempSS.getId()).setTrashed(true);

  // Blob を Base64 文字列にして返す
  const blob = response.getBlob().setName("export.xlsx");
  return Utilities.base64Encode(blob.getBytes());
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    /* ベースリセット */
    html, body { height:100%; margin:0; padding:0; box-sizing:border-box; font-family:sans-serif; }
    /* ヘッダー */
    .header { background:#D93025; color:#fff; padding:12px; font-size:16px; }
    /* コンテナ */
    .container { display:flex; flex-direction:column; height:calc(100% - 48px); padding:16px; overflow:hidden; }
    /* 可変スクロール領域 */
    .scrollable { flex:1; overflow-y:auto; }
    .field { margin-bottom:12px; }
    label { display:block; margin-bottom:4px; font-size:14px; color:#202124; }
    select, input[type="text"] {
      width:100%; padding:8px; font-size:14px;
      border:1px solid #dadce0; border-radius:4px; box-sizing:border-box;
    }
    /* シートリスト */
    #sheetContainer {
      border:1px solid #dadce0; border-radius:4px;
      padding:8px; max-height:260px; overflow-y:auto;
    }
    #sheetContainer div { display:flex; align-items:center; margin-bottom:4px; }
    #sheetContainer input { margin-right:8px; }
    /* ボタン */
    .buttons { text-align:right; margin-top:8px; }
    .buttons button {
      margin-left:8px; padding:8px 16px; font-size:14px;
      border:none; border-radius:4px; cursor:pointer;
    }
    .cancel { background:transparent; color:#5f6368; }
    .download { background:#1a73e8; color:#fff; }
  </style>
</head>
<body>
  <div class="header">シートをExcelでダウンロード</div>
  <div class="container">
    <div class="scrollable">
      <div class="field">
        <label>ダウンロードするシートを選択</label>
        <div id="sheetContainer"></div>
      </div>
      <div class="field">
        <label for="fileName">ファイル名(拡張子不要)</label>
        <input id="fileName" type="text" placeholder="exported_sheets">
      </div>
      <div class="field">
        <label>エクスポート方法</label>
        <select id="formulaOption">
          <option value="false">値のみエクスポート</option>
          <option value="true">関数も含めてエクスポート</option>
        </select>
      </div>
    </div>
    <div class="buttons">
      <button class="cancel" onclick="google.script.host.close()">キャンセル</button>
      <button class="download" onclick="doExport()">ダウンロード</button>
    </div>
  </div>

  <script>
    // 初期化:シート名を取得してチェックリストを生成
    google.script.run.withSuccessHandler(names => {
      const container = document.getElementById('sheetContainer');
      names.forEach(name => {
        const id = 'chk_' + name.replace(/[^a-zA-Z0-9]/g, '_');
        const div = document.createElement('div');
        const cb = document.createElement('input');
        cb.type = 'checkbox'; cb.id = id; cb.value = name;
        const lbl = document.createElement('label');
        lbl.htmlFor = id; lbl.textContent = ' ' + name;
        div.appendChild(cb); div.appendChild(lbl);
        container.appendChild(div);
      });
    }).getSheetNames();

    // ダウンロード実行
    function doExport() {
      const checked = Array.from(
        document.querySelectorAll('#sheetContainer input:checked')
      ).map(cb => cb.value);
      if (!checked.length) {
        alert('少なくとも1つ選択してください');
        return;
      }
      const exportFormulas = document.getElementById('formulaOption').value === 'true';
      const fname = document.getElementById('fileName').value.trim() || 'exported_sheets';

      google.script.run.withSuccessHandler(b64 => {
        const link = document.createElement('a');
        link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + b64;
        link.download = fname + '.xlsx';
        link.click();
        google.script.host.close();
      }).exportSheetsAsBase64WithOption({
        sheetNames: checked,
        exportFormulas: exportFormulas
      });
    }
  </script>
</body>
</html>

※Google Apps Script 本体コードはスクリプトを選んで実行してください。(承認作業必要)ダイアログ用 HTMLはHTMLを選んで、名称をExportDialog.htmlにしてください。

拡張機能→Apps Scriptでカスタムできます。

このツールを使えば、日々のExcel出力作業がとてもスムーズになります。

  • 手作業で1枚ずつ保存する必要なし!
  • 間違って上書き保存する心配もなし!
  • 作業時間がグッと短縮!

「これは便利!」と思ったら、ぜひ自分用にカスタマイズしてみてくださいね😊

HSBC香港、香港保険、オフショア積立等でお困り方はLINEでお気軽にお問い合わせください(^^♪

友だち追加    

ご支援いただけましたら励みになりますm(_ _)m

※一口500円です。