2023. 4. 28. 11:02ㆍLibrary/React
일을 하다보면 값을 일일히 쳐서 데이터를 밀어넣는 경우보다 엑셀을 이용해 일괄로 데이터를 등록해야하는 경우가 있다.
이번 포스트는 리액트에서 엑셀을 업로드해 엑셀 내 데이터를 간단하게 다뤄보는 글을 써보려고 한다.
ReactJS | SheetJS Community Edition
ReactJS | SheetJS Community Edition
ReactJS is a JS library for building user interfaces.
docs.sheetjs.com
npm i --save https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz
0. 전체 코드
import React, { useState } from 'react';
import * as XLSX from 'xlsx'
const Excel = () => {
const [result, setResult] = useState([]);
const excelHandle = (e) => {
const reader = new FileReader();
reader.onload = (e) => {
console.log(e)
let data = e.target.result;
console.log(data);
const sheets = XLSX?.read(data,{type:"binary"});
console.log(sheets)
console.log(sheets.Sheets)
console.log(sheets.SheetNames)
const sheet = sheets.Sheets[sheets.SheetNames[0]]
console.log(sheet)
const sheet1_json = XLSX.utils.sheet_to_json(sheets.Sheets[sheets.SheetNames[0]]);
console.log(sheet1_json)
const sheet2_html = XLSX.utils.sheet_to_html(sheets.Sheets[sheets.SheetNames[1]])
console.log(sheet2_html)
let mutResult = [];
let sheet2 = sheets.Sheets[sheets.SheetNames[0]]
let row, rowNum, colNum;
let range = XLSX.utils.decode_range(sheet2["!ref"]);
for(rowNum = range.s.r; rowNum <= range.e.r; rowNum++){
row = [];
for (colNum = range.s.c; colNum <= range.e.c; colNum++){
var nextCell = sheet2[XLSX.utils.encode_cell({r:rowNum, c:colNum})]
if(typeof nextCell ==='undefined'){
row.push(<td>{}</td>)
}else{
row.push(<td>{nextCell.w}</td>);
}
}
mutResult.push(<tr>{row}</tr>)
}
setResult(mutResult)
}
reader.readAsBinaryString(e.target.files[0])
}
return (
<>
<div class="contents">
<input
type='file'
onChange={(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.files)
excelHandle(e)
}}
/>
<table>
<tbody>
{result}
</tbody>
</table>
</div>
</>
);
};
export default Excel;
1. input 태그 내 엑셀파일
import React from 'react';
import * as XLSX from 'xlsx'
const Excel = () => {
return (
<div>
<input
type='file'
onChange={(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.files)
}}
/>
</div>
);
};
export default Excel;
먼저 input 태그를 만들어 파일을 업로드하고 로그를 찍어보면
- e : 이벤트 객체
- e.target : 이벤트가 발생한 타겟
- e.target.files : 해당 태그 내 파일이 들어있는 배열
이 콘솔에 찍힌 것을 확인할 수 있다.
그렇다면 우리는 e.target.files 배열에 들어있는 엑셀 파일을 다루면 되겠고
보통은 e.target.files[0] 을 통해 꺼내오거나
다중파일업로드를 이용하는 사람이라면 원하는 배열 인덱스 혹은 반복문을 통해 해당 파일을 다루면 되겠다.
2. 엑셀파일 읽기
import React from 'react';
import * as XLSX from 'xlsx'
const Excel = () => {
const excelHandle = (e) => {
const reader = new FileReader();
reader.onload = (e) => {
}
reader.readAsBinaryString(e.target.files[0])
}
return (
<div>
<input
type='file'
onChange={(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.files)
excelHandle(e)
}}
/>
</div>
);
};
export default Excel;
인풋 태그에 파일이 올라가면 excelHandle 함수가 실행된다.
해당 함수 내에서는 먼저 FileReader를 생성해준 후 onload 함수를 정의해준다.
이후 FileReader의 readAsBinaryString함수를 실행해주면 onload 함수가 돌기때문에
우리는 onload함수 내에서 원하는 작업을 처리할 것이다.
readAsBinaryString 함수의 파라미터로 엑셀파일을 넘겨준다.
3. 엑셀 내 데이터 다루기
먼저 다뤄볼 엑셀은 과일과 자동차 시트를 가지고 있다.
reader.onload = (e) => {
console.log(e)
let data = e.target.result;
console.log(data);
const sheets = XLSX.read(data,{type:"binary"});
console.log(sheets)
console.log(sheets.Sheets)
console.log(sheets.SheetNames)
}
로그를 찍어보면
파라미터로 넘어온 데이터중 우리가 필요한 엑셀 내부 데이터는 e.target.result 안에 들어있는 것을 확인할 수 있다.
이를 sheet.js에서 제공하는 함수를 이용해 읽어보면 (XLSX.read(data,{type:"binary"}))
sheets 변수에 엑셀파일에 대한 정보가 담겨있는 것을 확인할 수 있으며
sheets의 키값 중 Sheets에 현재 가지고있는 시트들이 객체로,
SheetNames에 시트들의 이름이 배열로 담겨있는 것을 확인할 수 있다.
우리가 필요한 각 셀들의 데이터는
Sheets 객체에 시트이름이 키, 시트 내용이 값으로 들어있으며,
시트내용은 또한번 셀번호가 키, 데이터가 값으로 들어있다.
우리는 시트이름을 이용해 전체 시트중 원하는 시트의 데이터를 가져오면 된다.
reader.onload = (e) => {
console.log(e)
let data = e.target.result;
console.log(data);
const sheets = XLSX?.read(data,{type:"binary"});
console.log(sheets)
console.log(sheets.Sheets)
console.log(sheets.SheetNames)
const sheet = sheets.Sheets[sheets.SheetNames[0]]
const sheet1_json = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
console.log(web)
const sheet2_html = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[1]])
console.log(html)
}
sheet.js에서 제공하는 함수를 이용해 시트내용을 json객체 혹은 html로 변환할 수 있다.
sheet_to_json : 시트 정보를 파라미터로 받아 json 객체를 리턴한다.
sheet_to_html : 시트 정보를 파라미터로 받아 html을 반환한다.
시트정보는 전체 시트내용 중 시트이름을 키값으로 꺼내와 사용했다.
위는 sheet_to_json, 아래는 sheet_to_html의 결과로
원하는 데이터를 갖다 쓰면 된다.
현재 엑셀은 가장 위에 속성명이 적혀있기 때문에 json으로 변환할 때 자동으로 키값이 설정되지만
엑셀 내 데이터 형태에 따라 json으로 변환하기 애매할 때가 있다.
그럴 경우 각 셀을 가져와 배열을 돌려 원하는대로 만들 수 있다.
reader.onload = (e) => {
console.log(e)
let data = e.target.result;
console.log(data);
const sheets = XLSX?.read(data,{type:"binary"});
console.log(sheets)
console.log(sheets.Sheets)
console.log(sheets.SheetNames)
const sheet = sheets.Sheets[sheets.SheetNames[0]]
console.log(sheet)
const sheet1_json = XLSX.utils.sheet_to_json(sheets.Sheets[sheets.SheetNames[0]]);
console.log(sheet1_json)
const sheet2_html = XLSX.utils.sheet_to_html(sheets.Sheets[sheets.SheetNames[1]])
console.log(sheet2_html)
let mutResult = [];
let sheet2 = sheets.Sheets[sheets.SheetNames[0]]
let row, rowNum, colNum;
let range = XLSX.utils.decode_range(sheet2["!ref"]);
for(rowNum = range.s.r; rowNum <= range.e.r; rowNum++){
row = [];
for (colNum = range.s.c; colNum <= range.e.c; colNum++){
var nextCell = sheet2[XLSX.utils.encode_cell({r:rowNum, c:colNum})]
if(typeof nextCell ==='undefined'){
row.push(<td>{}</td>)
}else{
row.push(<td>{nextCell.w}</td>);
}
}
mutResult.push(<tr>{row}</tr>)
}
setResult(mutResult)
}
'Library > React' 카테고리의 다른 글
리액트 엑셀 다운로드 (0) | 2023.04.28 |
---|---|
fetch 페치란 (0) | 2023.03.29 |
axios 액시오스란 (0) | 2023.03.29 |
리액트 DB데이터로 메뉴 트리뷰 만들기 (0) | 2023.03.29 |
리액트 페이징 처리 (0) | 2023.03.29 |