diff --git a/app/Config/Routes.php b/app/Config/Routes.php
index bc16274..5686df9 100644
--- a/app/Config/Routes.php
+++ b/app/Config/Routes.php
@@ -103,6 +103,7 @@ $routes->group('article', ['namespace' => 'App\Controllers\Article'], function (
*/
$routes->get('apt/ground/getAptLists', 'Ground::getAptLists');
$routes->get('apt/ground/excel', 'Ground::excel');
+ $routes->post('apt/ground/uploadExcel', 'Ground::uploadExcel');
$routes->post('apt/ground/chgAptDamdang', 'Ground::chgAptDamdang');
$routes->post('apt/ground/uploadFile', 'Ground::uploadFile');
$routes->get('apt/ground/print', 'Ground::print');
diff --git a/app/Controllers/Article/Ground.php b/app/Controllers/Article/Ground.php
index beafaae..f374494 100644
--- a/app/Controllers/Article/Ground.php
+++ b/app/Controllers/Article/Ground.php
@@ -84,6 +84,57 @@ class Ground extends BaseController
}
+ // 엑셀 업로드
+ public function uploadExcel()
+ {
+ try {
+
+ $payload = $this->request->getJSON(true);
+ $datas = $payload['datas'] ?? null;
+
+ if (count($datas) === 0) {
+ return $this->response->setJSON([
+ 'code' => '9',
+ 'msg' => "데이터 없음",
+ ]);
+ }
+
+ foreach ($datas as $data) {
+ $rdate = date("Y-m-d H:i:s");
+
+ $params = [
+ 'hscp_no' => $data[1],
+ 'region_cd' => $data[2],
+ 'part_no' => $data[0],
+ 'apt_step' => 'S01',
+ 'addr' => $data[3] . ' ' . $data[4] . ' ' . $data[5],
+ 'addr2' => $data[6],
+ 'rcpt_hscp_nm' => $data[7],
+ 'apt_cate_nm' => $data[8],
+ 'pyeong_cnt' => $data[9],
+ 'rcpt_x' => $data[10],
+ 'rcpt_y' => $data[11],
+ 'ginsert_tm' => $rdate,
+ ];
+
+ // INSERT apt_ground
+ $this->model->saveExcelUploadData($params);
+
+ }
+
+ return $this->response->setJSON([
+ 'code' => '0',
+ 'msg' => 'success'
+ ]);
+
+ } catch (\Exception $e) {
+ return $this->response->setJSON([
+ 'code' => '9',
+ 'msg' => $e->getMessage(),
+ ]);
+ }
+ }
+
// 엑셀 다운로드
public function excel()
{
diff --git a/app/Models/article/GroundModel.php b/app/Models/article/GroundModel.php
index cd57b5a..790533f 100644
--- a/app/Models/article/GroundModel.php
+++ b/app/Models/article/GroundModel.php
@@ -468,6 +468,33 @@ class GroundModel extends Model
return $query->getResultArray();
}
+ // 엑셀 업로드 저장
+ public function saveExcelUploadData($params)
+ {
+ $this->db->transStart();
+
+ $builder = $this->db->table('apt_ground');
+ $res = $builder->insert($params);
+
+ if ($res === false) {
+ return [
+ 'success' => false,
+ 'msg' => "구분코드 : {$params['part_no']} 저장실패",
+ ];
+ }
+
+ $rcpt_no = $this->db->insertID();
+
+ $this->saveHistory($rcpt_no, $params['apt_step'], 'U', 'U1', session('usr_id'));
+
+ $this->db->transComplete();
+
+ // 성공
+ return [
+ 'success' => true,
+ ];
+ }
+
// 엑셀 다운로드
public function getExcelList($data)
{
diff --git a/app/Views/pages/article/lists2.php b/app/Views/pages/article/lists2.php
index f2de5df..3b6655b 100644
--- a/app/Views/pages/article/lists2.php
+++ b/app/Views/pages/article/lists2.php
@@ -44,6 +44,15 @@
background-color: #ff0000 !important;
color: #fff !important;
}
+
+ #excelList.dataTable {
+ width: max-content !important;
+ }
+
+ table.dataTable td,
+ table.dataTable th {
+ white-space: nowrap;
+ }
아파트 평면도 내역
@@ -279,6 +288,10 @@
+
+
@@ -386,6 +399,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - 엑셀 첫 행은 헤더로 인식됩니다.
+ - 컬럼 순서 및 개수는 샘플양식과 동일해야 합니다.
+
+
+
+
+
+
+
+
+ | 구분코드 |
+ 단지코드 |
+ 법정동코드 |
+ 시/도 |
+ 시/군/구 |
+ 읍/면/동 |
+ 상세주소 |
+ 단지명 |
+ 구분명 |
+ 평수 |
+ 총동수 |
+ 경도 |
+ 위도 |
+
+
+
+
+
+
+
+
+
+
+
= $this->endSection() ?>
@@ -685,6 +761,137 @@
table.ajax.reload()
});
+ // 엑셀업로드 click
+ $("#excel-upload").on("click", function () {
+ $("#excel").val("");
+ $("#excelList").DataTable().clear().destroy();
+
+ $("#excelModal").modal("show");
+
+ });
+
+ // 엑셀 업로드
+ $("#excel").on("change", async function () {
+ const file = this.files[0];
+ if (!file) return;
+
+ const bodyRows = await readExcelBodyOnly(file);
+ renderExcelDataTable(bodyRows);
+
+ });
+
+
+ // 엑셀 업로드 저장
+ $("#btnExcelUpload").on("click", function () {
+
+ const dt = $("#excelList").DataTable();
+
+ // 전체 row 데이터 (모든 페이지)
+ const excelData = dt.rows().data().toArray();
+
+ if (excelData.length === 0) {
+ Swal.fire({
+ title: "업로드할 데이터가 없습니다.",
+ icon: "warning"
+ });
+ return;
+ }
+
+ const headers = [
+ "구분코드", "단지코드", "법정동코드"
+ , "시/도", "시/군/구", "읍/면/동", "상세주소"
+ , "단지명", "구분명", "평수", "총동수", "경도", "위도"
+ ];
+
+ const errors = [];
+ let hasError = false;
+ for (let rowIdx = 0; rowIdx < excelData.length; rowIdx++) {
+ const row = excelData[rowIdx];
+
+ for (let colIdx = 0; colIdx < headers.length; colIdx++) {
+ const colName = headers[colIdx];
+ const val = row[colIdx];
+
+
+ if (val === undefined || val === null || String(val).trim() === "") {
+ Swal.fire({
+ title: `${rowIdx + 1}행 ${colName} 데이터 누락`,
+ icon: "warning"
+ });
+
+ hasError = true;
+ break;
+ }
+ }
+
+ if (hasError) break;
+ }
+
+ if (hasError) return;
+
+ swal.fire({
+ text: "저장 하시겠습니까?",
+ type: "warning",
+ showCancelButton: true,
+ confirmButtonText: "예",
+ cancelButtonText: "아니오",
+ closeOnConfirm: false,
+ closeOnCancel: true,
+ confirmButtonColor: "#3085d6",
+ cancelButtonColor: "#d33",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ $.ajax({
+ url: '/article/apt/ground/uploadExcel',
+ contentType: 'application/json;charset=UTF-8',
+ method: 'POST',
+ data: JSON.stringify({ datas: excelData }),
+ beforeSend: function () {
+ blockUI.blockPage({
+ message: tpl
+ })
+ },
+ complete: function () {
+ blockUI.unblockPage()
+ },
+ error: function (xhr, error, thrown) {
+ blockUI.unblockPage()
+ var msg = "";
+ if (xhr.responseText != null) {
+ msg = xhr.responseText
+ } else {
+ msg = "잠시후 다시 시도해 주세요."
+ }
+
+ Swal.fire({
+ title: msg,
+ icon: "error"
+ })
+ },
+ success: function (result) {
+
+ if (result.code == '0') {
+ $("#btnSearch").trigger('click')
+ $("#excelModal").modal("hide")
+ Swal.fire({
+ title: '정상 처리되었습니다.',
+ icon: "success"
+
+ })
+ } else {
+ Swal.fire({
+ title: result.msg,
+ icon: "error"
+ })
+ }
+ }
+ });
+ }
+ });
+
+
+ });
+
// 엑셀 다운로드 click
$("#excel-download").on("click", function () {
@@ -984,6 +1191,46 @@
});
+ async function readExcelBodyOnly(file) {
+ const data = await file.arrayBuffer();
+ const wb = XLSX.read(data, { type: "array" });
+ const ws = wb.Sheets[wb.SheetNames[0]];
+
+ const rows2d = XLSX.utils.sheet_to_json(ws, {
+ header: 1,
+ defval: "",
+ raw: false
+ });
+
+ // 첫 줄(엑셀 헤더) 제거 + 빈 행 제거
+ return rows2d
+ .slice(1)
+ .filter(r => r.some(v => String(v).trim() !== ""));
+ }
+
+ function renderExcelDataTable(data2d) {
+ // 이미 DataTable이 있으면 파괴 후 재생성(컬럼 구조가 바뀔 수 있으니)
+ if ($.fn.DataTable.isDataTable("#excelList")) {
+ $("#excelList").DataTable().clear().destroy();
+ }
+
+ excelTbl = $("#excelList").DataTable({
+ language: lang_kor,
+ columnDefs: [
+ { className: 'text-center dt-nowrap', targets: '_all' },
+ ],
+ data: data2d,
+ searching: false,
+ ordering: false,
+ destroy: true,
+ deferRender: true,
+ pageLength: 10,
+ lengthMenu: [10, 25, 50, 100],
+ scrollX: true,
+ autoWidth: true,
+ });
+ }
+
function hscp_no_enter(event) {
if (event.keyCode == 13) {
table.ajax.reload()
diff --git a/public/plugin/sample/sample_apt_ground.xlsx b/public/plugin/sample/sample_apt_ground.xlsx
new file mode 100644
index 0000000..e44fed7
Binary files /dev/null and b/public/plugin/sample/sample_apt_ground.xlsx differ