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>
63 lines
3.0 KiB
JavaScript
63 lines
3.0 KiB
JavaScript
// サイト定義書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);
|