import ExcelJS from "exceljs"; import { useCounterMixin } from "@/stores/mixin"; import { useGovernmentPosDataStore } from "@/modules/10_registry/store/Position"; import type { DataPosition } from "@/modules/10_registry/interface/review/Edit"; const { date2Thai } = useCounterMixin(); const store = useGovernmentPosDataStore(); export async function exportToExcelPosition(data: DataPosition[]) { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet("รายการประวัติตำแหน่งเงินเดือน"); // --- ส่วนที่ 1: สร้าง Master Data Sheet สำหรับอ้างอิง ID --- // เราจะซ่อนแผ่นงานนี้ไว้ (hidden) เพื่อใช้ทำ Dropdown และ VLOOKUP const masterSheet = workbook.addWorksheet("MasterData", { state: "hidden" }); const masterData = store.commandCodeData; // [{id: 1, name: "ย้าย"}, ...] masterData.forEach((item, index) => { masterSheet.getCell(`A${index + 1}`).value = item.name; masterSheet.getCell(`B${index + 1}`).value = item.id; }); // --- ส่วนที่ 2: กำหนด Columns --- worksheet.columns = [ { header: "ลำดับ", key: "no", width: 8 }, { header: "วันที่คำสั่งมีผล", key: "commandDateAffect", width: 18 }, { header: "ตำแหน่งในสายงาน", key: "positionName", width: 25 }, { header: "ตำแหน่งประเภท", key: "positionType", width: 18 }, { header: "ระดับ", key: "positionLevel", width: 12 }, { header: "ระดับซี", key: "positionCee", width: 12 }, { header: "สายงาน", key: "positionLine", width: 20 }, { header: "ด้าน/สาขา", key: "positionPathSide", width: 15 }, { header: "ตำแหน่งทางการบริหาร", key: "positionExecutive", width: 20 }, { header: "ด้านทางการบริหาร", key: "positionExecutiveField", width: 20 }, { header: "เงินเดือน", key: "amount", width: 15 }, { header: "เงินค่าตอบแทนรายเดือน", key: "mouthSalaryAmount", width: 15 }, { header: "เงินประจำตำแหน่ง", key: "positionSalaryAmount", width: 15 }, { header: "เงินค่าตอบแทนพิเศษ", key: "amountSpecial", width: 15 }, { header: "หน่วยงาน", key: "organization", width: 30 }, { header: "ส่วนราชการระดับ 1", key: "orgChild1", width: 20 }, { header: "ส่วนราชการระดับ 2", key: "orgChild2", width: 20 }, { header: "ส่วนราชการระดับ 3", key: "orgChild3", width: 20 }, { header: "ส่วนราชการระดับ 4", key: "orgChild4", width: 20 }, { header: "ตัวย่อเลขที่ตำแหน่ง", key: "posNoAbb", width: 15 }, { header: "เลขที่ตำแหน่ง", key: "posNo", width: 15 }, { header: "หน่วยงานที่ออกคำสั่ง", key: "posNumCodeSit", width: 20 }, { header: "ตัวย่อหน่วยงานที่ออกคำสั่ง", key: "posNumCodeSitAbb", width: 15, }, { header: "เลขที่คำสั่ง", key: "commandNo", width: 15 }, { header: "ปีเลขที่คำสั่ง", key: "commandYear", width: 12 }, { header: "วันที่ลงนาม", key: "commandDateSign", width: 18 }, { header: "ประเภทคำสั่ง", key: "commandCodeName", width: 25 }, // AA { header: "หมายเหตุ", key: "remark", width: 20 }, { header: "commandId", key: "commandId", width: 20 }, // AC (ลำดับที่ 29) { header: "commandCode", key: "commandCode", width: 20 }, // AD (ลำดับที่ 30) ]; // 3. Map ข้อมูล const newData = data.map((e, index) => ({ no: index + 1, commandDateAffect: date2Thai(e.commandDateAffect), positionName: e.positionName, positionType: e.positionType, positionLevel: e.positionLevel, positionCee: e.positionCee, positionLine: e.positionLine || "", positionPathSide: e.positionPathSide || "", positionExecutive: e.positionExecutive, positionExecutiveField: e.positionExecutiveField || "", amount: e.amount, mouthSalaryAmount: e.mouthSalaryAmount || 0, positionSalaryAmount: e.positionSalaryAmount, amountSpecial: e.amountSpecial || 0, organization: e.orgRoot, orgChild1: e.orgChild1, orgChild2: e.orgChild2, orgChild3: e.orgChild3, orgChild4: e.orgChild4, posNoAbb: e.posNoAbb, posNo: e.posNo, posNumCodeSit: e.posNumCodeSit, posNumCodeSitAbb: e.posNumCodeSitAbb, commandNo: e.commandNo, commandYear: e.commandYear ? Number(e.commandYear) + 543 : "", commandDateSign: date2Thai(e.commandDateSign), commandCodeName: store.convertCommandCodeName(e.commandCode), remark: e.remark, commandId: e.commandId, commandCode: e.commandCode, // ใส่ค่าเริ่มต้นไว้ })); worksheet.addRows(newData); // 4. ตกแต่งสี, Dropdown และ สูตร VLOOKUP newData.forEach((_, index) => { const rowIndex = index + 2; // --- ทำ Dropdown คอลัมน์ AA --- // อ้างอิงรายการจาก MasterData Sheet จะทำให้ Excel ทำงานได้เสถียรกว่า (กรณีรายการเยอะ) worksheet.getCell(`AA${rowIndex}`).dataValidation = { type: "list", allowBlank: true, formulae: [`MasterData!$A$1:$A$${masterData.length}`], }; // --- ผูกสูตรให้ commandCode (AD) เปลี่ยนตามการเลือกใน AA --- // AA คือประเภทคำสั่ง, AD คือ commandCode worksheet.getCell(`AD${rowIndex}`).value = { formula: `=IFERROR(VLOOKUP(AA${rowIndex}, MasterData!$A$1:$B$${masterData.length}, 2, FALSE), "")`, }; }); // 5. สไตล์ Header worksheet.getRow(1).font = { bold: true }; worksheet.getRow(1).alignment = { vertical: "middle", horizontal: "center" }; // 6. เขียนไฟล์ const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }); const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "รายการประวัติตำแหน่งเงินเดือน.xlsx"; a.click(); window.URL.revokeObjectURL(url); }