OSSスプレッドシート代替比較:Grist vs NocoDB vs Baserow でAirtable・Excelを脱却する
オープンソースラボ編集部 ・ 2026年6月13日
OSSスプレッドシート代替比較:Grist vs NocoDB vs Baserow でAirtable・Excelを脱却する
AirtableのFreeプランは5ワークスペース・1,000レコード制限。ExcelはMicrosoft 365が月1,280円〜。これに対してGrist(TypeScript/Python Formula対応の高機能OSSスプレッドシート)・NocoDB(既存DBをAirtable風UIに変換)・Baserow(オープンソースのAirtable完全代替)はSaaS費用を0にする選択肢です。
OSSスプレッドシート代替を選ぶ理由
- コスト: Airtable Teamプランは$20/ユーザー/月。10名チームで$2,400/年。セルフホストで0円に
- データ主権: 顧客データ・財務データを外部SaaSに預けずに社内サーバーで管理
- カスタマイズ: APIとWebhookで自社システムと深く統合できる
- Airtableからの移行: CSVまたはAPI経由でデータを完全移行できる
主要ツールの概要
Grist
2019年公開、TypeScript製のOSSスプレッドシートです。GitHubスター7k+。Excelライクなグリッド・Pythonベースのフォーミュラ・カード/ガントチャートビュー・アクセスルール・自己ホスト型Cloud Driveを搭載。特にPythonフォーミュラで複雑な計算ロジックを実装できる点が他ツールと差別化されています。
# Grist を Docker Compose でセルフホスト
mkdir grist-data && cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
grist:
image: gristlabs/grist:latest
restart: unless-stopped
ports:
- "8484:8484"
environment:
APP_HOME_URL: https://grist.yourcompany.com
GRIST_SINGLE_ORG: mycompany
GRIST_SESSION_SECRET: your-very-long-secret-key-here
GRIST_HIDE_UI_ELEMENTS: helpCenter
EMAIL_USE_TLS: "true"
# Supabase Authと連携(OIDC)
GRIST_OIDC_IDP_ISSUER: https://ucceyqlkrzojulwyryia.supabase.co/auth/v1
GRIST_OIDC_IDP_CLIENT_ID: your-supabase-client-id
GRIST_OIDC_IDP_CLIENT_SECRET: your-supabase-client-secret
volumes:
- ./grist-data:/persist
EOF
docker compose up -d
# Grist Python フォーミュラ(スプレッドシート内で動作)
# セルにPythonフォーミュラを入力してリッチな計算を実装
# 売上予測フォーミュラ(トレンド回帰)
import statistics
def calculate_forecast(monthly_sales):
'''過去12ヶ月のデータから3ヶ月先を予測'''
if len(monthly_sales) < 3:
return None
n = len(monthly_sales)
x_vals = list(range(n))
x_mean = statistics.mean(x_vals)
y_mean = statistics.mean(monthly_sales)
# 線形回帰の傾き
numerator = sum((x - x_mean) * (y - y_mean) for x, y in zip(x_vals, monthly_sales))
denominator = sum((x - x_mean) ** 2 for x in x_vals)
slope = numerator / denominator if denominator != 0 else 0
intercept = y_mean - slope * x_mean
# 3ヶ月後の予測値
return slope * (n + 2) + intercept
# GristフォーミュラでAirtableのLOOKUP的な検索
# =VLOOKUP($ProductCode, Products.all, "Price") # Grist の lookup 構文
// Grist API で外部システムからデータを操作
const GRIST_URL = 'https://grist.yourcompany.com'
const API_KEY = process.env.GRIST_API_KEY
// ドキュメント一覧を取得
async function listDocuments(orgId: string) {
const res = await fetch(`${GRIST_URL}/api/orgs/${orgId}/workspaces`, {
headers: { Authorization: `Bearer ${API_KEY}` },
})
const workspaces = await res.json()
return workspaces.flatMap((ws: any) => ws.docs)
}
// テーブルのレコードを取得
async function fetchRecords(docId: string, tableId: string) {
const res = await fetch(
`${GRIST_URL}/api/docs/${docId}/tables/${tableId}/records`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
)
return (await res.json()).records
}
// レコードを追加/更新(upsert)
async function upsertRecords(
docId: string,
tableId: string,
records: Array<{ fields: Record<string, any> }>
) {
const res = await fetch(
`${GRIST_URL}/api/docs/${docId}/tables/${tableId}/records`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ records }),
}
)
return res.json()
}
// 使用例: 外部APIのデータをGristに同期
async function syncSalesData() {
const salesData = await fetchExternalSalesAPI()
await upsertRecords('doc123', 'Sales', salesData.map(sale => ({
fields: {
Date: sale.date,
Amount: sale.amount,
Product: sale.product_name,
},
})))
console.log('Gristへの同期完了')
}
NocoDB
2021年公開、TypeScript/Vue製のOSSです。GitHubスター51k+。既存のMySQL・PostgreSQL・SQLite・MariaDBを接続するだけでAirtable風UIが即座に生成されるのが最大の特長。Supabaseのテーブルを直接NocoDBに接続することも可能です。
# NocoDB を既存 Supabase/PostgreSQL に接続
docker run -d --name nocodb -p 8080:8080 -e NC_DB="pg://db.ucceyqlkrzojulwyryia.supabase.co:5432?u=postgres&p=yourpassword&d=postgres" -e NC_AUTH_JWT_SECRET=your-jwt-secret-32chars nocodb/nocodb:latest
# docker-compose.yml での本番構成
cat > docker-compose.yml << 'DCEOF'
version: '3.8'
services:
nocodb:
image: nocodb/nocodb:latest
restart: unless-stopped
ports:
- "8080:8080"
environment:
NC_DB: "pg://postgres:5432?u=nocodb_user&p=${DB_PASSWORD}&d=nocodb_meta"
NC_AUTH_JWT_SECRET: ${JWT_SECRET}
NC_PUBLIC_URL: https://nocodb.yourcompany.com
NC_SMTP_HOST: smtp.sendgrid.net
NC_SMTP_PORT: "587"
NC_SMTP_USERNAME: apikey
NC_SMTP_PASSWORD: ${SENDGRID_API_KEY}
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16
environment:
POSTGRES_USER: nocodb_user
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: nocodb_meta
healthcheck:
test: ["CMD", "pg_isready", "-U", "nocodb_user"]
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
DCEOF
# NocoDB API でレコードを操作(Python SDK)
# pip install requests
import requests
import os
class NocoDBClient:
def __init__(self, base_url: str, api_token: str):
self.base_url = base_url
self.headers = {
'xc-token': api_token,
'Content-Type': 'application/json',
}
def list_records(self, table_id: str, where: str = '', limit: int = 100):
params = {'limit': limit}
if where:
params['where'] = where # NocoDB式: (Name,eq,田中)
resp = requests.get(
f'{self.base_url}/api/v1/db/data/noco/p_multiplayer/{table_id}',
headers=self.headers,
params=params,
)
resp.raise_for_status()
return resp.json()
def create_record(self, table_id: str, data: dict):
resp = requests.post(
f'{self.base_url}/api/v1/db/data/noco/p_multiplayer/{table_id}',
headers=self.headers,
json=data,
)
resp.raise_for_status()
return resp.json()
# 使用例
noco = NocoDBClient('https://nocodb.yourcompany.com', os.environ['NOCODB_API_TOKEN'])
clients = noco.list_records('md_clients', where='(Status,eq,Active)', limit=50)
print(f'アクティブクライアント: {clients["pageInfo"]["totalRows"]}件')
機能比較表
| 比較項目 | Grist | NocoDB | Baserow |
|---|---|---|---|
| Airtable互換UI | △ | ✅ | ✅ |
| 既存DB接続 | ❌ | ✅(Pg/MySQL) | ❌ |
| Pythonフォーミュラ | ✅ | ❌ | ❌ |
| ガントチャート | ✅ | ✅ | ✅ |
| GitHub Stars | 7k+ | 51k+ | 12k+ |
| Webhook対応 | ✅ | ✅ | ✅ |
スプレッドシートのデータをLow-Codeカテゴリ/categories/low-codeのn8n・Budibaseと連携してノーコードワークフローを構築します。DevOpsカテゴリ/categories/devopsのGitLab CIと組み合わせてCSVエクスポートを自動化するパイプラインも構築できます。
FAQ
Q. AirtableからNocoDBへのデータ移行方法は?
A. AirtableはCSVエクスポート(Table → Download → CSV)またはAirtable API経由で移行できます。①Airtable API(https://api.airtable.com/v0/{base_id}/{table_name})でJSONを取得②NocoDBのインポート機能(画面上部「+」→「Import Data」→ CSV/JSON)でインポート③またはimport-airtable-to-nocodb.pyスクリプトでAPI間直接転送。AttachmentフィールドはURLとして移行され、ファイル実体は再ダウンロードが必要です。FormulaフィールドはNocoDBの数式構文に書き直しが必要(Airtable: IF({Status}="Done", "完了", "進行中") → NocoDB: IF(Status="Done", "完了", "進行中"))。
Q. GristとExcelの互換性は?
A. GristはExcelのCSV/XLSXをインポート可能(Import → File)。数式の自動変換は非対応で手動での書き直しが必要です。GristフォーミュラはPythonベースのため =VLOOKUP は VLOOKUP(value, range, col_num) と同様に動作しますが、=CONCATENATE は "%s %s" % ($First_Name, $Last_Name) のようにPython文字列書式を使います。エクスポートはCSV・XLSX・JSON・Pythonに対応しています。大量データ(10万行以上)では他ツールより処理が重くなる傾向があり、NocoDBの方がパフォーマンスが良いです。
Q. NocoDBで複数のデータベースを1つのUIで管理できますか?
A. 可能です。NocoDBの「Bases」機能で複数のDB接続を追加できます(Administration → Bases → New Base)。同一のNocoDBインスタンスからMySQL・PostgreSQL・SQLite・MariaDB・TiDB・CockroachDBを別々のBaseとして接続できます。ただし複数Base間のJOINは現時点では未対応(同一DB内のテーブル間リレーションのみ対応)。複数DBの横断ダッシュボードを作るにはSuperset(Apache)やMetabaseとNocoDBの組み合わせを推奨します。
Q. Baserow・NocoDB・GristのうちAirtableに最も近いのはどれですか?
A. Baserowが最もAirtableに近いUIとUXを提供します。Grid/Gallery/Kanban/Form/Calendarビューがすべて揃っており、Airtableユーザーが違和感なく使い始められます。セルフホスト版はDockerでデプロイし、クラウド版はbaserow.ioでSaaS提供(Starter $5/ユーザー/月)。Airtableから移行する場合: Baserowの「Import Airtable base」機能(Airtable APIキーを入力するだけ)でテーブル・フィールド・レコードを自動インポートできます(添付ファイル含む)。Enterprise機能(SSO・監査ログ・エンタープライズサポート)はオープンソース版にも含まれています。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| Airtable移行・最高の互換性 | Baserow |
| 既存PostgreSQL/MySQLに即UIが欲しい | NocoDB |
| Pythonフォーミュラ・高度な計算 | Grist |