2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

💸 予算ゼロから始める「脱Excel」!OSSだけで作る在庫管理システム【Luckysheet × Python】

Last updated at Posted at 2025-12-04

はじめに:なぜOSSでExcel DXなのか

「Excel業務をシステム化したい。でも、高額な商用ライブラリやSaaSを導入する予算がない…」

そんな悩みを持つエンジニアや情シス担当者は多いはずです。しかし、諦める必要はありません。OSSにもExcelのUIをWeb上で忠実に再現できるライブラリが存在します。

本記事では、商用ツールを一切使わず、「Luckysheet(フロントエンド)」と「FastAPI(バックエンド)」 という完全OSS構成で、「在庫管理・発注シミュレーションシステム」を構築するアプローチをご紹介します。

1. 目指すアーキテクチャ

「データはDBで堅牢に守り、UIはExcelライクに使いやすく」という方針は変わりません。

  • Frontend (UI): Luckysheet (MITライセンス)

    • Webブラウザ上でExcelのような見た目と操作感(数式、ドラッグ&ドロップ、書式設定)を提供
  • Backend (API): FastAPI (Python)

    • 高速かつモダンなPythonフレームワークで、計算ロジックとDB操作を担当
  • Database: PostgreSQL

    • 堅牢なRDBでデータを一元管理

2. ユースケース:在庫発注シミュレーション

Excelで運用されがちな「在庫一覧を見ながら、システムが提案した発注数を手動で微調整する」業務を想定します。

3. 実装ステップとコード解説

Step 1: データベース構築 (PostgreSQL)

-- inventory_table.sql
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    current_stock INT NOT NULL,  -- 現在在庫
    safety_stock INT DEFAULT 10, -- 安全在庫
    lead_time INT DEFAULT 3      -- 調達リードタイム(日)
);

-- サンプルデータ
INSERT INTO products (name, current_stock, safety_stock, lead_time) VALUES
('ネジ Type-A', 50, 20, 5),
('ボルト M8', 5, 30, 2),
('ワッシャー', 100, 10, 1);

Step2:バックエンドロジックの実装(FastAPI)

Excelマクロで行っていた発注点計算ロジックを、PythonでAPI化します。

# main.py
from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

app = FastAPI()

# データモデル定義
class Product(BaseModel):
    id: int
    name: str
    current_stock: int
    suggested_order: int = 0

# ダミーのDB接続(実際はSQLAlchemy等を使用)
mock_db = [
    {"id": 1, "name": "ネジ Type-A", "current_stock": 50, "safety_stock": 20, "lead_time": 5},
    {"id": 2, "name": "ボルト M8", "current_stock": 5, "safety_stock": 30, "lead_time": 2},
]

def calculate_order_logic(stock, safety, lead_time):
    """
    [脱属人化ポイント] 
    計算ロジックをここに集約。
    在庫が (安全在庫 + リードタイム消費分) を下回ったら発注。
    """
    avg_daily_sales = 5 # 簡易化のため固定値
    threshold = safety + (lead_time * avg_daily_sales)
    
    if stock < threshold:
        return threshold - stock + 50 # 50個を発注ロットとする
    return 0

@app.get("/api/inventory", response_model=List[Product])
def get_inventory():
    results = []
    for item in mock_db:
        # サーバー側で計算を実行
        suggestion = calculate_order_logic(
            item["current_stock"], 
            item["safety_stock"], 
            item["lead_time"]
        )
        
        results.append({
            "id": item["id"],
            "name": item["name"],
            "current_stock": item["current_stock"],
            "suggested_order": suggestion
        })
    return results

Step 3: フロントエンド実装 (Luckysheet)

ここが「活Excel」の肝です。Luckysheetを使って、ブラウザ上にスプレッドシートを描画し、APIデータを流し込みます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>在庫管理システム(サンプル)</title>
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' />
    <link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' />
    <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js"></script>
</head>
<body>
    <div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;height:100%;left:0px;top:0px;"></div>

    <script>
        document.addEventListener('DOMContentLoaded', async () => {
            // 1. APIからデータを取得
            const response = await fetch('http://localhost:8000/api/inventory');
            const data = await response.json();

            // 2. Luckysheet用のデータ形式(Celldata)に変換
            // r:行, c:列, v:値(m:表示値, v:実値)
            let cellData = [];
            
            // ヘッダー
            const headers = ["ID", "商品名", "現在在庫", "システム提案数", "手動調整", "発注確定数"];
            headers.forEach((text, index) => {
                cellData.push({ r: 0, c: index, v: { v: text, m: text, bg: "#f0f0f0", stat: "1" } }); // stat:1 は太字など
            });

            // データ行
            data.forEach((item, index) => {
                const row = index + 1;
                cellData.push({ r: row, c: 0, v: { v: item.id, m: String(item.id) } });
                cellData.push({ r: row, c: 1, v: { v: item.name, m: item.name } });
                cellData.push({ r: row, c: 2, v: { v: item.current_stock, m: String(item.current_stock) } });
                cellData.push({ r: row, c: 3, v: { v: item.suggested_order, m: String(item.suggested_order), fc: "#ff0000" } }); // 提案数は赤文字
                
                // 手動調整欄(空欄)
                cellData.push({ r: row, c: 4, v: { v: 0, m: "0", bg: "#ffffcc" } }); // 黄色背景で入力可を示唆

                // 発注確定数(Excel数式を埋め込む!)
                // =D2 + E2 のような形式
                const formula = `=D${row + 1}+E${row + 1}`;
                cellData.push({ r: row, c: 5, v: { f: formula, v: item.suggested_order } });
            });

            // 3. Luckysheetの初期化設定
            luckysheet.create({
                container: 'luckysheet', 
                title: '在庫発注管理', 
                lang: 'ja', // 日本語対応
                data: [{
                    "name": "発注リスト",
                    "celldata": cellData,
                    "freeze": "A2"
                }],
                showinfobar: false, // インフォメーションバー非表示
            });
        });
    </script>
</body>
</html>

4. OSS構成のメリット・デメリット

商用製品と比較した際の、現場のリアリティです。

メリット

  1. ライセンス費ゼロ: 初期投資なしでPoC(概念実証)やスモールスタートが可能。

  2. ブラックボックスなし: コードが公開されているため、バグがあっても自力で調査・修正が可能。

  3. コミュニティ: 世界中の開発者が機能追加を行っていす(Luckysheetは非常に高機能です)。

デメリット・注意点

  1. 公式サポートがない: トラブル時は自己解決か、コミュニティ頼みになります。

  2. ドキュメントの壁: Luckysheetは中国発祥のため、一部ドキュメントが中国語メインだったり、英語が不十分な場合があります。

  3. 印刷・PDF出力: 商用版ほど完璧な「帳票印刷機能」を持っていないことが多く、PDF生成はバックエンド側(PythonのReportLabなど)で実装する工夫が必要です。

まとめ

予算がなくても、技術選定次第で「脱Excel」と「活Excel」の両立は可能です。 特にLuckysheetのようなOSSは、現場ユーザーが求める「あのExcelの操作感」をWeb上で再現してくれます。

まずは、身近なExcelを一つ、OSSでWebアプリ化してみませんか? 現場の業務を少しでも楽にしましょう!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?