【簡単GAS】GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法【Drive API 使用版】

アフィリエイト広告を利用しています。
運営者・ポテ

いつもありがとうございます!

ノンプログラマー向け「GAS(Google Apps Script)解説シリーズ」へようこそ。

本稿では「Drive APIを使用して GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法」を解説いたします。

Information
  • Google Apps Script(GAS)
    Googleが提供するスクリプト言語で、GoogleスプレッドシートやGoogleドキュメントなどの操作を自動化できます。JavaScriptをベースにしています。
  • GASとVBAの違い
    GASはWebベースで動作し、クラウド上のファイルを操作します。一方、VBAはローカル環境のExcelに組み込まれた言語です。どちらも「自動化」のために使いますが、GASはGoogleの各種サービスと連携しやすいのが強みです。

前回の記事では、スプレッドシートをプレーンテキストの Excel ファイルに変換し、ローカルにダウンロードする方法をご紹介しました。

この方法は手軽で便利ですが、一時的なスプレッドシートが実行ユーザーのマイドライブに生成されるという設計になっています。

個人利用であれば特に問題はありませんが、組織内で共有しているファイルを処理する場合、個人のドライブにファイルが残るのは避けたいところです。

そうした場面で有効なのが、今回ご紹介するスクリプトです。

基本的な処理の流れは前回と同様ですので、前回の記事もあわせてご覧いただければ理解が深まります。

初心者の方でも理解できるように、わかりやすく、丁寧に解説していきます。ぜひご覧ください。

GASで「Drive API を使用して GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法」

アプリーションの仕様

ここでは、次のようなスプレッドシートを例にとります。このシートでは、商品情報(品番・名称・価格)に加えて、価格に割引率を掛けた「セール価格」が D 列に表示されています。

Googleスプレッドシートに表示された「商品管理表」。A列からD列にかけて「品番」「名称」「価格(円)」「セール価格(円)」の見出しがあり、果物10品目(例:りんご、バナナ、メロンなど)の価格とセール価格が一覧表示されている。D列には、元の価格に対して 20% 割引された値が入力されている。

D 列の各セルには、次のような関数が入力されています。

Googleスプレッドシートの一部。D2セルに「=C2*0.8」という数式が入力されており、隣のC列(価格)から20%引きの値を計算してD列(セール価格)に表示している。品番F001の「りんご」は120円で、セール価格は96円となっている。

今回ご紹介するアプリは次のような流れで動作します。

  1. アクティブなシートの表示値をプレーンテキストとしてコピーし、.xlsx 形式で元のスプレッドシートと同じフォルダに自動保存します。
  2. その後、画面にダウンロード用のダイアログを表示し、リンクをクリックすることで、ファイルをローカルのダウンロードフォルダに保存します。
運営者・ポテ

次のセクションにて、この処理を実現するスクリプトの具体的な内容を解説していきます!

おおまかな処理の流れ

このアプリケーションの大まかな流れは以下の通りです。各ステップの詳細は、次のセクションで解説していきます。

├ onOpen
│ └ メニュー「スクリプトの実行」を作成し、「エクスポート」を追加
└ exportSheetAsExcel
  ├ スプレッドシートの表示値を取得
  ├ Drive APIで一時スプレッドシートを共有フォルダ内に作成
  ├ 表示値を一時スプレッドシートに貼り付け
  ├ 一時スプレッドシートのIDをもとに、サーバー側にExcel形式で出力するためのURLを構築
  │   ※Excelファイルを直接取得できないため
  ├ URLからExcelファイルの中身(バイナリデータ)を取得し、Blob形式に変換
  ├ BlobをExcelファイルとして保存(同じ共有フォルダ内)
  ├ 一時スプレッドシートをごみ箱へ移動
  └ エクスポートファイルのダウンロードリンクをHTMLダイアログで表示

コードの実装

まず、コード全文を示します。

Information
  • 本稿での構文のハイライトについて
    本稿で掲載しているコードは Google Apps Script(GAS)ですが、JavaScript の構文としてハイライト表示しています。
  • コードとスクリプトの違い
    コードはプログラムを構成する記述全般を指し、広い意味を持つ言葉です。スクリプトはその中でも、特定の処理を自動で実行するために書かれた比較的軽量なコードのことを指します。
