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 @@
+ + 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