summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-08-27 09:46:36 +0000
committerjoonhoekim <26rote@gmail.com>2025-08-27 09:46:36 +0000
commita0c94e1d019339babf8bd45b1ff192ade47fc6e7 (patch)
tree6b7b5887daf143d9a0c3b07a51fdc7583dbd99b0
parentb203a0017f4b7150333024a1b1a5d1d9d21dea76 (diff)
(김준회) 호스트네임에 따른 도메인별 spreadjs 라이선스 적용 처리 및 운영용 환경변수 주석으로 추가
-rw-r--r--.env.development5
-rw-r--r--.env.production6
-rw-r--r--components/form-data/spreadJS-dialog.tsx6
-rw-r--r--components/spread-js/dataBinding.tsx7
-rw-r--r--components/spread-js/testSheet.tsx8
-rw-r--r--lib/spread-js/license-utils.ts83
6 files changed, 103 insertions, 12 deletions
diff --git a/.env.development b/.env.development
index 64ed6ac5..d2e34235 100644
--- a/.env.development
+++ b/.env.development
@@ -35,8 +35,9 @@ NEXT_PUBLIC_DESIGNER_LICENSE="43.203.251.114|60.101.108.100|evcp.dtsolution.io,2
# NEXT_PUBLIC_DESIGNER_LICENSE="Designer-514482759413237#B1IdxRUVvQnMkFkYVBzLjRzZohUVWZnSiJWUO9WS4pnMLp5KJZ7dX3CelFlW53STTlkdLlzdYBFV6lzTLRGUKVWOU3UbR3GUXFWZxJ5K8lzTnpVcEBHT5p4Yqt6RvEXaTtWMrRmUWpGW5x6dZlzVM5GRjZXMNVGdKxUZptGVUlUWiRnZ7cnTndkWsRGZllTcDpXeVpWRIV5M9BDVkBFNElWUCd5ZzcUWLNjYPNXOl9ESVJTQ756MFlFWzcmcGFDcXt6dDdnV4YmejJHSnNUc6t4MxcXNzQkU9kFSBRGa73WNEtyR6MkZzsEbvRVVHdHWYVlMr2UTGFmZI3mWIdUTihWb43WY78Eaz3SV9d6UzU4R7V5YjJiOiMlIsISMFBjQ8kDRiojIIJCLxITMzUjN5cTN0IicfJye35XX3JCSJpkQiojIDJCLigTMuYHITpEIkFWZyB7UiojIOJyebpjIkJHUiwiI9QTOwMDMgEjM7ATNyAjMiojI4J7QiwiIw8CMuAjLw2icl96ZpNXZkJiOiMXbEJCLikCjGyOoEyOshyOngyOsxqOKFeJ15Or0RSK1xSI12KI1iojIh94QiwiI7MjMzEDN9UzNygDN4ETNiojIklkIs4XXiQXZlh6U4J7bwVmUiwiI4JXYoNUY4FGRiwiIlxmYhRFdvZXaQJCLiQXZlh6U4RnbhdkIbpjInxmZiwSZ5JHd0IiczRmI1pjIs9WQisnOiQkIsISP3E4N82mcKVkdBZ7butkQQNXcMJWNnVVMxE6aUZ4QXBldnZWcrAXM9lmS9FDbp9ERUV7Q9IndiNHd0plb7pmd5debKh"
# SPREAD JS 내부망 eVCP 운영 (개발 배포시 이 키로 대체)
-# NEXT_PUBLIC_SPREAD_LICENSE=""
-# NEXT_PUBLIC_DESIGNER_LICENSE=""
+# NEXT_PUBLIC_SPREAD_LICENSE="partners.sevcp.com,674672615555322#B1gZNJnekBzRytSUL3UarhVcL56S9cEROVlYoB5QpdFVqZkN0hFaWhjdShmYqVmM7cHdKVzZqhnbnpFZ7M5bpJXRNNXdykjdrpUc9V6c8ImYKBXM6ljS5NWOjRnVhZ6UvRVZIVnZnxWd6h4axskZp9GbPpnbBRGczc5VKp6T4Bnc8FWeNVEVB9UVLFndoVXWvkzN5w6bol4MjFVSqFnejZmZGlEWqN4c6FkWzpnezZnUt3UNuBzYyc5dTtUcOR7am5WM4tSdFtCdDR6aUVkWsZ7apVVOkhzQwx6T9YWeCNXeOZ6dXR6Q5YUUwZne8MlSopHcXlFVNpXSUpmMPZGcpNFVF94UhhDWOZUYQR4TiojITJCLiQ4NGRjRGFzMiojIIJCL8YTN6AzM9MzM0IicfJye#4Xfd5nIIlkSCJiOiMkIsICOx8idgMlSgQWYlJHcTJiOi8kI1tlOiQmcQJCLiUzM4ATMwAiMygDM5IDMyIiOiQncDJCLi46bj9CcjZXZz9ycyVmb4JXYwJiOiMXbEJCLiU8lsX1sqHJpsHLhszrgsLiOiEmTDJCLiIjMzUTN5UTM6IzN6QzN6IiOiQWSiwSfdJCdlVGaTRncvBXZSJCLiQnchh6QhRXYEJCLiUGbiFGV43mdpBlIsICdlVGaTRHduF6RislOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPRlUWzMHZZpHa9llRtVHNu5WWI5WRRVmSGhHUpZESvg7LWZTeZhTTnpVc5Q4YiJ4Vw34dsV5aWR6QWlXewFmexlmM8d7MslMTMV"
+# NEXT_PUBLIC_DESIGNER_LICENSE="Designer-514482759413237#B1IdxRUVvQnMkFkYVBzLjRzZohUVWZnSiJWUO9WS4pnMLp5KJZ7dX3CelFlW53STTlkdLlzdYBFV6lzTLRGUKVWOU3UbR3GUXFWZxJ5K8lzTnpVcEBHT5p4Yqt6RvEXaTtWMrRmUWpGW5x6dZlzVM5GRjZXMNVGdKxUZptGVUlUWiRnZ7cnTndkWsRGZllTcDpXeVpWRIV5M9BDVkBFNElWUCd5ZzcUWLNjYPNXOl9ESVJTQ756MFlFWzcmcGFDcXt6dDdnV4YmejJHSnNUc6t4MxcXNzQkU9kFSBRGa73WNEtyR6MkZzsEbvRVVHdHWYVlMr2UTGFmZI3mWIdUTihWb43WY78Eaz3SV9d6UzU4R7V5YjJiOiMlIsISMFBjQ8kDRiojIIJCLxITMzUjN5cTN0IicfJye35XX3JCSJpkQiojIDJCLigTMuYHITpEIkFWZyB7UiojIOJyebpjIkJHUiwiI9QTOwMDMgEjM7ATNyAjMiojI4J7QiwiIw8CMuAjLw2icl96ZpNXZkJiOiMXbEJCLikCjGyOoEyOshyOngyOsxqOKFeJ15Or0RSK1xSI12KI1iojIh94QiwiI7MjMzEDN9UzNygDN4ETNiojIklkIs4XXiQXZlh6U4J7bwVmUiwiI4JXYoNUY4FGRiwiIlxmYhRFdvZXaQJCLiQXZlh6U4RnbhdkIbpjInxmZiwSZ5JHd0IiczRmI1pjIs9WQisnOiQkIsISP3E4N82mcKVkdBZ7butkQQNXcMJWNnVVMxE6aUZ4QXBldnZWcrAXM9lmS9FDbp9ERUV7Q9IndiNHd0plb7pmd5debKh"
+# NEXT_PUBLIC_SPREAD_LICENSE_SEVCP="sevcp.com,674672615555322#B1c1hT0ZDdy3Ea9FUQyB5MIN7TLRTZxpVQ5VFUwIGOLRneilFZzoUUHxERmtkNOVlNYFnTNZVekZDSShTOxZ4Q7hkbM94V6QkaPxUM6J7UNBnSYlXMT3ScEpmby5WS5gGWRNkYhNjSTp5YBZHTqBFUwhHW5Y4NzsUcUZWQxJzbkhDM5ZDT8tkQmRjUW3UdXhWT9RTcSZ7U4MHeJBXTttET6EFcOF6V0dzcyETMFF4blREMMBTa5kmT7M5ZZ5WVTlFZsZXRjJFN62WMYtWant4RrQ6aTV6bsBla5l7cyBTYmJkSZdzVKdmU7ljSThlWoxmR5UETsFXRKRUMGJ7TGljQap7VkJUQyk5aiojITJCLiAzNCZzMBVjI0ICSiwSMwATOwcTO7AjM0IicfJye#4Xfd5nIIlkSCJiOiMkIsICOx8idgMlSgQWYlJHcTJiOi8kI1tlOiQmcQJCLiEzMzEzNwAyNygDM5IDMyIiOiQncDJCLi46bj9CcjZXZzJiOiMXbEJCLiU8lsX1sqHJpsHLhszrgsLiOiEmTDJCLiIjMzUTN5UTM6IzN6QzN6IiOiQWSiwSfdJCdlVGaTRncvBXZSJCLiQnchh6QhRXYEJCLiUGbiFGV43mdpBlIsICdlVGaTRHduF6RislOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPBNzSB54M8MVYtVFcSZUczZHTh3yZUl5LuZFdOl6b7gXTThlcL54Z7JXQyhTY6YHN74GRBNFSP34c6lVTBtCNFhVZSNFe9UHWGJUadcRV"
# === 기간계 시스템 연동 설정 ===
ERP_API_URL=https://erp.example.com/api/vendors
diff --git a/.env.production b/.env.production
index 90cda87d..9aab6cb7 100644
--- a/.env.production
+++ b/.env.production
@@ -35,8 +35,10 @@ NEXT_PUBLIC_DESIGNER_LICENSE="43.203.251.114|60.101.108.100|evcp.dtsolution.io,2
# NEXT_PUBLIC_DESIGNER_LICENSE="Designer-514482759413237#B1IdxRUVvQnMkFkYVBzLjRzZohUVWZnSiJWUO9WS4pnMLp5KJZ7dX3CelFlW53STTlkdLlzdYBFV6lzTLRGUKVWOU3UbR3GUXFWZxJ5K8lzTnpVcEBHT5p4Yqt6RvEXaTtWMrRmUWpGW5x6dZlzVM5GRjZXMNVGdKxUZptGVUlUWiRnZ7cnTndkWsRGZllTcDpXeVpWRIV5M9BDVkBFNElWUCd5ZzcUWLNjYPNXOl9ESVJTQ756MFlFWzcmcGFDcXt6dDdnV4YmejJHSnNUc6t4MxcXNzQkU9kFSBRGa73WNEtyR6MkZzsEbvRVVHdHWYVlMr2UTGFmZI3mWIdUTihWb43WY78Eaz3SV9d6UzU4R7V5YjJiOiMlIsISMFBjQ8kDRiojIIJCLxITMzUjN5cTN0IicfJye35XX3JCSJpkQiojIDJCLigTMuYHITpEIkFWZyB7UiojIOJyebpjIkJHUiwiI9QTOwMDMgEjM7ATNyAjMiojI4J7QiwiIw8CMuAjLw2icl96ZpNXZkJiOiMXbEJCLikCjGyOoEyOshyOngyOsxqOKFeJ15Or0RSK1xSI12KI1iojIh94QiwiI7MjMzEDN9UzNygDN4ETNiojIklkIs4XXiQXZlh6U4J7bwVmUiwiI4JXYoNUY4FGRiwiIlxmYhRFdvZXaQJCLiQXZlh6U4RnbhdkIbpjInxmZiwSZ5JHd0IiczRmI1pjIs9WQisnOiQkIsISP3E4N82mcKVkdBZ7butkQQNXcMJWNnVVMxE6aUZ4QXBldnZWcrAXM9lmS9FDbp9ERUV7Q9IndiNHd0plb7pmd5debKh"
# SPREAD JS 내부망 eVCP 운영 (개발 배포시 이 키로 대체)
-# NEXT_PUBLIC_SPREAD_LICENSE=""
-# NEXT_PUBLIC_DESIGNER_LICENSE=""
+# NEXT_PUBLIC_SPREAD_LICENSE="partners.sevcp.com,674672615555322#B1gZNJnekBzRytSUL3UarhVcL56S9cEROVlYoB5QpdFVqZkN0hFaWhjdShmYqVmM7cHdKVzZqhnbnpFZ7M5bpJXRNNXdykjdrpUc9V6c8ImYKBXM6ljS5NWOjRnVhZ6UvRVZIVnZnxWd6h4axskZp9GbPpnbBRGczc5VKp6T4Bnc8FWeNVEVB9UVLFndoVXWvkzN5w6bol4MjFVSqFnejZmZGlEWqN4c6FkWzpnezZnUt3UNuBzYyc5dTtUcOR7am5WM4tSdFtCdDR6aUVkWsZ7apVVOkhzQwx6T9YWeCNXeOZ6dXR6Q5YUUwZne8MlSopHcXlFVNpXSUpmMPZGcpNFVF94UhhDWOZUYQR4TiojITJCLiQ4NGRjRGFzMiojIIJCL8YTN6AzM9MzM0IicfJye#4Xfd5nIIlkSCJiOiMkIsICOx8idgMlSgQWYlJHcTJiOi8kI1tlOiQmcQJCLiUzM4ATMwAiMygDM5IDMyIiOiQncDJCLi46bj9CcjZXZz9ycyVmb4JXYwJiOiMXbEJCLiU8lsX1sqHJpsHLhszrgsLiOiEmTDJCLiIjMzUTN5UTM6IzN6QzN6IiOiQWSiwSfdJCdlVGaTRncvBXZSJCLiQnchh6QhRXYEJCLiUGbiFGV43mdpBlIsICdlVGaTRHduF6RislOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPRlUWzMHZZpHa9llRtVHNu5WWI5WRRVmSGhHUpZESvg7LWZTeZhTTnpVc5Q4YiJ4Vw34dsV5aWR6QWlXewFmexlmM8d7MslMTMV"
+# NEXT_PUBLIC_DESIGNER_LICENSE="Designer-514482759413237#B1IdxRUVvQnMkFkYVBzLjRzZohUVWZnSiJWUO9WS4pnMLp5KJZ7dX3CelFlW53STTlkdLlzdYBFV6lzTLRGUKVWOU3UbR3GUXFWZxJ5K8lzTnpVcEBHT5p4Yqt6RvEXaTtWMrRmUWpGW5x6dZlzVM5GRjZXMNVGdKxUZptGVUlUWiRnZ7cnTndkWsRGZllTcDpXeVpWRIV5M9BDVkBFNElWUCd5ZzcUWLNjYPNXOl9ESVJTQ756MFlFWzcmcGFDcXt6dDdnV4YmejJHSnNUc6t4MxcXNzQkU9kFSBRGa73WNEtyR6MkZzsEbvRVVHdHWYVlMr2UTGFmZI3mWIdUTihWb43WY78Eaz3SV9d6UzU4R7V5YjJiOiMlIsISMFBjQ8kDRiojIIJCLxITMzUjN5cTN0IicfJye35XX3JCSJpkQiojIDJCLigTMuYHITpEIkFWZyB7UiojIOJyebpjIkJHUiwiI9QTOwMDMgEjM7ATNyAjMiojI4J7QiwiIw8CMuAjLw2icl96ZpNXZkJiOiMXbEJCLikCjGyOoEyOshyOngyOsxqOKFeJ15Or0RSK1xSI12KI1iojIh94QiwiI7MjMzEDN9UzNygDN4ETNiojIklkIs4XXiQXZlh6U4J7bwVmUiwiI4JXYoNUY4FGRiwiIlxmYhRFdvZXaQJCLiQXZlh6U4RnbhdkIbpjInxmZiwSZ5JHd0IiczRmI1pjIs9WQisnOiQkIsISP3E4N82mcKVkdBZ7butkQQNXcMJWNnVVMxE6aUZ4QXBldnZWcrAXM9lmS9FDbp9ERUV7Q9IndiNHd0plb7pmd5debKh"
+# NEXT_PUBLIC_SPREAD_LICENSE_SEVCP="sevcp.com,674672615555322#B1c1hT0ZDdy3Ea9FUQyB5MIN7TLRTZxpVQ5VFUwIGOLRneilFZzoUUHxERmtkNOVlNYFnTNZVekZDSShTOxZ4Q7hkbM94V6QkaPxUM6J7UNBnSYlXMT3ScEpmby5WS5gGWRNkYhNjSTp5YBZHTqBFUwhHW5Y4NzsUcUZWQxJzbkhDM5ZDT8tkQmRjUW3UdXhWT9RTcSZ7U4MHeJBXTttET6EFcOF6V0dzcyETMFF4blREMMBTa5kmT7M5ZZ5WVTlFZsZXRjJFN62WMYtWant4RrQ6aTV6bsBla5l7cyBTYmJkSZdzVKdmU7ljSThlWoxmR5UETsFXRKRUMGJ7TGljQap7VkJUQyk5aiojITJCLiAzNCZzMBVjI0ICSiwSMwATOwcTO7AjM0IicfJye#4Xfd5nIIlkSCJiOiMkIsICOx8idgMlSgQWYlJHcTJiOi8kI1tlOiQmcQJCLiEzMzEzNwAyNygDM5IDMyIiOiQncDJCLi46bj9CcjZXZzJiOiMXbEJCLiU8lsX1sqHJpsHLhszrgsLiOiEmTDJCLiIjMzUTN5UTM6IzN6QzN6IiOiQWSiwSfdJCdlVGaTRncvBXZSJCLiQnchh6QhRXYEJCLiUGbiFGV43mdpBlIsICdlVGaTRHduF6RislOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPBNzSB54M8MVYtVFcSZUczZHTh3yZUl5LuZFdOl6b7gXTThlcL54Z7JXQyhTY6YHN74GRBNFSP34c6lVTBtCNFhVZSNFe9UHWGJUadcRV"
+
# === 기간계 시스템 연동 설정 ===
ERP_API_URL=https://erp.example.com/api/vendors
diff --git a/components/form-data/spreadJS-dialog.tsx b/components/form-data/spreadJS-dialog.tsx
index 14f4d3ea..fbeceaf3 100644
--- a/components/form-data/spreadJS-dialog.tsx
+++ b/components/form-data/spreadJS-dialog.tsx
@@ -12,6 +12,7 @@ import { updateFormDataInDB } from "@/lib/forms/services";
import { Loader, Save, AlertTriangle } from "lucide-react";
import '@mescius/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css';
import { DataTableColumnJSON, ColumnType } from "./form-data-table-columns";
+import { setupSpreadJSLicense } from "@/lib/spread-js/license-utils";
const SpreadSheets = dynamic(
() => import("@mescius/spread-sheets-react").then(mod => mod.SpreadSheets),
@@ -26,8 +27,9 @@ const SpreadSheets = dynamic(
}
);
-if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_SPREAD_LICENSE) {
- GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREAD_LICENSE;
+// 도메인별 라이선스 설정
+if (typeof window !== 'undefined') {
+ setupSpreadJSLicense(GC);
}
interface TemplateItem {
diff --git a/components/spread-js/dataBinding.tsx b/components/spread-js/dataBinding.tsx
index b619f9f2..35b9ab28 100644
--- a/components/spread-js/dataBinding.tsx
+++ b/components/spread-js/dataBinding.tsx
@@ -6,9 +6,12 @@ import GC from "@mescius/spread-sheets";
import "@mescius/spread-sheets-resources-ko";
import { SpreadSheets } from "@mescius/spread-sheets-react";
+import { setupSpreadJSLicense } from "@/lib/spread-js/license-utils";
+
GC.Spread.Common.CultureManager.culture("ko-kr");
-GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREAD_LICENSE
-GC.Spread.Sheets.Designer.LicenseKey = process.env.NEXT_PUBLIC_DESIGNER_LICENSE
+
+// 도메인별 라이선스 설정
+setupSpreadJSLicense(GC);
const DataBinding = () => {
let spread = null;
diff --git a/components/spread-js/testSheet.tsx b/components/spread-js/testSheet.tsx
index 02347b00..5be6a215 100644
--- a/components/spread-js/testSheet.tsx
+++ b/components/spread-js/testSheet.tsx
@@ -26,13 +26,13 @@ import {
exportJSON,handleFileImport
} from "@/lib/spread-js/fns";
import { Button } from "@/components/ui/button";
+import { setupSpreadJSLicense } from "@/lib/spread-js/license-utils";
// SpreadJS 라이선싱
-// var SpreadJSKey = "xxx"; // 라이선스 키 입력
-// GC.Spread.Sheets.LicenseKey = SpreadJSKey;
GC.Spread.Common.CultureManager.culture("ko-kr");
-GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREAD_LICENSE
-GC.Spread.Sheets.Designer.LicenseKey = process.env.NEXT_PUBLIC_DESIGNER_LICENSE
+
+// 도메인별 라이선스 설정
+setupSpreadJSLicense(GC);
export default function SpreadSheet() {
const [spread, setSpread] = useState(null);
diff --git a/lib/spread-js/license-utils.ts b/lib/spread-js/license-utils.ts
new file mode 100644
index 00000000..1f586c50
--- /dev/null
+++ b/lib/spread-js/license-utils.ts
@@ -0,0 +1,83 @@
+/**
+ * SpreadJS 라이선스 관리 유틸리티
+ * 도메인에 따라 적절한 라이선스 키를 반환합니다.
+ */
+
+/**
+ * 현재 도메인을 기반으로 적절한 SpreadJS 라이선스 키를 반환합니다.
+ *
+ * @returns 도메인에 맞는 라이선스 키 또는 null
+ */
+export function getSpreadJSLicenseKey(): string | null {
+ // 서버 사이드에서는 라이선스를 설정하지 않음
+ if (typeof window === 'undefined') {
+ return null;
+ }
+
+ const hostname = window.location.hostname;
+
+ // partners.sevcp.com 도메인 (케이스1)
+ if (hostname === 'partners.sevcp.com') {
+ return process.env.NEXT_PUBLIC_SPREAD_LICENSE || null;
+ }
+
+ // sevcp.com 도메인 (케이스2)
+ if (hostname === 'sevcp.com') {
+ return process.env.NEXT_PUBLIC_SPREAD_LICENSE_SEVCP || process.env.NEXT_PUBLIC_SPREAD_LICENSE || null;
+ }
+
+ // 개발 환경 (localhost)
+ if (hostname === 'localhost' || hostname === '127.0.0.1') {
+ // 개발 환경에서는 기본 라이선스 사용
+ return process.env.NEXT_PUBLIC_SPREAD_LICENSE || null;
+ }
+
+ // 기타 도메인의 경우 기본 라이선스 사용
+ return process.env.NEXT_PUBLIC_SPREAD_LICENSE || null;
+}
+
+/**
+ * SpreadJS Designer 라이선스 키를 반환합니다.
+ * Designer 라이선스는 도메인 구분 없이 항상 동일한 라이선스를 사용합니다.
+ *
+ * @returns Designer 라이선스 키 또는 null
+ */
+export function getSpreadJSDesignerLicenseKey(): string | null {
+ // 서버 사이드에서는 라이선스를 설정하지 않음
+ if (typeof window === 'undefined') {
+ return null;
+ }
+
+ // Designer 라이선스는 도메인 구분 없이 항상 동일한 라이선스 사용
+ return process.env.NEXT_PUBLIC_DESIGNER_LICENSE || null;
+}
+
+/**
+ * SpreadJS 라이선스를 설정합니다.
+ * GC 객체가 로드된 후에 호출해야 합니다.
+ *
+ * @param GC - SpreadJS GC 객체
+ */
+export function setupSpreadJSLicense(GC: any): void {
+ if (typeof window === 'undefined') {
+ return;
+ }
+
+ const spreadLicense = getSpreadJSLicenseKey();
+ const designerLicense = getSpreadJSDesignerLicenseKey();
+
+ // SpreadSheets 라이선스 설정
+ if (spreadLicense && GC?.Spread?.Sheets) {
+ GC.Spread.Sheets.LicenseKey = spreadLicense;
+
+ // ExcelIO 라이선스 설정 (있는 경우)
+ if (typeof (window as any).ExcelIO !== 'undefined') {
+ (window as any).ExcelIO.LicenseKey = spreadLicense;
+ }
+ }
+
+ // Designer 라이선스 설정
+ if (designerLicense && GC?.Spread?.Sheets?.Designer) {
+ GC.Spread.Sheets.Designer.LicenseKey = designerLicense;
+ }
+}