엑셀 파일을 업로드하고 이를 테이블로 보여줘야하는 요구사항이 생겼습니다.
하나의 파일에 해당 기능을 모두 구현한 코드입니다.
import React, {useState} from 'react';
import * as XLSX from 'xlsx';
const ExcelReader: React.FC = () => {
const [data, setData] = useState<Record<string, string>[]>([]);
const tableHead = Array.from(data.reduce((acc, cur) => {
// 키값을 모두 Set 객체에 add
Object.keys(cur).forEach(k => acc.add(k));
return acc;
}, new Set<string>()));
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
// 파일을 업로드 했을 때의 처리
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (evt) => {
const bstr = evt.target?.result as string;
const wb = XLSX.read(bstr, {type: 'binary'});
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const data: Record<string, string>[] = XLSX.utils.sheet_to_json(ws);
setData(data);
};
reader.readAsBinaryString(file);
}
};
return (
<div>
<input type='file' onChange={handleFileUpload} />
<table>
<thead>
<tr>
{tableHead.map((value) => (
<td key={value}>{value}</td>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i}>
{tableHead.map((key) => (
<td key={key}>{row[key] ?? ''}</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
};
export default ExcelReader;
이 코드는 엑셀 파일을 업로드하고, 그 내용을 웹 페이지의 테이블로 나타내는 기본적인 기능을 구현한 것입니다.
화면은 다음과 같이 나타납니다.
[파일 선택전]
[파일 선택 후]
React에서 엑셀 파일을 업로드하고, 그 내용을 웹 페이지의 테이블로 나타내는 작업은 다음과 같은 단계로 구성했습니다.:
파일 업로드: 사용자가 엑셀 파일을 웹 페이지에 업로드할 수 있도록 input 태그를 사용하여 파일 업로드 기능을 구현합니다.
파일 읽기: 업로드된 파일을 읽기 위해 FileReader 객체를 사용합니다. 이 객체는 웹 애플리케이션에서 비동기적으로 데이터를 읽을 수 있게 해줍니다.
엑셀 파싱: 'xlsx' 라이브러리를 사용하여 엑셀 파일을 파싱합니다. 이 라이브러리는 엑셀 파일을 JSON 형식으로 변환해줍니다.
테이블 렌더링: 파싱된 데이터를 기반으로 React 컴포넌트 내에서 테이블을 렌더링합니다.
파일 업로드 컴포넌트와 데이터를 보여주는 테이블 컴포넌트를 나누면 다음과 같이 만들 수 있습니다.
// FileUpload.tsx
import React from 'react';
import * as XLSX from 'xlsx';
interface FileUploadProps {
onFileUpload: (data: Record<string, string>[]) => void;
}
const FileUpload: React.FC<FileUploadProps> = ({onFileUpload}) => {
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
const reader = new FileReader();
reader.onload = (evt) => {
const bstr = evt.target?.result as string;
const wb = XLSX.read(bstr, {type: 'binary'});
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const data: Record<string, string>[] = XLSX.utils.sheet_to_json(ws);
onFileUpload(data);
};
reader.readAsBinaryString(file);
}
};
return <input type='file' onChange={handleFileUpload} />;
};
export default FileUpload;
// DataTable.tsx
import React from 'react';
interface DataTableProps {
data: Record<string, string>[];
}
const DataTable: React.FC<DataTableProps> = ({data}) => {
const tableHead = Array.from(data.reduce((acc, cur) => {
Object.keys(cur).forEach(k => acc.add(k));
return acc;
}, new Set<string>()));
return (
<table>
<thead>
<tr>
{tableHead.map((value) => (
<td key={value}>{value}</td>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i}>
{tableHead.map((key) => (
<td key={key}>{row[key] ?? ''}</td>
))}
</tr>
))}
</tbody>
</table>
);
};
export default DataTable;
// ExcelReader.tsx
import React, {useState} from 'react';
import FileUpload from './FileUpload';
import DataTable from './DataTable';
const ExcelReader: React.FC = () => {
const [data, setData] = useState<Record<string, string>[]>([]);
return (
<div>
<FileUpload onFileUpload={setData} />
<DataTable data={data} />
</div>
);
};
export default ExcelReader;