GASでスプレッドシートを
CSVファイルに出力・保存する方法

スプレッドシートのデータを他システムに渡すには、CSV(値をカンマで区切ったテキスト形式)での書き出しが定番です。 GASなら値のCSV化・エスケープ・文字化け対策・ドライブ保存・メール添付・定期実行まで、Utilities.newBlobを軸に自動化できます。

|対象: GAS / スプレッドシート / CSV出力

Table of Contents

CSV出力が必要になる場面

スプレッドシートは便利ですが、他システムはCSVでのやり取りを前提にしていることが多くあります。 GASでCSV出力を自動化すると、以下のような場面で手作業のダウンロードが不要になります。

会計・給与ソフトへの取り込み

売上や勤怠のデータを、会計ソフトが読めるCSV形式に整えて渡す

ECモール・広告への商品登録

商品マスタを各サービス指定のCSVフォーマットで書き出す

定期バックアップ

スプレッドシートの内容を毎日CSVでドライブに残し、履歴を残す

他部署・取引先への共有

編集権限を渡さず、その時点のデータだけをCSVで配布する

シートをCSV文字列に変換する基本コード

まずは考え方の骨格です。getDataRange().getValues()でシート全体を二次元配列として取得し、各行をカンマで、行同士を改行でつなぐとCSV文字列になります。 1セルずつの変換は次のtoCsvCellに任せます。

// シート全体をCSV文字列に変換する
function sheetToCsv(sheet) {
  const values = sheet.getDataRange().getValues();
  return values
    .map((row) => row.map(toCsvCell).join(","))
    .join("\r\n"); // CSVの改行はCRLFが無難
}

改行コードはCRLF(\r\n)にしておくと、 Excelなど多くのアプリで安定して開けます。

カンマ・改行・引用符を安全にエスケープする

