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

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

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

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

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

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

データの規模が大きい場合や、GAS では対応しきれない高度で柔軟な処理を行いたい場合、スプレッドシートをローカルにダウンロードして、VBA などで扱いたくなることがあります。

そのようなときには、Google スプレッドシートが提供している Microsoft Excel 形式でのダウンロード機能を利用するのが一般的です。ファイルメニューから数クリックで実行でき、操作もとても簡単です。

Googleスプレッドシートの「ファイル」メニューを開き、「ダウンロード」から「Microsoft Excel(.xlsx)」形式を選択している画面。青い矢印が Excel形式を指しており、手動でエクスポートする操作を示している。
ファイルメニューからの Excel ダウンロード

ただし、スプレッドシートに設定されている関数が複雑だったり、データ量が多かったりする場合には、ダウンロードした Excel ファイルが破損して正しく開けないことがあります。そうした場面で有効なのが、今回ご紹介するスクリプトです。

このスクリプトは、次のような流れで動作します。

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

本稿が、あなたのアプリケーションの価値をさらに高める一助となれば幸いです。GAS(Google Apps Scripts)を活用して、自分自身や身近なコミュニティに合ったアプリケーションを作成し、仕事量は半分に、成果は2倍にしていきましょう!成果を増やす!

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

GASで「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  
   ├ スプレッドシートの表示値を取得  
   ├ 一時スプレッドシートを作成して表示値を貼り付け  
   ├ 一時スプレッドシートを元に、サーバー側に Excel 形式で出力するための URL を構築
   │   ※マイドライブに直接 Excel を出力できないため 
   ├ URLからExcelファイルの中身(バイナリデータ)を取得し、Blob形式に変換 
   │  ※Excelファイルを直接取得できないため
   ├ BlobをExcelファイルに変換し、スプレッドシートと同じフォルダに保存  
   ├ 一時スプレッドシートをゴミ箱へ移動  
   └ エクセルのダウンロードリンクをHTMLダイアログで表示  

コードの実装

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

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

/**
 * アクティブシートの表示値を .xlsx 形式でエクスポートし、
 * 元のスプレッドシートと同じフォルダに保存する。
 * 保存後にダウンロードリンクをダイアログで表示する。
 */
function exportSheetAsExcel() {
  // アクティブシートと表示値を取得
  const sheet  = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const values = sheet.getDataRange().getDisplayValues();

  // 値貼り付け用の一時スプレッドシートを作成
  const tempSS    = SpreadsheetApp.create('Export_' + sheet.getName());
  const tempSheet = tempSS.getActiveSheet();
  tempSheet.getRange(1, 1, values.length, values[0].length).setValues(values);

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

  // .xlsx エクスポート 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');
  
  // 元スプレッドシートと同じフォルダに保存(フォルダがない場合はルート)-----------------------
  // ssFile・・・Spredsheet File
  const ssFile     = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId());
  const parents    = ssFile.getParents();
  const destFolder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
  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 ドライブ内に自動的に生成されます。生成されたファイルは、元のスプレッドシートと同じフォルダに保存されます。

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();
}

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

SpreadsheetApp.getUi() を使ってユーザーインターフェースを取得し、「スクリプトの実行」という名前のメニューを作成しています。そのメニューの中に「エクスポート」という項目を追加し、この項目をクリックすると exportSheetAsExcel() 関数が実行されるようにしています。

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

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

ここでは、エクスポート対象となるアクティブシートと、その表示値を取得しています。

まず SpreadsheetApp.getActiveSpreadsheet().getActiveSheet() で、現在開いているスプレッドシートのうち、ユーザーが選択中のシート(アクティブシート)を取得します。

次に sheet.getDataRange().getDisplayValues() によって、そのシート内で実際に表示されているデータ(関数の式ではなく計算後の値)を、2次元配列の形式で取得します。

このようにして、ユーザーが見ているとおりの値をそのままエクスポート対象として扱えるようにしています。

  // 値貼り付け用の一時スプレッドシートを作成
  const tempSS    = SpreadsheetApp.create('Export_' + sheet.getName());
  const tempSheet = tempSS.getActiveSheet();
  tempSheet.getRange(1, 1, values.length, values[0].length).setValues(values);

ここでは、データの貼り付け用として一時的なスプレッドシートを新たに作成し、そこに取得した表示値を貼り付けています。

