ken_nogi/Pleasanter/.claude/js/extract-excel-def.js
Kenichiro NOGI ce58cb4be4 初回コミット: dev配下(NodeSrv/Pleasanter等)をGitea管理下に統合
GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。
NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは
別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter
インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:37:06 +09:00

63 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// サイト定義書xlsxの1シートを、ブロック(文字列/数値/日付/説明/チェックボックス/添付ファイル)ごとに
// 縦展開したレコード配列へ変換する。読み取り専用の調査用スクリプト(ファイルへの書き込みは行わない)。
const fs = require("fs");
const XLSX = require("xlsx");
const [, , xlsxPath, sheetName, outPath] = process.argv;
const wb = XLSX.readFile(xlsxPath);
const ws = wb.Sheets[sheetName];
if (!ws) {
console.error("シートが見つかりません:", sheetName, "候補:", wb.SheetNames);
process.exit(1);
}
const rows = XLSX.utils.sheet_to_json(ws, { header: 1, defval: "" });
// ヘッダー行(2行目、0-indexed row1)の3列目が「タブ」かどうかでブロック幅を自動判定する。
// シートによって「タブ」列の有無が異なるためsite-335411は有り、site-335410は無し
// また「サンプル項目有無」列は先頭の文字列ブロックのみに存在し、それ以外のブロックには無い(不均等な列幅)。
const hasTabColumn = String((rows[1] && rows[1][2]) || "").trim() === "タブ";
const firstBlockOff = hasTabColumn
? { col: 0, tab: 1, label: 2, show: 3, req: 4, ro: 5, lock: 6, style: 7, sample: 8, ver: 9, note: 10, other: 11 }
: { col: 0, tab: -1, label: 1, show: 2, req: 3, ro: 4, lock: 5, style: 6, sample: 7, ver: 8, note: 9, other: 10 };
const restBlockOff = hasTabColumn
? { col: 0, tab: 1, label: 2, show: 3, req: 4, ro: 5, lock: 6, style: 7, sample: -1, ver: 8, note: 9, other: 10 }
: { col: 0, tab: -1, label: 1, show: 2, req: 3, ro: 4, lock: 5, style: 6, sample: -1, ver: 7, note: 8, other: 9 };
const firstBlockWidth = Math.max(...Object.values(firstBlockOff)) + 1;
const restBlockWidth = Math.max(...Object.values(restBlockOff)) + 1;
const kinds = ["文字列", "数値", "日付", "説明", "チェックボックス", "添付ファイル"];
const blocks = kinds.map((kind, i) => {
const start = i === 0 ? 1 : 1 + firstBlockWidth + restBlockWidth * (i - 1);
const off = i === 0 ? firstBlockOff : restBlockOff;
const abs = {};
for (const [k, v] of Object.entries(off)) abs[k] = v === -1 ? -1 : start + v;
return { kind, ...abs };
});
const records = [];
for (let r = 2; r < rows.length; r++) {
const row = rows[r];
for (const b of blocks) {
const colName = String(row[b.col] || "").trim();
if (!colName) continue;
records.push({
rowIndex: r + 1, // 1-indexed excel row
kind: b.kind,
ColumnName: colName,
tab: row[b.tab] || "",
label: row[b.label] || "",
show: row[b.show] || "",
req: row[b.req] || "",
readOnly: row[b.ro] || "",
lock: row[b.lock] || "",
style: row[b.style] || "",
sample: b.sample >= 0 ? row[b.sample] || "" : "",
ver: row[b.ver] || "",
note: row[b.note] || "",
other: row[b.other] || "",
});
}
}
fs.writeFileSync(outPath, JSON.stringify(records, null, 2), "utf8");
console.log("件数:", records.length, "→", outPath);