/**
 * スプレッドシートにカスタムメニュー「スクリプトの実行」を作成し、
 * そのメニューに exportSheetAsExcel 関数を登録する
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('スクリプトの実行')
    .addItem('エクスポート', 'exportSheetAsExcel')
    .addToUi();
}


/**
 * ※この関数の実行には、Drive API(Advanced Drive Service)の有効化が必要です。
 * 
 * アクティブシートの「表示値」を .xlsx 形式でフォルダに出力し、
 * ダウンロードリンクをダイアログで表示する
 */
function exportSheetAsExcel() {
  
  // フォルダの取得
  const folderId = 'your_folder_id'; // ← ★ここにフォルダIDを入れる

  // アクティブシートと表示値を取得
  const sheet  = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const values = sheet.getDataRange().getDisplayValues();

  // Drive API で共有フォルダ内に一時スプレッドシートを作成する
  const fileMetadata = {
    title: 'Export_' + sheet.getName(),             // 作成するスプレッドシートのタイトル
    mimeType: MimeType.GOOGLE_SHEETS,               // 作成形式は Google スプレッドシート
    parents: [{ id: folderId }]                     // 保存先のフォルダを指定
  };

  // Drive API で metadata のみのファイルを作成(フォルダ編集権限が無ければ終了)
  let createdFile;
  try {
    createdFile = Drive.Files.insert(fileMetadata);
  } catch (e) {
    SpreadsheetApp.getUi().alert(
      '一時スプレッドシートの作成に失敗しました。\n' +
      '対象フォルダに編集権限がない可能性があります。\n\n' +
      'エラー内容: ' + e.message
    );
    return;
  }

  // 作成した一時スプレッドシートを開く
  const tempSS = SpreadsheetApp.openById(createdFile.id);
  const tempSheet = tempSS.getActiveSheet();

  // 取得済みの表示値を一時スプレッドシートに貼り付ける
  tempSheet.getRange(1, 1, values.length, values[0].length).setValues(values);

  // ★重要:ここでバッファをフラッシュしないと空の .xlsx が生成される ★
  SpreadsheetApp.flush();   

  // エクセルエクスポート用の URL を構築
  const exportUrl =
    'https://docs.google.com/spreadsheets/d/' +
    tempSS.getId() +
    '/export?format=xlsx';

  // OAuth トークンを付与してエクセルファイルを取得し、ファイル名に "Export_" を付ける
  // blob・・・Binary Large Object;画像やファイルなどの“中身そのもの”をデータのかたまりとして扱うもの
  const blob = UrlFetchApp.fetch(exportUrl, {
    headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() }
  }).getBlob().setName('Export_' + sheet.getName() + '.xlsx');
  
  // エクスポートファイルを指定フォルダ(folderId)に保存する 
  const destFolder = DriveApp.getFolderById(folderId);  // 保存先フォルダを folderId で取得
  const excelFile  = destFolder.createFile(blob);

// ファイル操作の反映を確実に行う(念のため)
  SpreadsheetApp.flush();  

  // 一時スプレッドシートをゴミ箱へ移動
  DriveApp.getFileById(tempSS.getId()).setTrashed(true);

  // HTML ダイアログでダウンロードリンクを表示
  const fileId      = excelFile.getId();
  const downloadUrl = 'https://drive.google.com/uc?export=download&id=' + fileId;
  const htmlContent =
    '<p>Excelファイルが作成されました。<br>' +
    '<a href="' + downloadUrl + '" target="_blank">' +
    '▶ ダウンロード (Export_' + sheet.getName() + '.xlsx)' +
    '</a></p>';
  const html = HtmlService
    .createHtmlOutput(htmlContent)
    .setWidth(400)
    .setHeight(120);
  SpreadsheetApp.getUi().showModalDialog(html, 'ファイルをダウンロード');
}

次に、このコードの基本的な動作を説明します。

このコードは、スプレッドシートに追加されたカスタムメニューから実行します。メニュー「スクリプトの実行」から「エクスポート」をクリックすると、処理が開始されます。

Googleスプレッドシート上に表示された商品管理表。カスタムメニュー『スクリプトの実行』が表示されており、その中に『エクスポート』という項目がある。
スクリプトの実行

処理が始まると、アクティブシートの表示値がプレーンテキストとして抽出され、Excelファイル(.xlsx形式)として Google ドライブ内に自動的に生成されます。生成されたファイルは、指定した Folder ID のフォルダに保存されます

Google ドライブ上のフォルダ『エクスポート方法検討』に保存された Excel ファイル『Export_商品管理表.xlsx』が表示されている画面
Excelファイルが生成される

続いて、画面上にダウンロード用のダイアログが自動的に表示されます。

