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


いつもありがとうございます!
ノンプログラマー向け「GAS(Google Apps Script)解説シリーズ」へようこそ。
本稿では「GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法」を解説いたします。
データの規模が大きい場合や、GAS では対応しきれない高度で柔軟な処理を行いたい場合、スプレッドシートをローカルにダウンロードして、VBA などで扱いたくなることがあります。
そのようなときには、Google スプレッドシートが提供している Microsoft Excel 形式でのダウンロード機能を利用するのが一般的です。ファイルメニューから数クリックで実行でき、操作もとても簡単です。

ただし、スプレッドシートに設定されている関数が複雑だったり、データ量が多かったりする場合には、ダウンロードした Excel ファイルが破損して正しく開けないことがあります。そうした場面で有効なのが、今回ご紹介するスクリプトです。
このスクリプトは、次のような流れで動作します。
- アクティブなシートの表示値をプレーンテキストとしてコピーし、.xlsx 形式で元のスプレッドシートと同じフォルダに自動保存します。
- その後、画面にダウンロード用のダイアログを表示し、リンクをクリックすることで、ファイルをローカルのダウンロードフォルダに保存します。
本稿が、あなたのアプリケーションの価値をさらに高める一助となれば幸いです。GAS(Google Apps Scripts)を活用して、自分自身や身近なコミュニティに合ったアプリケーションを作成し、仕事量は半分に、成果は2倍にしていきましょう!成果を増やす!
初心者の方でも理解できるように、わかりやすく、丁寧に解説していきます。ぜひご覧ください。
GASで「GoogleスプレッドシートをプレーンテキストのExcelファイルでローカルにダウンロードする方法」

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

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

冒頭のセクションの繰り返しになりますが、今回ご紹介するアプリは次のような流れで動作します。
- アクティブなシートの表示値をプレーンテキストとしてコピーし、.xlsx 形式で元のスプレッドシートと同じフォルダに自動保存します。
- その後、画面にダウンロード用のダイアログを表示し、リンクをクリックすることで、ファイルをローカルのダウンロードフォルダに保存します。

次のセクションでは、この処理を実現するスクリプトの具体的な内容を解説していきます!
おおまかな処理の流れ
このアプリケーションの大まかな流れは以下の通りです。各ステップの詳細は、次のセクションで解説していきます。
├ onOpen
│ └─ メニュー「スクリプトの実行」を作成し、「エクスポート」を追加
└ exportSheetAsExcel
├ スプレッドシートの表示値を取得
├ 一時スプレッドシートを作成して表示値を貼り付け
├ 一時スプレッドシートを元に、サーバー側に Excel 形式で出力するための URL を構築
│ ※マイドライブに直接 Excel を出力できないため
├ URLからExcelファイルの中身(バイナリデータ)を取得し、Blob形式に変換
│ ※Excelファイルを直接取得できないため
├ BlobをExcelファイルに変換し、スプレッドシートと同じフォルダに保存
├ 一時スプレッドシートをゴミ箱へ移動
└ エクセルのダウンロードリンクをHTMLダイアログで表示
コードの実装

まず、コード全文を示します。
/**
* スプレッドシートを開いたときにカスタムメニューを追加する。
* メニュー「スクリプトの実行」から 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, 'ファイルをダウンロード');
}
次に、このコードの基本的な動作を説明します。
このコードは、スプレッドシートに追加されたカスタムメニューから実行します。メニュー「スクリプトの実行」から「エクスポート」をクリックすると、処理が開始されます。

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

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

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

ダウンロードされたファイルでは、数式が削除され、表示されていた値のみが残ります。たとえば、D2セルには元々「=C2*0.8
」と数式が入力されていましたが、いダウンロードされたされたExcelファイルでは計算結果の「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)」に掲載)