SpreadsheetApp.create('Export_' + sheet.getName()) によって、新しいスプレッドシートを作成します。名前には、元のシート名の前に "Export_" を付けています。

続いて、作成されたばかりの一時スプレッドシートからアクティブシートを取得し、先ほど取得した values 配列をそのまま貼り付けます。貼り付け先の範囲は、データの行数と列数に応じて動的に指定されます。

データの貼り付けの部分をさらに詳述すると次のようになります。

  • getRange(1, 1, values.length, values[0].length)
    これは「貼り付け先のセル範囲」を指定しています。最初の 1, 1 は、左上のセル(A1セル)を起点にするという意味です。次の values.length はデータの「行数」、values[0].length は「列数」を表しています。つまり、元のデータと同じサイズの範囲を動的に取得している、ということになります。
  • .setValues(values)
    指定した範囲に、取得したデータ values をまとめて一括で貼り付ける処理です。
  // ★重要:ここでバッファをフラッシュしないと空の .xlsx が生成される★
  SpreadsheetApp.flush();   

ここでは、貼り付け処理を確実に反映させるために .flush() を実行しています。これは Google Apps Script が内部的に行っている処理を明示的に確定させる操作です。

特に今回のように、.xlsx 形式でファイルを書き出す処理では注意が必要です。なぜなら、スクリプトがまだ値の貼り付け処理を終える前にエクスポートが始まってしまうと、貼り付けられていない=空のスプレッドシートの状態で出力されてしまうことがあるからです。

この .flush() を入れることで、貼り付け処理の完了を待ってから次の処理(エクスポート)が実行されるようになります。

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

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

  • 'https://docs.google.com/spreadsheets/d/'
    これは Google スプレッドシートのファイルにアクセスするための共通のパスです。スプレッドシートのIDをこのあとに続けることで、個別のファイルを指定します。
  • tempSS.getId()
    一時的に作成したスプレッドシートの ユニークなID(ファイルID) を取得しています。このIDは、Googleドライブ上で各スプレッドシートに自動的に割り当てられており、URLに組み込むことで対象のファイルを特定できます。
  • '/export?format=xlsx'
    この部分は、そのファイルをダウンロード可能な形式で取得するための指示です。ここでは format=xlsx を指定しているため、Excelファイル(.xlsx)として出力されます。

このURLを構築することで、スプレッドシートをExcelファイルとして出力できる仕組みが整います。このあと実行される処理で、このURLを使って実際にファイルを取得します。

  // 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()
    指定したURLに対して、HTTPリクエストを送信し、その結果(レスポンス)を取得する関数です。ここでは exportUrl にアクセスし、Excelファイルを取得しています。
  • headers: { Authorization: 'Bearer ...' }
    この headers は、HTTPリクエストに付け加える追加情報をまとめるための設定です。 その中の Authorization は、リクエストの送り手が正規のユーザーであることを示す役割を担います。ここでは、ScriptApp.getOAuthToken() を使って、スクリプトを実行しているユーザーのアクセストークンを取得し、それを Bearer(ベアラー)という形式で指定しています。「Bearer」とは、「このトークンを持っている人にはアクセスを許可する」という認証方式のことです。このようにして、Googleドライブ上の非公開ファイルにも、スクリプトから安全にアクセスできるようになります。
  • .getBlob()
    取得したファイルの内容を「Blob(バイナリ・ラージ・オブジェクト)」として受け取ります。これは、画像やファイルなどの“中身そのもの”をバイナリ形式で扱うためのデータ構造です。
  • .setName(...)
    取得した Blob にファイル名を付けています。ここでは、元のシート名の先頭に Export_ を付けて、Excel ファイルの名前としています。

このようにして、取得したファイルデータをプログラム内で扱える状態にし、以降の処理で保存や表示に利用できるようにしています。

  // 元スプレッドシートと同じフォルダに保存(フォルダがない場合はルート)-----------------------
  // ssFile・・・Spredsheet File
  const ssFile     = DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId());
  const parents    = ssFile.getParents();
  const destFolder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
  const excelFile  = destFolder.createFile(blob);
  //--------------------------------------------------------------------------------------