単純にカンマでつなぐだけだと、セルの中にカンマや改行が入っていた瞬間に列がずれます。 CSVのルールでは、カンマ・改行・ダブルクオートを含む値は全体をダブルクオートで囲み、 値の中のダブルクオートは2個重ねて(" → "")エスケープします。

// 1セルをCSVの1項目に変換する(エスケープ処理)
function toCsvCell(value) {
  // null/undefined や日付・数値も文字列に揃える
  let s = value === null || value === undefined ? "" : String(value);

  // カンマ・改行・ダブルクオートを含むなら " で囲む
  if (/[",\r\n]/.test(s)) {
    s = '"' + s.replace(/"/g, '""') + '"'; // 内側の " は "" に
  }
  return s;
}

住所や問い合わせ本文など、カンマ・改行が混ざりやすい列を扱うときは、この処理が必須です。

文字化けを防ぐBOM付きUTF-8で保存する

GASが出力するCSVはUTF-8です。ところがExcelはBOM(文字コードを示す先頭の目印)が無いUTF-8をうまく判別できず、 日本語が文字化けすることがあります。CSV文字列の先頭にBOM()を付けてから保存すると、多くの環境で正しく開けます。

// CSVをBOM付きUTF-8でGoogleドライブに保存する
function exportSheetAsCsv() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上データ");
  const bom = "\uFEFF"; // ExcelでUTF-8を正しく開くための目印
  const csv = bom + sheetToCsv(sheet);

  const fileName = "売上データ_" + formatToday() + ".csv";
  const blob = Utilities.newBlob(csv, "text/csv", fileName); // 既定でUTF-8

  const folder = DriveApp.getFolderById("ここにフォルダIDを入れる");
  folder.createFile(blob);
}

function formatToday() {
  return Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyyMMdd");
}

Utilities.newBlobは既定でUTF-8として文字列をファイル化します。ファイル名に日付を入れておくと、世代管理がしやすくなります。

必要な列だけを書き出す

全列ではなく特定の列だけをCSVにしたいこともあります。 出力したい列のインデックス(0始まり)を配列で渡し、各行からその列だけを取り出します。 個人情報の列を除外したい、公開用に一部だけ書き出したいときに便利です。

// 指定した列だけをCSVにする(colIndexesは0始まり)
function selectedColumnsToCsv(sheet, colIndexes) {
  const values = sheet.getDataRange().getValues();
  return values
    .map((row) => colIndexes.map((i) => toCsvCell(row[i])).join(","))
    .join("\r\n");
}

// 使用例: A列(0)・B列(1)・D列(3)だけを書き出す
function exportSelectedColumns() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("会員リスト");
  const csv = "\uFEFF" + selectedColumnsToCsv(sheet, [0, 1, 3]);
  const blob = Utilities.newBlob(csv, "text/csv", "会員リスト_public.csv");
  DriveApp.getFolderById("フォルダID").createFile(blob);
}

CSVをメール添付して定期実行する

作ったCSVは、ドライブ保存だけでなくGmailの添付ファイルとして送れます。GmailApp.sendEmailattachmentsにBlobを渡すだけです。

// CSVをGmailに添付して送る
function mailCsv() {
  const sheet = SpreadsheetApp.getActive().getSheetByName("売上データ");
  const csv = "\uFEFF" + sheetToCsv(sheet);
  const fileName = "売上データ_" + formatToday() + ".csv";
  const blob = Utilities.newBlob(csv, "text/csv", fileName);

  GmailApp.sendEmail("send-to@example.com", "月次売上CSV", "添付のCSVをご確認ください。", {
    attachments: [blob],
  });
}

あとは時間主導トリガーを設定すれば、毎月1日など決まったタイミングで自動送信できます。 月次レポートやバックアップに向いています。

// 毎月1日の朝6時台に自動でCSVをメール送信する
function createMonthlyCsvTrigger() {
  ScriptApp.newTrigger("mailCsv")
    .timeBased()
    .onMonthDay(1)
    .atHour(6)
    .create();
}

実務での注意点

1. 日付・数値の見え方に注意する

getValues()は日付をDateオブジェクト、数値を数値型で返します。String()での変換だと表示がずれる場合があるため、 日付はUtilities.formatDateで整形し、金額はgetDisplayValues()で見た目どおりの文字列を使う、といった調整を検討します。

2. Shift_JIS指定のシステム向けは要確認

取り込み先が文字コードShift_JISを要求する場合、BOM付きUTF-8では読めないことがあります。 まずはBOM付きUTF-8で試し、指定がある場合のみ相手のフォーマット要件に合わせてください。

3. 大量データは実行時間制限に注意

数万行を超えるシートでは処理に時間がかかり、GASの6分制限に達することがあります。 getValues()での一括取得を基本にしつつ、行数が多い場合は分割出力も検討しましょう。

まとめ

GASでのCSV出力は、値のCSV化・エスケープ・BOM付きUTF-8での保存という3点を押さえれば、 文字化けや列ずれのない実務レベルのファイルを作れます。 ドライブ保存やGmail添付、定期トリガーと組み合わせれば、他システムへのデータ受け渡しを丸ごと自動化できます。

よくある質問

getDataRange().getValues()で全データを二次元配列として取得し、各行をカンマで連結して改行でつなぐとCSV文字列になります。あとはUtilities.newBlobでBlob(ファイルの中身を表すオブジェクト)にし、DriveApp.createFileでGoogleドライブに保存すれば完成です。ただしカンマや改行を含むセルはエスケープが必要です。

GASが出力するCSVはUTF-8です。Excelは先頭にBOM(文字コードを示す目印)が無いUTF-8をうまく判別できず文字化けすることがあります。CSV文字列の先頭にBOM(\uFEFF)を付けてから保存すると、多くの環境で正しく開けます。

CSVではカンマ・改行・ダブルクオートを含む値は、全体をダブルクオートで囲み、値の中のダブルクオートは2個重ねてエスケープするのがルールです。1セルずつこの処理を通す関数を用意すれば、住所や自由記述が入っていても列がずれません。

出力したい列のインデックス(0始まり)を配列で指定し、各行からその列だけを取り出してCSV化します。個人情報の列を除外したい、公開用に一部の列だけ書き出したいといったケースで役立ちます。

できます。時間主導トリガー(ScriptApp.newTriggerのonMonthDayやeveryDays)を使えば、毎月1日や毎日決まった時刻にCSVを出力してドライブ保存やメール送信まで自動化できます。月次の売上データやログのバックアップに向いています。

GAS開発・業務Webシステムを
相談する。

CSV出力以外にも、他システムとのデータ連携・帳票出力・Gmail自動化など、日々の業務を自動化するGAS開発をご相談いただけます。

GAS Webシステム開発を見る