import { Upload, message, ... } from 'antd';
import * as XLSX from 'xlsx';
function UploadOrderList() {
const [uploadFileName, setUploadFileName] = useState('');
const handleBeforeUpload = useCallback((file) => {
...자세한 로직은 아래에
}, []);
const handleOnChange = useCallback(
(info) => {
const status = info.file.status;
if (status === 'done') {
setUploadFileName(info.file.name);
....파일 업로드 성공 후 작업
} else if (status === 'error') {
message.error(`${info.file.name} 파일 업로드에 실패하였습니다. 다시 시도해주세요.`);
}
},
[],
);
useEffect(() => {
if (uploadFileName) {
message.success(`${uploadFileName} 파일 업로드에 성공하였습니다.`);
}
}, [uploadFileName]);
const props = {
name: 'file',
multiple: true,
showUploadList: false,
maxCount: 1,
beforeUpload: handleBeforeUpload,
onChange: handleOnChange,
};
return(
<Dragger {...props}>
...
</Dragger>
);
}
export default UploadOrderList;
File 객체를 읽는 handleBeforeUpload를 자세히 살펴보자.
File객체에 숨어있는 데이터를 FileReader API를 통해 읽는다.
new FileReader()를 통해 파일리더를 만들고,
onload 이벤트 핸들러를 붙여서 콜백으로 파일을 다 읽었다는 것을 알려주도록 하고 있다.
다음은 파일을 읽는 방법 중 readAsArrayBuffer를 사용한 예시이다.
ArrayBuffer 객체는 데이터를 일정한 크기로 조금 조금씩 서버로 보낼 때 사용한다.
const handleBeforeUpload = useCallback(
(file) => {
let fileExt = file.name.split('.');
fileExt = fileExt[fileExt.length - 1];
const reader = new FileReader();
if (fileExt === 'xlsx' || fileExt === 'xls' || fileExt === 'csv') {
reader.readAsArrayBuffer(file);
reader.onload = (evt) => {
// evt = on_file_select event
const bstr = evt.target.result;//file data
console.log('bstr', bstr);
const wb = XLSX.read(bstr, { type: 'array', cellDates: true });
const firstSheetName = wb.SheetNames[0];
if (firstSheetName) {
const firstSheet = wb.Sheets[firstSheetName];
const range = XLSX.utils.decode_range(firstSheet['!ref']);//엑셀 열의 갯수를 파악하기
...엑셀데이터를 가지고 원하는 작업 진행하기
} else {
//엑셀파일양식 중 fileData가 html으로 읽혀서 들어오는 경우가 있어 readAsBinaryString로 처리해준다.
reader.readAsBinaryString(file);//이진데이터로 반환하기
reader.onload = () => {
const bstr = reader.result;
const wb = XLSX.read(bstr, { type: 'binary' });
const firstSheetName = wb.SheetNames[0]; // 첫번째 시트명
const firstSheet = wb.Sheets[firstSheetName]; // 첫번째 시트
const range = XLSX.utils.decode_range(firstSheet['!ref']);//엑셀 열의 갯수를 파악하기
...엑셀데이터를 가지고 원하는 작업 진행하기
};
}
};
} else {
//확장자가 xlsx, xls, csv가 아닌 경우 에러 처리하기
return false;
}
},
[],
);
구현된 화면은 다음과 같다.
Button을 클릭하면 handleDownloadInvoice함수가 실행되고 GetBatchInfos요청이 서버로 간다.(redux-toolkit 사용함)
요청이 성공했을 때 서버로부터 받아온 응답값이 BatchInfosList에 담긴다.
이 데이터를 makeInvoiceExcelDataLists 함수에서 엑셀형식에 맞게 invoiceData에 담는다.
아래의 예시에서는 xls, csv, xlsx 세가지 형식으로 엑셀파일이 다운받아진다.
import * as XLSX from 'xlsx';
const BatchOrderStatusLists = ()=>{
const makeInvoiceExcelDataLists = (BatchInfosList) => {
let invoiceData = [];
if (openmarketKind === 'cafe24') {
for (let i = 0; i < BatchInfosList.length; i++) {
invoiceData.push({
주문번호: BatchInfosList[i].Order.OrderID,
품목번호: BatchInfosList[i].ProductOrder.ProductID,
'품목별 주문번호': `${BatchInfosList[i].Order.OrderID}+${i % 10 ? '0' + i : i}`,
운송장번호: BatchInfosList[i].trackingNumber,
});
}
return invoiceData;
}
useEffect(() => {
const invoiceData = makeInvoiceExcelDataLists(BatchInfosList);
if (invoiceData) {
/* make the worksheet */
const ws = XLSX.utils.json_to_sheet(invoiceData);
/* add to workbook */
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, '발송처리');//시트 이름을 '발송처리'로 한다.
XLSX.writeFile(wb, `modument_${BatchInfosList[0]?.openmarketKind.toLowerCase()}_invoice.xls`, {
bookType: 'biff8', //Microsoft Office Excel 97-2003 Binary File Format, xls
})
XLSX.writeFile(wb, `modument_${BatchInfosList[0]?.openmarketKind.toLowerCase()}_invoice.csv`, {
bookType: 'csv',
})
XLSX.writeFile(wb, `modument_${BatchInfosList[0]?.openmarketKind.toLowerCase()}_invoice.xlsx`);
}
}
}, [ BatchInfosList]);
const handleDownloadInvoice = useCallback(
(batchNumber) => (e) => {
dispatch(GetBatchInfos({ batchNumber }));//서버에 요청보내기
},
[],
);
return(
<Button onClick={handleDownloadInvoice(text.batchNumber)}>송장번호 일괄등록 엑셀다운로드</Button>
);
...
}
export default BatchOrderLists;
다운로드된 csv형식의 엑셀은 다음과 같은 모양이 된다.
출처:
https://eblo.tistory.com/83
https://www.zerocho.com/category/HTML&DOM/post/592827558653d6001804a0a5
https://developer.mozilla.org/ko/docs/Web/API/FileReader