ChatGPTでスプレッドシートの文章を自動生成する方法【30分で完成】
この記事ではGoogleスプレッドシートとChatGPT APIを使って文章を自動で作成する仕組みを作ります。難しい知識は必要ありません。手順どおりに進めれば約30分で「スプレッドシートに入力した内容からChatGPTが自動で文章を作成する仕組み」を完成させることができます。
1. この記事でできること
今回のゴールはとてもシンプルです。スプレッドシートのA列に「題材(例:商品名、記事テーマ)」、B列に「トーン(例:やさしい、営業向け)」を入力すると、数秒後にChatGPTが内容に合わせた文章を生成し、C列へ自動で書き込まれる仕組みを作ります。
一度設定してしまえば、その後は題材とトーンを入力するだけで文章を自動生成できるようになります。記事の下書きや商品紹介文など、繰り返し行う文章作成を大幅に効率化できます。なお、Googleのサービスは無料で利用できますがChatGPT APIは2026年時点でクレジットカードの登録が必要です(後ほど詳しく説明します)。
2. 今回作る自動化の仕組みの全体像
今回作る仕組みは、次のような流れで動きます。
- スプレッドシートに題材とトーンを入力する
- 編集を検知するトリガーが自動で実行される
- Google Apps Script(GAS)がChatGPT APIへリクエストを送る
- 生成された文章がC列へ自動で入力される
トリガーを設定することでボタンを押さなくても入力をきっかけに自動で処理が始まります。まずは仕組みを動かすことを目標に、一つずつ進めていきましょう。
3. 事前に必要なアカウント・準備物
| 項目 | 用途 | 登録・取得するもの | 料金/必要情報 |
|---|---|---|---|
| Googleアカウント | スプレッドシートとGASの利用 | Googleアカウントのログイン | 無料 |
| スプレッドシート | 題材の管理と出力の保存 | 新規スプレッドシート | 無料(Google Drive内) |
| OpenAI(ChatGPT)アカウント | 文章生成(API経由) | APIキーの発行 | API利用はクレカ登録が必要。少額から利用可 |
補足しておくと普段ブラウザで使っているChatGPTだけではこのような自動化はできません。今回は外部サービスからChatGPTを利用するため、OpenAIのAPIキーを使用します。ChatGPTの画面とAPIは別のサービスなのでこの点は間違えやすいポイントです。
4. 必要なツール、アカウントの設定
4-1. スプレッドシートの雛形を作る(3分)
まずはGoogle Driveで新しいスプレッドシートを作成し、シート名を「AI生成」など分かりやすい名前に変更します。続いて、1行目に以下の見出しを入力してください。
- A1: 題材
- B1: トーン
- C1: 出力(自動)

今回は必要最低限の構成で進めます。出力先をC列に固定しておくことで、後からコードの内容も理解しやすくなります。また、「表示」→「固定」→「1行」を選択しておくと、見出しが常に表示されるため作業しやすくなります。
4-2. OpenAI(ChatGPT)APIキーを取得(5〜10分)
- OpenAIにログインし、APIの管理画面を開きます。
- 左メニューの「API keys」→「Create new secret key」を選択し、新しいAPIキーを作成します。表示されたキー(sk-から始まる文字列)はあとで使うので、安全な場所へ保存してください。


- 「Billing」からクレジットカードを登録します。無料トライアルが提供されていない期間は、この登録がないとAPIを利用できません。
APIキーは自分のアカウントを識別するための重要な情報です。パスワードと同じように扱い、他人へ共有したり公開したりしないよう注意してください。
この記事ではコストを抑えながら十分な性能を持つ「gpt-4o-mini」を利用します。簡単なテストであれば数円〜数十円程度で試せるケースがほとんどです。
4-3. Apps Script(GAS)の準備(5分)
- スプレッドシートで「拡張機能」→「Apps Script」を開きます。