Googleスプレッドシート上でスクリプトを実行した直後に、ファイルをダウンロードするためのダイアログが表示され、『ダウンロード(Export_商品管理表.xlsx)』というリンクが案内されている。
ダウンロードのリンク

このダイアログには、生成された Excel ファイルをダウンロードするためのリンクが含まれています。ユーザーがそのリンクをクリックすると、ファイルはローカルの「ダウンロード」フォルダに保存されます。

Windowsのダウンロードフォルダを開いた状態。『Export_商品管理表.xlsx』というExcelファイルが保存されている様子が表示されている。
ローカルにダウンロードされる

ダウンロードされたファイルでは、数式が削除され、表示されていた値のみが残ります。たとえば、D2セルには元々「=C2*0.8」と数式が入力されていましたが、いダウンロードされたされたExcelファイルでは計算結果の「96」という数値だけが保持され、数式は含まれません。

Excelで開いたエクスポート済みファイルの画面。D2セルには '96' という数値が表示されており、上部の数式バーにも '96' と表示されている。セルには数式が含まれていないことを示している。

以上が、基本的な処理の流れです。


運営者・ポテ

ここからは、コードの詳細な解説をしていきます。

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('スクリプトの実行')
    .addItem('エクスポート', 'exportSheetAsExcel')
    .addToUi();
}

ここでは、スプレッドシートを開いたときに表示されるカスタムメニューを追加しています。

onOpen() は、スプレッドシートを開いたタイミングで自動的に実行される関数です。

この中で、SpreadsheetApp.getUi() を使ってユーザーインターフェースを取得し、「スクリプトの実行」という名前のメニューを作成しています。

そのメニューの中に「エクスポート」という項目を追加し、クリックすると exportSheetAsExcel() 関数が実行されるように設定しています。

このようにすることで、ユーザーがスプレッドシートのメニューから、スクリプトを直接呼び出せるようになります。

