Amazonで商品を見るセール会場へ

Figmaの情報をGoogleスプレッドシートに出力する方法|GAS・REST API・セクション指定

Figmaのコンポーネントやインスタンスを一覧にするには、REST APIでファイルのノードを取得し、Google Apps Script(GAS)で行データへ変換します。名前、node ID、部品のキー、文字情報を並べれば、デザインの棚卸しに使えます。

最初は小さなファイルか、特定のセクションを対象にしてください。ファイル全体の取得はデータ量とAPIの制限に影響されます。この記事では、外部ライブラリを使わずに取得する例と、従来のFigmaSheetライブラリを使う例を分けます。

目次

用意するものと取得できる範囲

用意するもの用途
Googleスプレッドシートと編集権限一覧の出力先
スプレッドシートに紐づくGASAPIの呼び出しと行の生成
FigmaのPATfile_content:readでファイル内容を取得
ファイルキー/design/ファイルキー/の部分
セクション等のnode ID(任意)取得範囲を絞る

REST APIのノード情報は、デザインの見た目をそのまま表へ移す機能ではありません。ローカルのPlugin APIと取得できる情報が異なり、参照先部品の情報が常にすべて入るとも限りません。REST APIとPlugin APIの違い

次の画像は旧FigmaSheet実装による2025年12月の出力例です。後述の独立したGAS例を新たに実行した画面ではありません。

スクリプトを実行してスプレッドシートに出力されたFigmaの情報一覧。
2025年12月の旧画面・旧版の参考画像。現在のUIや改稿コードの実行結果とは区別してください。

PATとファイルキーを設定する

  1. スプレッドシートの拡張機能 → Apps Scriptを開きます。
  2. プロジェクトの設定でスクリプトプロパティを追加します。
  3. FIGMA_TOKENにPAT、FIGMA_FILE_KEYにファイルキーを保存します。
  4. 範囲を絞る場合はFIGMA_NODE_IDSに123:456,789:1011のようなnode IDを保存します。

PATの作成は個人アクセストークンの取得とスコープを参照してください。プロパティにはトークンを置き、ソースコードや実行ログへ値を記載しません。スクリプトプロパティは同じプロジェクトのコードから読み取れるため、プロジェクトを編集できる人も確認してください。

node IDはAPI用の123:456形式を使います。画面のリンクにnode-id=123-456とある場合は区切りを確認してください。シートで数字の自動変換を防ぐための先頭アポストロフィは、APIへ渡すIDには付けません。ファイルとノードの取得仕様

Google Apps ScriptのスクリプトプロパティにFIGMA_TOKENを保存した旧画面。値は伏せられています。
2025年12月のGAS設定画面。改稿したコードの実行結果ではありません。

外部ライブラリを使わないGASの最小例

新しいシート名Figma取得結果へ、コンポーネント・コンポーネントセット・インスタンス・テキストを出力します。同名シートがある場合は、取得と解析が終わってから内容を更新します。既存の業務表とは別のスプレッドシートで試してください。

function exportFigmaNodes() {
  const props = PropertiesService.getScriptProperties();
  const token = props.getProperty('FIGMA_TOKEN');
  const fileKey = props.getProperty('FIGMA_FILE_KEY');
  const ids = (props.getProperty('FIGMA_NODE_IDS') || '')
    .split(',').map(s => s.trim()).filter(Boolean);
  if (!token || !fileKey) throw new Error('トークンとファイルキーを設定してください');
  if (ids.some(id => !/^\d+:\d+$/.test(id))) {
    throw new Error('node IDは123:456形式で指定してください');
  }
  const base = 'https://api.figma.com/v1/files/' + encodeURIComponent(fileKey);
  const url = ids.length ? base + '/nodes?ids=' +
    encodeURIComponent(ids.join(',')) : base;
  const response = UrlFetchApp.fetch(url, {
    headers: { 'X-Figma-Token': token }, muteHttpExceptions: true
  });
  const status = response.getResponseCode();
  if (status !== 200) {
    throw new Error('Figma API HTTP ' + status + '。権限・期限・制限を確認してください');
  }
  const data = JSON.parse(response.getContentText());
  const types = new Set(['INSTANCE', 'COMPONENT', 'COMPONENT_SET', 'TEXT']);
  const rows = [];
  const seen = new Set();
  const safeCell = value => {
    const text = value == null ? '' : String(value);
    return /^[=+@\-\t\r\n]/.test(text) ? "'" + text : text;
  };
  function walk(node, path, components) {
    if (!node || seen.has(node.id)) return;
    seen.add(node.id);
    const nextPath = path.concat(node.name || node.id);
    if (types.has(node.type)) {
      const component = components[node.componentId || node.id] || {};
      const bounds = node.absoluteBoundingBox || {};
      rows.push([node.id, node.type, node.name, nextPath.join(' / '),
        node.componentId || '', component.key || '', node.characters || '',
        bounds.width == null ? '' : bounds.width,
        bounds.height == null ? '' : bounds.height].map(safeCell));
    }
    (node.children || []).forEach(child => walk(child, nextPath, components));
  }
  if (ids.length) {
    ids.forEach(id => {
      const item = data.nodes && data.nodes[id];
      if (!item || !item.document) throw new Error('対象node IDを取得できませんでした');
      walk(item.document, [], item.components || {});
    });
  } else {
    if (!data.document) throw new Error('ファイルのdocumentがありません');
    walk(data.document, [], data.components || {});
  }
  const headers = ['nodeId', 'type', 'name', 'layerPath', 'componentId',
    'componentKey', 'characters', 'width', 'height'];
  const sheetName = 'Figma取得結果';
  const book = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = book.getSheetByName(sheetName) || book.insertSheet(sheetName);
  const values = [headers].concat(rows);
  if (sheet.getMaxRows() < values.length) {
    sheet.insertRowsAfter(sheet.getMaxRows(), values.length - sheet.getMaxRows());
  }
  if (sheet.getMaxColumns() < headers.length) {
    sheet.insertColumnsAfter(sheet.getMaxColumns(), headers.length - sheet.getMaxColumns());
  }
  sheet.clearContents();
  sheet.getRange(1, 1, values.length, headers.length).setValues(values);
  sheet.setFrozenRows(1);
  console.log('出力行数: ' + rows.length);
}