- プロジェクト名を「ChatGPT_自動生成」などに変更します。
- コードエディタへ、下記のコードをそのまま貼り付けて保存してください。
// ========= 設定ここから =========
const MODEL_NAME = 'gpt-4o-mini'; // 低コストで十分高品質
const OUTPUT_CHAR_HINT = '150〜200字'; // 出力の目安
// ========= 設定ここまで =========
/** 初期設定:既存トリガー削除→onEditトリガー作成 */
function setup() {
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('handleEdit')
.forSpreadsheet(SpreadsheetApp.getActive())
.onEdit()
.create();
SpreadsheetApp.getUi().alert('初期設定が完了しました。シートを編集すると自動生成されます。');
}
/** メニュー追加 */
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('AI生成')
.addItem('初期設定(トリガー作成)', 'setup')
.addItem('選択行を手動生成', 'generateSelected')
.addToUi();
}
/** 編集トリガー本体(インストール型) */
function handleEdit(e) {
try {
const range = e && e.range;
if (!range) return; // 念のため
const sheet = range.getSheet();
const row = range.getRow();
const col = range.getColumn();
if (row === 1) return; // 見出し行は無視
if (col > 2) return; // A/B列の変更だけ反応
generateRow_(sheet, row);
} catch (err) {
console.error(err);
}
}
/** 選択行をまとめて生成(手動実行用) */
function generateSelected() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getActiveRange();
const start = range.getRow();
const end = start + range.getNumRows() - 1;
for (let r = start; r <= end; r++) {
if (r === 1) continue; // 見出しスキップ
generateRow_(sheet, r);
}
}
/** 指定行を生成 */
function generateRow_(sheet, row) {
const lock = LockService.getDocumentLock();
lock.waitLock(20 * 1000);
try {
const topic = sheet.getRange(row, 1).getValue(); // A:題材
const tone = sheet.getRange(row, 2).getValue() || 'やさしい'; // B:トーン
if (!topic) return; // 題材が空なら何もしない
// すでに出力済みなら上書きしない(必要なら消して再入力)
const outCell = sheet.getRange(row, 3);
const existing = (outCell.getValue() + '').trim();
if (existing) return;
outCell.setValue('生成中…');
const prompt = buildPrompt_(topic, tone);
const result = callChatGPT_(prompt);
outCell.setValue(result);
} catch (err) {
sheet.getRange(row, 3).setValue('エラー: ' + err.message);
console.error(err);
} finally {
lock.releaseLock();
}
}
/** プロンプト(指示文)を作る */
function buildPrompt_(topic, tone) {
return [
'あなたは日本語のライティングアシスタントです。',
`次の題材について${OUTPUT_CHAR_HINT}の紹介文を作成してください。`,
'要件:',
'- 結論を先に書く',
'- 箇条書きは使わない',
'- 固有名詞の誤りに注意',
`- トーン: ${tone}`,
`題材: ${topic}`
].join('\n');
}
/** OpenAI Chat Completions API を呼び出す */
function callChatGPT_(userPrompt) {
const apiKey = PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY');
if (!apiKey) throw new Error('APIキー未設定(プロジェクトのプロパティに OPENAI_API_KEY を保存)');
const url = 'https://api.openai.com/v1/chat/completions';
const payload = {
model: MODEL_NAME,
messages: [
{ role: 'system', content: 'あなたは正確で簡潔な日本語ライターです。' },
{ role: 'user', content: userPrompt }
],
temperature: 0.7,
max_tokens: 600
};
const res = UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + apiKey },
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
const code = res.getResponseCode();
const text = res.getContentText();
if (code >= 300) {
throw new Error('OpenAIエラー ' + code + ': ' + text);
}
const data = JSON.parse(text);
return data.choices[0].message.content.trim();
}
このコードではスプレッドシートの編集を検知し、入力された題材とトーンからChatGPTへリクエストを送信し、その結果をC列へ自動で書き込みます。また複数の処理が同時に動いた場合の競合を防ぐロック処理や、エラー発生時の処理もあらかじめ組み込んでいます。
4-4. APIキーをGASに安全に保存(2分)
- Apps Script画面左の「歯車」→「プロジェクトの設定」を開きます。
- 「スクリプトのプロパティ」で「スクリプト プロパティを追加」をクリックします。
- プロパティ名に「OPENAI_API_KEY」、値に取得したAPIキー(sk-で始まる文字列)を入力して保存します。

APIキーをコードへ直接書いてしまうと誤って公開してしまうリスクがあります。スクリプトプロパティへ保存しておけば安全に管理できます。
4-5. 初回実行で承認&トリガー作成(2分)
- Apps Script上部の関数一覧から「setup」を選択し、実行します。

