From 7ad064138dfed1c2d59722062e1fca85e2c50705 Mon Sep 17 00:00:00 2001 From: minuk926 Date: Fri, 1 Apr 2022 16:46:20 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=97=91=EC=85=80=EB=8B=A4=EC=9A=B4?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/views/biz/parking/Regist.jsx | 9 ++- src/views/form/CustomPagination.js | 2 +- src/views/form/ExcelDownload.jsx | 103 +++++++++++++++++++++++++++++ src/views/form/MuiDataGrid.jsx | 6 +- 5 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 src/views/form/ExcelDownload.jsx diff --git a/package.json b/package.json index 94b610c..91c9c22 100755 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "date-fns": "^2.28.0", "draft-js": "^0.11.7", "emoji-picker-react": "^3.5.1", + "exceljs": "^4.3.0", "file-saver": "^2.0.5", "formik": "^2.2.9", "framer-motion": "^4.1.13", diff --git a/src/views/biz/parking/Regist.jsx b/src/views/biz/parking/Regist.jsx index 57933fd..9b61458 100644 --- a/src/views/biz/parking/Regist.jsx +++ b/src/views/biz/parking/Regist.jsx @@ -1,10 +1,13 @@ import { useState } from 'react'; +import * as Excel from 'exceljs'; +import saveAs from 'file-saver'; + // material-ui import { Button, Divider, FormControl, FormControlLabel, FormLabel, Grid, Radio, RadioGroup, TextField } from '@mui/material'; // assets -import { IconSearch } from '@tabler/icons'; +import { IconSearch, IconFileExport } from '@tabler/icons'; import PersonAddTwoToneIcon from '@mui/icons-material/PersonAddTwoTone'; // berry ui @@ -18,6 +21,7 @@ import xitCmm from '../../../commons/XitCmm'; import CmmModal from '../../form/Modal/CmmModal'; import SaveParkingSimsaForm from './SaveParkingSimsaForm'; import NumberFormat from 'react-number-format'; +import ExcelDownload from '../../form/ExcelDownload'; const ParkingRegister = () => { const [rcIrTransfer, setRcIrTransfer] = useState('1'); @@ -166,6 +170,9 @@ const ParkingRegister = () => { 저장 + + + diff --git a/src/views/form/CustomPagination.js b/src/views/form/CustomPagination.js index 9554e3c..34d84cd 100644 --- a/src/views/form/CustomPagination.js +++ b/src/views/form/CustomPagination.js @@ -41,7 +41,7 @@ const CustomPagination = ({ totalCount, pageSize }) => { }} /> )} - + {/* 전체 {totalCount} 건 현재페이지 {pageCount > 1 ? `${page * pageSize + 1} / ${totalCount} 건` : `${totalCount}`} */} {totalCount > 0 ? `전체 ${totalCount} 건 ` : ``} {pageCount > 1 ? `[ ${page + 1} / ${pageCount} ]` : ``} diff --git a/src/views/form/ExcelDownload.jsx b/src/views/form/ExcelDownload.jsx new file mode 100644 index 0000000..68bad31 --- /dev/null +++ b/src/views/form/ExcelDownload.jsx @@ -0,0 +1,103 @@ +import PropTypes from 'prop-types'; +import { IconFileExport } from '@tabler/icons'; +import { Button } from '@mui/material'; +import * as Excel from 'exceljs'; +import saveAs from 'file-saver'; + +const ExcelDownload = ({ fileName, gridColumns, excelDatas }) => { + const handleExcelDownload = () => { + const workbook = new Excel.Workbook(); + const worksheet = workbook.addWorksheet('Sheet'); // sheet 이름이 My Sheet + /* + // subject + worksheet.mergeCells('A2:I2'); + const customCell = worksheet.getCell('A2'); + customCell.font = { + name: 'Comic Sans MS', + family: 4, + size: 20, + underline: true, + bold: true + }; + customCell.value = 'Subject'; +*/ + const headerRow = worksheet.addRow(); + worksheet.getRow(1).font = { bold: true }; + + gridColumns.forEach((col, idx) => { + const currentColumnWidth = col.width; + worksheet.getColumn(idx + 1).width = currentColumnWidth !== undefined ? currentColumnWidth / 6 : 20; + const cell = headerRow.getCell(idx + 1); + cell.value = col.headerName; + }); + + // if (this.state.excelFilterEnabled === true) { + worksheet.autoFilter = { + from: { + row: 1, + column: 1 + }, + to: { + row: 1, + column: gridColumns.length + } + }; + + worksheet.properties.outlineProperties = { + summaryBelow: false, + summaryRight: false + }; + + excelDatas.forEach((row) => { + const dataRow = worksheet.addRow(); + + // eslint-disable-next-line guard-for-in,no-restricted-syntax + for (const [k, v] of Object.entries(row)) { + // eslint-disable-next-line no-plusplus + + // eslint-disable-next-line consistent-return + gridColumns.forEach((col, idx) => { + if (col.field === k) { + const cell = dataRow.getCell(idx + 1); + cell.value = v; + return false; + } + }); + } + }); + + /* + // Footer + const rowCount = worksheet.rowCount; + worksheet.mergeCells(`A${rowCount}:I${rowCount + 1}`); + worksheet.getRow(1).font = { bold: true }; + worksheet.getCell(`A${rowCount}`).font = { + name: 'Comic Sans MS', + family: 4, + size: 20, + underline: true, + bold: true + }; + + worksheet.getCell(`A${rowCount}`).value = 'Custom Footer here'; +*/ + + workbook.xlsx.writeBuffer().then((buffer) => { + saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `${fileName}.xlsx`); + }); + }; + + return ( + + ); +}; + +ExcelDownload.propTypes = { + fileName: PropTypes.string.isRequired, + gridColumns: PropTypes.array.isRequired, + excelDatas: PropTypes.array.isRequired +}; + +export default ExcelDownload; diff --git a/src/views/form/MuiDataGrid.jsx b/src/views/form/MuiDataGrid.jsx index f90ba65..d23a3f2 100644 --- a/src/views/form/MuiDataGrid.jsx +++ b/src/views/form/MuiDataGrid.jsx @@ -90,11 +90,7 @@ MuiDataGrid.propTypes = { isCheckbox: PropTypes.bool, // isDisableSelection: PropTypes.bool, columns: PropTypes.array, - rowsState: { - page: PropTypes.number, - pageSize: PropTypes.number, - rows: PropTypes.array - }, + rowsState: PropTypes.object, totalCount: PropTypes.number, setRowsState: PropTypes.func, handleCellClick: PropTypes.func,