function exportSheetAsExcel() {
  
  // フォルダの取得
  const folderId = '1i0VdKQPmj58oMavxLjjEddQDNLF9w4zX'; // ← ★ここにフォルダIDを入れる

ここでは、エクスポートファイルを保存するGoogleドライブのフォルダIDを指定しています。

folderId には、ファイルの保存先となるフォルダのIDを文字列で代入します。この値は、GoogleドライブのURLから分かります

たとえば、URLがhttps://drive.google.com/drive/folders/xxxxxxxxxxxxxxxxxxxxxxxであれば、その「xxxxxxxxxxxxxxxxxxxxxxx」の部分がフォルダIDです。

  // アクティブシートと表示値を取得
  const sheet  = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const values = sheet.getDataRange().getDisplayValues();

ここでは、スプレッドシートの表示値を取得しています。

getActiveSpreadsheet() でアクティブなスプレッドシートを取得し、その中から getActiveSheet() を使って、現在表示されているシートを取得しています。

続いて、getDataRange().getDisplayValues() を使って、シート内のすべてのセルの表示値を二次元配列として取得しています。

ここでの「表示値」とは、セルに入力されている数式ではなく、画面上に表示されている見た目の値のことです。

  // Drive API で共有フォルダ内に一時スプレッドシートを作成する
  const fileMetadata = {
    title: 'Export_' + sheet.getName(),             // 作成するスプレッドシートのタイトル
    mimeType: MimeType.GOOGLE_SHEETS,               // 作成形式は Google スプレッドシート
    parents: [{ id: folderId }]                     // 保存先のフォルダを指定
  };

ここでは、Drive API で作成する一時ファイルの情報(メタデータ)を定義しています。

fileMetadata は、作成するスプレッドシートの基本情報をまとめたオブジェクトです。

設定の内容は、次の通りです。

  • title
    ファイル名を指定しています。元のシート名に "Export_" という接頭辞を付けて構成しています。
  • mimeType
    作成するファイルの形式を指定しています。ここでは MimeType.GOOGLE_SHEETS を指定しており、Google スプレッドシート形式でファイルが作成されます。
  • parents
    保存先のフォルダ ID を指定しています。この ID に対応するフォルダの中に、ファイルが作成されます。
  // Drive API で metadata のみのファイルを作成(フォルダ編集権限が無ければ終了)
  let createdFile;
  try {
    createdFile = Drive.Files.insert(fileMetadata);
  } catch (e) {
    SpreadsheetApp.getUi().alert(
      '一時スプレッドシートの作成に失敗しました。\n' +
      '対象フォルダに編集権限がない可能性があります。\n\n' +
      'エラー内容: ' + e.message
    );
    return;
  }

ここでは、Drive API を使って一時スプレッドシートを作成しています。スプレッドシートの作成には、保存先フォルダに対する「編集権限」が必要です。そのため、ユーザーに権限がない場合はエラーを発生させ、スクリプトの実行を中断するようにしています。

具体的には、Drive.Files.insert(fileMetadata) を使って、あらかじめ指定したメタデータに基づくスプレッドシートを作成しています。

この処理は、フォルダに編集権限がないと失敗するため、try...catch 構文を使ってエラーを検知し、SpreadsheetApp.getUi().alert() でメッセージを表示したうえで、処理を中断するようにしています。

このようにして、編集権限のない組織外のユーザーは、スクリプトを実行できないようにしています。

  // 作成した一時スプレッドシートを開く
  const tempSS = SpreadsheetApp.openById(createdFile.id);
  const tempSheet = tempSS.getActiveSheet();

ここでは、Drive API で作成した一時スプレッドシートを開き、アクティブシートを取得しています。

  • temSS
    一時スプレッドシートを操作できるように、ファイル ID を使ってスプレッドシートを開いています。このファイル ID(createdFile.id)には、直前の処理で Drive API によって作成されたスプレッドシートの ID が格納されています。
    SpreadsheetApp.openById() を使うことで、そのファイルを Apps Script の操作対象として扱えるようになります。
  • tempSheet
    上記の操作で開いた一時スプレッドシートから、getActiveSheet() を使ってアクティブシートを取得しています。このシート(tempSheet)が、後の処理で表示値を貼り付ける対象になります。
  // 取得済みの表示値を一時スプレッドシートに貼り付ける
  tempSheet.getRange(1, 1, values.length, values[0].length).setValues(values);

ここでは、取得した表示値を一時スプレッドシートに貼り付けています。

getRange(1, 1, values.length, values[0].length) で、左上のセル(1行1列目)を起点に、データの行数と列数に対応する範囲を指定しています。その範囲に対して setValues(values) を呼び出すことで、2次元配列である values を一括で書き込んでいます。

  // ★重要:ここでバッファをフラッシュしないと空の .xlsx が生成される ★
  SpreadsheetApp.flush();   

ここでは、貼り付けたデータの変更内容を確実に反映させるため、バッファを明示的にフラッシュしています。

SpreadsheetApp.flush() を呼び出すことで、スクリプト上の変更内容が Google のサーバーに即時反映されます。これを実行しないと、あとでエクスポートする .xlsx ファイルにデータが反映されず、空のファイルが生成されてしまうことがあります。

Information

フラッシュ(flush)
処理中の変更内容を一時的なバッファ(作業領域)から確定状態として反映させることを意味します。Apps Script では、flush() を使うことで、変更がスプレッドシートに適用されます。

  // エクセルエクスポート用の URL を構築
  const exportUrl =
    'https://docs.google.com/spreadsheets/d/' +
    tempSS.getId() +
    '/export?format=xlsx';

ここでは、一時スプレッドシートを Excel(.xlsx)形式でエクスポートするための URL を構築しています。

tempSS.getId() で、先ほど作成したスプレッドシートのファイル ID を取得し、その ID を Google スプレッドシートのエクスポート用URLのパターンに当てはめています。

末尾に付けている '/export?format=xlsx' は、スプレッドシートを Excel 形式でエクスポートするための形式の指定です。

この URL は、ユーザーが直接アクセスするものではなく、スクリプト内部でファイルデータを取得するためのリクエスト用 URL として使われます。後の処理で UrlFetchApp.fetch() に渡され、ファイルデータの取得に使われます。

  // OAuth トークンを付与してエクセルファイルを取得し、ファイル名に "Export_" を付ける
  // blob・・・Binary Large Object;画像やファイルなどの“中身そのもの”をデータのかたまりとして扱うもの
  const blob = UrlFetchApp.fetch(exportUrl, {
    headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() }
  }).getBlob().setName('Export_' + sheet.getName() + '.xlsx');

ここでは、エクスポート用 URL を使って Excel ファイルのデータを取得し、そのファイルに名前を付けています。処理の流れは次の通りです。

  • UrlFetchApp.fetch()exportUrl を渡し、スクリプト内からリクエストを送っています。このとき、OAuth トークンをヘッダーに付与することで、スクリプト実行者の権限でファイルを取得できるようにしています。
  • .getBlob() を使って、取得したレスポンスを blob(Binary Large Object)形式のデータとして取り出しています。blob とは、画像やファイルなどの“中身そのもの”をひとまとまりのデータとして扱う形式です。
  • .setName() で、取得したファイルに "Export_" + シート名 + ".xlsx" の形式で名前を付けています。
  // エクスポートファイルを指定フォルダ(folderId)に保存する 
  const destFolder = DriveApp.getFolderById(folderId);  // 保存先フォルダを folderId で取得
  const excelFile  = destFolder.createFile(blob);