exportFigmaNodesを実行し、初回のGoogle側の承認でアクセス内容を確認します。出力先、node ID、対象数をFigma側と照合してください。このコードは公式の応答構造に基づく例です。2026年10月3日のNode.js上の模擬データで、部品のキーと列の生成、数式として扱われる文字列への対処、429時にシートを書き換えない処理を確認しました。実PATを使う接続やGAS上の実行は未検証です。

特定セクションを取得した旧実装の例です。範囲指定は、ファイル全体の取得よりデータ量を抑えるためにも使えます。

特定のセクションを指定して出力したスプレッドシートの実行結果。
2025年12月の旧画面・旧版の参考画像。現在のUIや改稿コードの実行結果とは区別してください。

既存のFigmaSheetライブラリを利用する場合

従来の公開ライブラリを使う場合は、Apps Scriptのライブラリ追加で次のスクリプトIDを指定し、識別子をFigmaSheetにします。FIGMA_TOKENは認証情報のプロパティ名であり、このライブラリIDとは別です。

1KjcblxtHtWAzr20-1Voztr0RTh-blaHx_BdLxsFuO0nT9CDdpGgsYCxF

追加画面で利用できる版と関数を確認してください。現在の公開権限・利用可能な版・実装全体の挙動は今回再検証できていません。ライブラリが表示されない場合は、上記の独立したGAS例で試せます。Googleのライブラリ追加手順

スクリプトエディタでライブラリを追加しスクリプトIDやバージョンを設定する画面。
2025年12月の旧画面・旧版の参考画像。現在のUIや改稿コードの実行結果とは区別してください。

従来の呼び出しでは、全体取得をFigmaSheet.exportToSheet、範囲指定をFigmaSheet.exportSectionToSheetへ渡します。以下は範囲指定の形です。ファイルキーとIDは利用するファイルの値へ変更します。

function runExportSection() {
  const props = PropertiesService.getScriptProperties();
  const token = props.getProperty('FIGMA_TOKEN');
  const fileKey = props.getProperty('FIGMA_FILE_KEY');
  const sectionIds = ['123:456'];
  const result = FigmaSheet.exportSectionToSheet(fileKey, sectionIds, {
    token: token,
    sheetName: 'Figma情報一覧',
    fields: ['nodeId', 'layerPath', 'componentKey', 'pageName',
      'instanceName', 'componentSetName', 'characters'],
    nodeTypes: ['INSTANCE', 'COMPONENT', 'COMPONENT_SET', 'TEXT']
  });
  console.log(result);
}

旧実装ではmainComponent、バリアント、位置・寸法、塗り、線、文字スタイルなどの列も扱っていました。これはFigmaSheet側で解析している項目で、REST APIの同名プロパティが必ず直接返るという意味ではありません。使う版の実装と対象ファイルで確認します。

コンポーネントの種類や項目などの条件を細かく指定して出力した一覧。
2025年12月の旧画面・旧版の参考画像。現在のUIや改稿コードの実行結果とは区別してください。

大きなファイル・エラー・列の不足への対応

状況対応
401・403PATの期限、Required scopes、ファイル権限を確認
429再実行を止め、Retry-AfterとFigmaの制限を確認
応答が大きい・実行時間を超えるセクションを指定し、複数回に分ける
コンポーネントのキーが空欄応答のcomponents情報と参照先の条件を確認
一部の文字情報が不足RESTで取得した文字とスタイルの表現を確認
Libraryの関数が見つからない識別子、利用版、公開権限を確認

GASのURL Fetchには応答サイズ、実行時間、日次呼び出し数などの制限があります。現在の公式表では応答サイズは1回50MB、通常のスクリプト実行は1回6分です。Figma側のレート制限も併せて設計し、再取得前にキャッシュや変更有無を検討してください。GASの制限、Figmaの制限

旧ライブラリの設計は、公開関数で認証・取得方法・キャッシュを管理し、API通信、JSON解析、シート書き込みを分ける構成でした。既存の呼び出し例も残しています。GitHubのフォルダーは呼び出し例を掲載したもので、公開ライブラリの実装全体が含まれているとは限りません。

Figma上で外部スタイルを調べる場合はPlugin APIによるCSV抽出を参照してください。

サービス

Service

デザイン制作に関心がありましたら、ぜひ詳細をご覧ください。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Figmaのおすすめ書籍

Figma用PCの選び方

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次