- Googleの承認画面が表示されたら、内容を確認して許可してください。

- 「初期設定が完了しました」と表示されれば設定完了です。

初回だけはGoogleからアクセス権限の承認を求められます。一度許可すればその後は毎回承認する必要はありません。もし途中でエラーになった場合は再度「setup」を実行してみてください。
5. 自動化ツールの設定
ここでは実際に動作を確認します。行うことは次の2つだけです。
- テスト用のデータを入力する
- 必要に応じて手動実行で動作を確認する
まずは以下のような内容を入力してください。
- A2: 無印良品の方眼ノート / B2: ていねい
- A3: 社内報の巻頭あいさつ / B3: フレンドリー

入力後、数秒でC列へ文章が表示されれば成功です。もし何も起こらない場合は「AI生成」→「選択行を手動生成」を実行してみてください。ここで動作すればコードではなくトリガー設定に原因があると判断できます。
6. 動作確認(実際の質問例)
標準では紹介文を作成する設定になっていますが、題材やトーンを変更すればさまざまな用途で活用できます。
- 例1)A: 新作ハンドドリップコーヒーの紹介 / B: 温かみのある
- 例2)A: 月次レポートのメール本文(要件: 指標と次アクションを先に) / B: 端的に
- 例3)A: ECサイトの返品案内(優しい印象に) / B: ていねい

B列には文章の雰囲気を指定するイメージで入力します。A列には細かな条件を書いても問題ありませんが、最初はシンプルな内容で試したほうが安定して動作します。もし「生成中…」のまま止まってしまう場合は、C列を空にしてからA列またはB列を編集し直してみてください。
7. うまく動かないときのチェックポイント
- APIキー未設定エラー:C列に「APIキー未設定」と表示された場合は、プロジェクトのプロパティへOPENAI_API_KEYが正しく登録されているか確認してください。
- 401 Unauthorized:APIキーが間違っている、または無効になっています。新しいキーを発行して設定し直してください。
- 429 Too Many Requests:短時間に大量のリクエストを送っています。少し時間を空けてから再度実行してください。
- トリガーが動かない:Apps Scriptの「トリガー」画面でhandleEditが作成されているか確認し、なければsetupを再実行してください。
- 権限不足:Googleの承認が完了していない可能性があります。setupをもう一度実行して承認してください。
- モデル名エラー:MODEL_NAMEには存在するモデル名を指定する必要があります。この記事ではgpt-4o-miniを使用してください。
- 文章が途中で切れる:max_tokensの値が小さい可能性があります。600程度に設定しておくと安心です。
- 会社PCで動かない:社内ネットワークで外部APIへの通信が制限されている場合があります。自宅環境などで試してみてください。
- タイムアウト:一度に大量の行を処理すると時間切れになることがあります。数行ずつ実行すると安定します。
エラーの原因を詳しく調べたい場合はApps Scriptの「実行ログ」を確認してください。表示されたエラーメッセージをそのまま検索すると解決方法が見つかることも多いです。
8. 次にできる改善アイデア
- テンプレ列の追加:D列に「紹介文」「要約」「メール」などの出力形式を指定できるようにする。
- 文字数を変更できるようにする:E列で希望文字数を指定できるようにする。
- 利用回数を制限する:1日の生成回数を管理して使いすぎを防ぐ。
- 品質を安定させる:systemメッセージへ禁止事項やルールを追加する。
- まとめて生成する:時間トリガーを利用して未生成データを定期的に処理する。
- モデルを切り替える:MODEL_NAMEをシートから読み込み、用途に応じて使い分ける。
まずは今回の仕組みを動かしてみることが大切です。基本ができれば用途に合わせて少しずつ機能を追加し、自分だけの自動化ツールへ育てていけます。
費用と安全面の補足:
- APIの利用料金は実行回数や生成する文章量によって変わります。まずは少ない件数で試し必要に応じて利用量を調整しましょう。
- APIキーは第三者へ公開せず、コードへ直接記載しないようにしてください。
ここまで設定できればChatGPTを使った文章生成の自動化は完成です。ぜひ日々の業務や記事作成に活用してみてください。