ここでは、取得した Excel ファイル(blob)を、指定したフォルダに保存しています。

  • destFolder
    DriveApp.getFolderById(folderId) を使って、保存先のフォルダを取得しています。folderId は、スクリプトの前半で指定したフォルダ ID です。
  • excelFile
    createFile(blob) を呼び出すことで、blob データをそのまま Excel ファイルとして保存しています。このとき、前の処理で .setName() しておいたファイル名がそのまま適用されます。
// ファイル操作の反映を確実に行う(念のため)
  SpreadsheetApp.flush();  

ここでは、保存処理などのファイル操作が確実に反映されるよう、明示的にフラッシュを実行しています。

  // 一時スプレッドシートをゴミ箱へ移動
  DriveApp.getFileById(tempSS.getId()).setTrashed(true);

ここでは、処理の中で一時的に作成したスプレッドシートを、ゴミ箱に移動しています。

DriveApp.getFileById(tempSS.getId()) で対象のファイルを特定し、setTrashed(true) によってゴミ箱に送っています。ここではファイルを完全に削除するのではなく、ごみ箱へ移動している状態です。

これは、共有ドライブに不要な一時ファイルが残らないようにするための処理ですが、もしこのファイルを残しておきたい場合は、このコード行を削除するか、コメントアウトしておいても問題ありません。

  // HTML ダイアログでダウンロードリンクを表示
  const fileId      = excelFile.getId();
  const downloadUrl = 'https://drive.google.com/uc?export=download&id=' + fileId;
  const htmlContent =
    '<p>Excelファイルが作成されました。<br>' +
    '<a href="' + downloadUrl + '" target="_blank">' +
    '▶ ダウンロード (Export_' + sheet.getName() + '.xlsx)' +
    '</a></p>';
  const html = HtmlService
    .createHtmlOutput(htmlContent)
    .setWidth(400)
    .setHeight(120);
  SpreadsheetApp.getUi().showModalDialog(html, 'ファイルをダウンロード');
}

ここでは、ダウンロードリンクを含む HTML ダイアログを作成し、ユーザーに表示しています。処理の流れは次の通りです。

  • excelFile.getId() で、先ほど保存した Excel ファイルの ID を取得し、それを使って https://drive.google.com/uc?export=download&id=... という 直接ダウンロード用の URL を組み立てています。
  • htmlContent では、ダイアログに表示する内容(文章とリンク)を、HTMLというWebページ用の書式で1つの文字列として用意しています。<a> タグでリンクを設定し、ファイル名には "Export_" + シート名 + ".xlsx" を使用しています。
  • HtmlService.createHtmlOutput() を使って HTML を生成し、サイズ(幅400px × 高さ120px)を指定しています。
  • 最後に、showModalDialog() を使って、スプレッドシート上にダイアログを表示しています。このダイアログには、作成されたファイルをユーザーが手動でダウンロードできるリンクが表示されます。

このようにして、生成されたExcelファイルをユーザーが迷うことなくスムーズにダウンロードできるよう、導線を整えています。

運営者・ポテ

以上で解説は終了です。ありがとうございました!

おわりに

運営者・ポテ

ご覧いただきありがとうございました!

今回の記事では、「Drive APIを使用して GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法」を解説いたしました。

お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。

皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。

なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。

この記事を書いた人

運営者・ポテ
■人生を追求する凡人■日本一安全で、気の向くままに自分の時間を過ごせる、こだわりのキャンプ場を作るのが夢■光学・機械系エンジニア(歴20年、内マネジメント10年、特許数件権利化)/副業フリーランスエンジニア■読書・文学愛好■人生は時間そのもの。ひとりでも多くの人が「より良い人生にするために時間を使って欲しい」と願い、仕事のスキルの向上、余暇の充実、資産形成を研究。■VBAアプリ開発サービス提供中(業務委託 / VBA使用経験20年)■Python愛好(歴5年)■VBAエキスパート「Excel VBA スタンダード」(上級者向け資格)/ Python 3 エンジニア認定基礎(経済産業省「ITスキル標準(ITSS)」に掲載)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です