diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-24 01:44:03 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-24 01:44:03 +0000 |
| commit | 4e63d8427d26d0d1b366ddc53650e15f3481fc75 (patch) | |
| tree | ddfb69a92db56498ea591eed0f14ed2ce823431c /components | |
| parent | 127185717263ea3162bd192c83b4c7efe0d96e50 (diff) | |
(대표님/최겸) 20250624 작업사항 10시43분
Diffstat (limited to 'components')
| -rw-r--r-- | components/document-lists/vendor-doc-list-client.tsx | 2 | ||||
| -rw-r--r-- | components/form-data/form-data-table.tsx | 2 | ||||
| -rw-r--r-- | components/spread-js/dataBinding.tsx | 491 | ||||
| -rw-r--r-- | components/spread-js/testSheet.tsx | 90 |
4 files changed, 583 insertions, 2 deletions
diff --git a/components/document-lists/vendor-doc-list-client.tsx b/components/document-lists/vendor-doc-list-client.tsx index 4dea591f..d914b6f0 100644 --- a/components/document-lists/vendor-doc-list-client.tsx +++ b/components/document-lists/vendor-doc-list-client.tsx @@ -51,7 +51,7 @@ export default function VendorDocumentListClient({ setProjectType("plant") // Navigate to the contract's documents page - router.push(`/partners/document-list/${contractId}?projectType=plnat`) + router.push(`/partners/document-list/${contractId}?projectType=plant`) } return ( diff --git a/components/form-data/form-data-table.tsx b/components/form-data/form-data-table.tsx index b59684e3..92ec3c56 100644 --- a/components/form-data/form-data-table.tsx +++ b/components/form-data/form-data-table.tsx @@ -111,7 +111,7 @@ async function fetchTemplateFromSEDP(projectCode: string, formCode: string): Pro // Make the API call const response = await fetch( - `${SEDP_API_BASE_URL}/Data/GetPubData`, + `${SEDP_API_BASE_URL}/Template/GetByRegisterID`, { method: 'POST', headers: { diff --git a/components/spread-js/dataBinding.tsx b/components/spread-js/dataBinding.tsx new file mode 100644 index 00000000..52171dbf --- /dev/null +++ b/components/spread-js/dataBinding.tsx @@ -0,0 +1,491 @@ +// @ts-nocheck +"use client"; + +import * as React from "react"; +import GC from "@mescius/spread-sheets"; +import "@mescius/spread-sheets-resources-ko"; +import { SpreadSheets } from "@mescius/spread-sheets-react"; + +GC.Spread.Common.CultureManager.culture("ko-kr"); +GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREADJS_KEY +GC.Spread.Sheets.Designer.LicenseKey = process.env.NEXT_PUBLIC_SPREADJS_KEY + +const DataBinding = () => { + let spread = null; + let dataSource1 = null; + let dataSource2 = null; + + const changeDataSource = () => { + if (!spread) return; + let sheet = spread.getActiveSheet(); + if (sheet.getDataSource() === dataSource1) { + sheet.setDataSource(dataSource2); + } else { + sheet.setDataSource(dataSource1); + } + }; + const initSpread = (currSpread) => { + spread = currSpread; + + if(currSpread){ + let company1 = new Company( + "Baidu", + null, + "We know everything!", + "Beijing 1st road", + "Beijing", + "010-12345678", + "baidu@baidu.com" + ), + company2 = new Company( + "Tecent", + null, + "We have everything!", + "Shenzhen 2st road", + "Shenzhen", + "0755-12345678", + "tecent@qq.com" + ), + company3 = new Company( + "Alibaba", + null, + "We sale everything!", + "Hangzhou 3rd road", + "Hangzhou", + "0571-12345678", + "alibaba@alibaba.com" + ), + customer1 = new Customer("A1", "employee 1", company2), + customer2 = new Customer("A2", "employee 2", company3), + records1 = [ + new Record("Finance charge on overdue balance at 1.5%", 1, 150), + new Record("Invoice #100 for $1000 on 2014/1/1", 1, 150), + ], + records2 = [ + new Record("Purchase server device", 2, 15000), + new Record("Company travel", 100, 1500), + new Record("Company Dinner", 100, 200), + new Record("Company Dinner", 100, 200), + new Record("Company Dinner", 100, 200), + new Record("Company Dinner", 100, 200), + new Record("Company Dinner", 100, 200), + new Record("Company Dinner", 100, 200), + ], + invoice1 = new Invoice( + company1, + "00001", + new Date(2014, 0, 1), + customer1, + customer1, + records1 + ), + invoice2 = new Invoice( + company2, + "00002", + new Date(2014, 6, 6), + customer2, + customer2, + records2 + ); + + dataSource1 = new GC.Spread.Sheets.Bindings.CellBindingSource(invoice1); + dataSource2 = new GC.Spread.Sheets.Bindings.CellBindingSource(invoice2); + + //Get sheet instance + spread.suspendPaint(); + let sheet = spread.sheets[0]; + sheet.name("FINANCE CHARGE"); + + //Set value or bindingPath and style + let bindingPathCellType = new BindingPathCellType(); + sheet + .getCell(1, 2) + .bindingPath("company.slogan") + .cellType(bindingPathCellType) + .vAlign(GC.Spread.Sheets.VerticalAlign.bottom); + sheet + .getCell(1, 4) + .value("INVOICE") + .foreColor("#58B6C0") + .font("33px Arial"); + sheet + .getCell(3, 1) + .bindingPath("company.name") + .cellType(bindingPathCellType) + .foreColor("#58B6C0") + .font("bold 20px Arial"); + sheet + .getCell(5, 1) + .bindingPath("company.address") + .cellType(bindingPathCellType); + sheet.getCell(5, 3).value("INVOICE NO.").font("bold 15px Arial"); + sheet.getCell(5, 4).bindingPath("number").cellType(bindingPathCellType); + sheet + .getCell(6, 1) + .bindingPath("company.city") + .cellType(bindingPathCellType); + sheet.getCell(6, 3).value("DATE").font("bold 15px Arial"); + sheet + .getCell(6, 4) + .bindingPath("date") + .cellType(bindingPathCellType) + .formatter("MM/dd/yyyy") + .hAlign(GC.Spread.Sheets.HorizontalAlign.left); + sheet + .getCell(7, 1) + .bindingPath("company.phone") + .cellType(bindingPathCellType); + sheet.getCell(7, 3).value("CUSTOMER ID").font("bold 15px Arial"); + sheet + .getCell(7, 4) + .bindingPath("customer.id") + .cellType(bindingPathCellType); + sheet + .getCell(8, 1) + .bindingPath("company.email") + .cellType(bindingPathCellType); + sheet.getCell(10, 1).value("TO").font("bold 15px Arial"); + sheet.getCell(10, 3).value("SHIP TO").font("bold 15px Arial"); + sheet + .getCell(11, 1) + .bindingPath("customer.name") + .cellType(bindingPathCellType) + .textIndent(10); + sheet + .getCell(12, 1) + .bindingPath("customer.company.name") + .cellType(bindingPathCellType) + .textIndent(10); + sheet + .getCell(13, 1) + .bindingPath("customer.company.address") + .cellType(bindingPathCellType) + .textIndent(10); + sheet + .getCell(14, 1) + .bindingPath("customer.company.city") + .cellType(bindingPathCellType) + .textIndent(10); + sheet + .getCell(15, 1) + .bindingPath("customer.company.phone") + .cellType(bindingPathCellType) + .textIndent(10); + sheet + .getCell(11, 4) + .bindingPath("receiverCustomer.name") + .cellType(bindingPathCellType); + sheet + .getCell(12, 4) + .bindingPath("receiverCustomer.company.name") + .cellType(bindingPathCellType); + sheet + .getCell(13, 4) + .bindingPath("receiverCustomer.company.address") + .cellType(bindingPathCellType); + sheet + .getCell(14, 4) + .bindingPath("receiverCustomer.company.city") + .cellType(bindingPathCellType); + sheet + .getCell(15, 4) + .bindingPath("receiverCustomer.company.phone") + .cellType(bindingPathCellType); + sheet.addSpan(17, 1, 1, 2); + sheet + .getCell(17, 1) + .value("JOB") + .foreColor("#58B6C0") + .font("bold 12px Arial"); + sheet.addSpan(17, 3, 1, 2); + sheet + .getCell(17, 3) + .value("PAYMENT TERMS") + .foreColor("#58B6C0") + .font("bold 12px Arial"); + sheet.addSpan(18, 1, 1, 2); + sheet.getCell(18, 1).backColor("#DDF0F2"); + sheet.addSpan(18, 3, 1, 2); + sheet + .getCell(18, 3) + .value("Due on receipt") + .backColor("#DDF0F2") + .foreColor("#58B6C0") + .font("12px Arial"); + sheet + .getRange(17, 1, 2, 4) + .setBorder( + new GC.Spread.Sheets.LineBorder( + "#58B6C0", + GC.Spread.Sheets.LineStyle.thin + ), + { top: true, bottom: true, innerHorizontal: true } + ); + let table = sheet.tables.add( + "tableRecordds", + 20, + 1, + 1, + 4, + GC.Spread.Sheets.Tables.TableThemes.light6 + ); + table.autoGenerateColumns(false); + let tableColumn1 = new GC.Spread.Sheets.Tables.TableColumn(0); + tableColumn1.name("DESCRIPTION"); + tableColumn1.dataField("description"); + let tableColumn2 = new GC.Spread.Sheets.Tables.TableColumn(1); + tableColumn2.name("QUANTITY"); + tableColumn2.dataField("quantity"); + let tableColumn3 = new GC.Spread.Sheets.Tables.TableColumn(2); + tableColumn3.name("AMOUNT"); + tableColumn3.dataField("amount"); + table.bindColumns([tableColumn1, tableColumn2, tableColumn3]); + table.bindingPath("records"); + table.showFooter(true); + table.setColumnName(3, "TOTAL"); + table.setColumnValue(2, "TOTAL DUE"); + table.setColumnDataFormula(3, "=[@QUANTITY]*[@AMOUNT]"); + table.setColumnFormula(3, "=SUBTOTAL(109,[TOTAL])"); + sheet + .getCell(26, 1) + .formula( + '="Make all checks payable to "&B4&". THANK YOU FOR YOUR BUSINESS!"' + ) + .foreColor("gray") + .font("italic 14px Arial"); + sheet.options.allowCellOverflow = true; + //Adjust row height and column width + sheet.setColumnWidth(0, 5); + sheet.setColumnWidth(1, 300); + sheet.setColumnWidth(2, 115); + sheet.setColumnWidth(3, 125); + sheet.setColumnWidth(4, 155); + sheet.setRowHeight(0, 5); + sheet.setRowHeight(1, 40); + sheet.setRowHeight(2, 10); + sheet.setRowHeight(3, 28); + sheet.setRowHeight(17, 0); + sheet.setRowHeight(18, 0); + sheet.setRowHeight(19, 0); + sheet.setRowHeight(25, 10); + sheet.options.gridline = { + showHorizontalGridline: false, + showVerticalGridline: false, + }; + + spread.resumePaint(); + } + }; + + return ( + <div className="sample-tutorial"> + <div className="sample-spreadsheets"> + <SpreadSheets workbookInitialized={(spread) => initSpread(spread)} /> + </div> + <div className="options-container"> + <div className="option-row"> + <label style={{ backgroundColor: "#F4F8EB" }}> + Click this button to set the data source for the data-bound table. + </label> + </div> + <input + type="button" + onClick={() => { + changeDataSource(); + }} + id="changeDataSource" + value="Set DataSource" + title="Toggle table binding's data source" + /> + <div className="option-row"> + <label style={{ backgroundColor: "#F4F8EB" }}> + 데이터 바인딩 위치 확인 + </label> + </div> + <input + type="button" + onClick={() => { + extractBindingPaths(spread); + }} + id="changeDataSource" + value="데이터 바인딩 위치 확인" + title="Toggle table binding's data source" + /> + <div className="option-row"> + <label style={{ backgroundColor: "#F4F8EB" }}> + 테이블 데이터 바인딩 위치 확인 + </label> + </div> + <input + type="button" + onClick={() => { + extractTableBindingPaths(spread); + }} + id="changeDataSource" + value="테이블 데이터 바인딩 위치 확인" + title="Toggle table binding's data source" + /> + <div className="option-row"> + <label style={{ backgroundColor: "#F4F8EB" }}>값 가져오기</label> + </div> + <input + type="button" + onClick={() => { + extractAllCellsWithValues(spread); + }} + id="changeDataSource" + value="테이블 데이터 바인딩 위치 확인" + title="Toggle table binding's data source" + /> + </div> + </div> + ); +}; + +export default DataBinding; + +class Company { + constructor( + public name?: string | null, + public logo?: string | null, + public slogan?: string | null, + public address?: string | null, + public city?: string | null, + public phone?: string | null, + public email?: string | null + ) {} +} + +class Customer { + constructor( + public id?: string, + public name?: string, + public company?: Company + ) {} +} + +class Record { + constructor( + public description?: string, + public quantity?: number, + public amount?: number + ) {} +} + +class Invoice { + constructor( + public company: Company, + public number: string, + public date: Date, + public customer: Customer, + public receiverCustomer: Customer, + public records: Record[] | [] + ) {} +} + +class BindingPathCellType extends GC.Spread.Sheets.CellTypes.Text { + constructor() { + super(); + } + + paint(ctx, value, x, y, w, h, style, context) { + if (value === null || value === undefined) { + let sheet = context.sheet, + row = context.row, + col = context.col; + if (sheet && (row === 0 || !!row) && (col === 0 || !!col)) { + let bindingPath = sheet.getBindingPath(context.row, context.col); + if (bindingPath) { + value = "[" + bindingPath + "]"; + } + } + } + super.paint(ctx, value, x, y, w, h, style, context); + } +} + +const extractBindingPaths = (spread) => { + let sheet = spread.getActiveSheet(); + let bindingPaths = []; + + for (let row = 0; row < sheet.getRowCount(); row++) { + for (let col = 0; col < sheet.getColumnCount(); col++) { + let bindingPath = sheet.getBindingPath(row, col); + if (bindingPath) { + bindingPaths.push({ row, col, bindingPath }); + } + } + } + + console.log( + "Extracted Binding Paths:", + JSON.stringify(bindingPaths, null, 2) + ); + return bindingPaths; +}; + +const extractTableBindingPaths = (spread) => { + let sheet = spread.getActiveSheet(); + let tables = sheet.tables.all(); + let tableBindings = []; + + tables.forEach((table) => { + let range = table.range(); // 테이블의 위치 정보 가져오기 + let tableInfo = { + tableName: table.name(), + bindingPath: table.bindingPath(), + tablePosition: { + startRow: range.row, + startCol: range.col, + rowCount: range.rowCount, + colCount: range.colCount, + }, + columns: [], + }; + + // 🔹 컬럼 바인딩 정보 직접 추출 (bindColumns() 사용 안함) + for (let c = range.col; c < range.col + range.colCount; c++) { + let bindingPath = sheet.getBindingPath(range.row, c); + let headerValue = sheet.getValue(range.row, c); + + if (bindingPath) { + tableInfo.columns.push({ + colIndex: c, + columnName: headerValue || `Column ${c - range.col + 1}`, + dataField: bindingPath, + }); + } + } + + tableBindings.push(tableInfo); + }); + + console.log( + "📌 바인딩된 위치 및 컬럼 정보:", + JSON.stringify(tableBindings, null, 2) + ); + return tableBindings; +}; + +const extractAllCellsWithValues = (spread) => { + let sheet = spread.getActiveSheet(); + let rowCount = sheet.getRowCount(); + let colCount = sheet.getColumnCount(); + let cellData = []; + + for (let row = 0; row < rowCount; row++) { + for (let col = 0; col < colCount; col++) { + let value = sheet.getValue(row, col); + if (value !== null && value !== undefined && value !== "") { + cellData.push({ + row: row, + col: col, + value: value, + }); + } + } + } + + console.log("📌 모든 값이 있는 셀 정보:", JSON.stringify(cellData, null, 2)); + return cellData; +}; diff --git a/components/spread-js/testSheet.tsx b/components/spread-js/testSheet.tsx new file mode 100644 index 00000000..0d69798e --- /dev/null +++ b/components/spread-js/testSheet.tsx @@ -0,0 +1,90 @@ +// @ts-nocheck +"use client"; + +import React, { useState } from "react"; +import "@mescius/spread-sheets-print"; +import "@mescius/spread-sheets-io"; +import "@mescius/spread-sheets-shapes"; +import "@mescius/spread-sheets-charts"; +import "@mescius/spread-sheets-slicers"; +import "@mescius/spread-sheets-pivot-addon"; +import "@mescius/spread-sheets-reportsheet-addon"; +import "@mescius/spread-sheets-tablesheet"; +import "@mescius/spread-sheets-ganttsheet"; +import "@mescius/spread-sheets-resources-ko"; +import "@mescius/spread-sheets-formula-panel"; +import "@mescius/spread-sheets-designer-resources-ko"; +import '@mescius/spread-sheets-datacharts-addon'; +import * as GC from "@mescius/spread-sheets"; +import { Designer } from "@mescius/spread-sheets-designer-react"; +import { + addSheet, + clearSheet, + createSampleReportForm, + removeSheet, + setSampleReportData, + exportJSON,handleFileImport +} from "@/lib/spread-js/fns"; +import { Button } from "@/components/ui/button"; + +// SpreadJS 라이선싱 +// var SpreadJSKey = "xxx"; // 라이선스 키 입력 +// GC.Spread.Sheets.LicenseKey = SpreadJSKey; +GC.Spread.Common.CultureManager.culture("ko-kr"); +GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREADJS_KEY +GC.Spread.Sheets.Designer.LicenseKey = process.env.NEXT_PUBLIC_SPREADJS_KEY + +export default function SpreadSheet() { + const [spread, setSpread] = useState(null); + + function initSpread(spread) { + setSpread(spread); + //init Status Bar + var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar( + document.getElementById("statusBar") + ); + statusBar.bind(spread); + } + + return ( + <div className="relative h-full overflow-hidden"> + <div className="sample-container"> + <div className="w-[calc(100%-280px)] h-full overflow-hidden float-left"> + <Designer + styleInfo={{ height: "100%" }} + designerInitialized={async (designer: any) => { + initSpread(designer.getWorkbook()); + designer.refresh(); + }} + spreadOptions={{ allowDragHeaderToMove: 3 }} + /> + </div> + <div id="statusBar"></div> + </div> + <div className="float-right w-[280px] p-[12px] h-full box-border bg-[#fbfbfb]"> + <div className="p-[5px] mt-[10px]"> + + <div className="flex flex-col gap-2"> + <Button onClick={() => addSheet(spread)}>Add Sheet</Button> + <Button onClick={() => removeSheet(spread)}>Remove Sheet</Button> + <Button onClick={() => clearSheet(spread)}>Clear Sheet</Button> + <Button onClick={() => createSampleReportForm(spread)}> + Create Report Form + </Button> + <Button onClick={() => setSampleReportData(spread)}> + Set Report Data + </Button> + <Button onClick={() => exportJSON(spread)}> + Export JSON + </Button> + <Button onClick={() => handleFileImport(spread)}> + Import JSON + </Button> + </div> + </div> + </div> + </div> + ); +} + + |