ここでは、生成された Excel ファイルを Google ドライブ上に保存する処理を行っています。具体的には、次のステップで構成されています。

  • const ssFile = ...
    DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()) を使って、現在開いているスプレッドシート自体のファイルオブジェクトを取得しています。これは、生成した Excel ファイルを同じフォルダに保存するため、現在のスプレッドシートがどこに保存されているかを知る必要があるためです。
  • const parents = ...
    ssFile.getParents() によって、このスプレッドシートが所属する Google ドライブ上のフォルダ(親フォルダ)を取得します。このメソッドの戻り値は FolderIterator という特殊なオブジェクトで、.hasNext().next() を使って順番にフォルダを取り出せる仕組みになっています。これは、Google ドライブのファイルが複数のフォルダに所属できるという仕様に対応するためです。
  • const destFolder = ...
    ここでは、「条件 ? 真の場合 : 偽の場合」という形式の三項演算子を用いて、保存先を1行で簡潔に切り替えています。
    parents.hasNext() で親フォルダが存在するかどうかを確認し、あれば parents.next() でそのフォルダを取得します。存在しない場合(たとえばマイドライブ直下にある場合)は、DriveApp.getRootFolder() によってマイドライブのルートを保存先としています。こうすることで、保存先のフォルダが確実に指定されるようになっています。
  • const excelFile = ...
    destFolder.createFile(blob) によって、先ほど取得した Excel ファイルのバイナリデータ(blob)を、指定されたフォルダ内に新しいファイルとして保存します。ここで実際に、ファイルが Google ドライブ上に書き出される処理が実行されます。
  // 念のため:ファイル操作系の反映を確実にする
  SpreadsheetApp.flush();  

ここでは、SpreadsheetApp.flush() を呼び出すことで、バッファリングされた変更を即座に反映させています。Google Apps Script は、一部の処理(とくに UI やファイル操作など)を最適化のために遅延させることがあります。flush() を使うことで、それまでに加えられた変更を強制的に反映させ、以降の処理で不整合が起きないようにしています。特に、ファイルの保存や削除といった操作の前後に呼ぶと安全性が高まります。

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

ここでは、一時的に作成したスプレッドシート(tempSS)が役割を終えたため、削除しています。

DriveApp.getFileById(tempSS.getId()) によって一時ファイル(tempSS)を取得し、その後 .setTrashed(true) を呼び出すことで、Google ドライブのゴミ箱に送られます。完全に削除されるわけではなく、あくまで「削除候補」として一時的に退避される処理です。スクリプトの途中で作成した一時ファイルをこのように整理しておくことで、不要なファイルが残らず、ドライブの管理もスムーズになります。

  // 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, 'ファイルをダウンロード');
}

ここでは、作成された Excel ファイルをダウンロードできるように、ダイアログを表示しています。具体的には、次のステップで構成されています。

  • const fileId = ...
    先ほど Google ドライブに保存した Excel ファイル(excelFile)から、そのファイル固有の ID を取得します。この ID は、Google ドライブ上で各ファイルに自動的に割り当てられている一意の識別子です。以降の処理では、この ID を使ってファイルの場所を特定し、ダウンロード用のリンクを生成します。
  • const downloadUrl = ...
    取得したファイル ID を使って、直接ダウンロード可能な URL を作成します。この形式の URL(uc?export=download)を使うことで、ユーザーがリンクをクリックした際に、Google ドライブのプレビュー画面を経由せず、すぐにファイルがダウンロードされるようになります。
  • const htmlContent = ...
    ダウンロード用リンクを含んだ HTML を文字列として構築しています。ここでは、ファイル名とともに「▶ ダウンロード」というリンクテキストを挿入し、ユーザーが視覚的にリンクだとわかるようにしています。
  • const html = ...
    作成した HTML 文字列をダイアログ表示用のオブジェクトに変換し、ウィンドウの幅と高さを指定しています。ここで作成されたオブジェクトが、最終的に画面上に表示されるダイアログの内容となります。
  • SpreadsheetApp.getUi().showModalDialog(html, 'ファイルをダウンロード');
    作成した HTML ダイアログを、スプレッドシートの画面上にモーダル(前面固定)として表示します。ユーザーはここに表示されるリンクをクリックすることで、先ほど生成した Excel ファイルを自分のパソコンにダウンロードできます。

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

運営者・ポテ

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

おわりに

運営者・ポテ

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

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

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

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

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

この記事を書いた人

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

コメントを残す

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