yarn add xlsx-js-style
스타일 없이 엑셀 다운로드만 하려고 하면 간단히 구현 가능하다
실제로 몇 분 안걸렸다!
그때는 스타일 줄 생각을 안하고 있어서 xlsx로 진행했는데 xlsx-js-style이 xlsx 포크해서 개발된거라 api가 거의 동일하다
만약 스타일 적용 안하고 간단하게만 사용할 예정이라면 xlsx 공식문서
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz or yarn add https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz
아래는 추출 할 데이터이다.
const header = [ '배송지 구분 번호', '배송지명', '배송지 주소', '수령인', '택배사', '송장번호', '비고', ]; const body = [ { deliveryTypeNumber: '1', deliveryName: '서울', deliveryAddress: '서울시 강남구', recipient: '홍길동', courierCompany: 'CJ대한통운', trackingNumber: '1234567890', notes: '특별 요청 없음', }, { deliveryTypeNumber: '2', deliveryName: '부산', deliveryAddress: '부산시 해운대구', recipient: '김철수', courierCompany: '한진택배', trackingNumber: '0987654321', notes: '빠른 배송 요청', }, { deliveryTypeNumber: '3', deliveryName: '대구', deliveryAddress: '대구시 수성구', recipient: '이영희', courierCompany: '롯데택배', trackingNumber: '1122334455', notes: '문 앞에 놓아주세요', }, ];
import { utils, WorkBook, writeFileXLSX } from 'xlsx'; // xlsx-js-style 동일 const ExportExcel = () => { const handleExport = useCallback(() => { const wb:WorkBook = utils.table_to_book([...header,...body]); writeFileXLSX(wb, '파일명.xlsx'); }, []); return ( <div className="w-120pxr"> <Button onClick={handleExport}>Export</Button> </div> ); }; export default ExportExcel;
간단히는 이렇게 가능하다
만약 시트를 생성해서 시트명과 함께 파일로 추출하고 싶다면
import { utils, WorkBook, writeFileXLSX } from 'xlsx'; // xlsx-js-style 동일 const ExportExcel = () => { const handleExport = useCallback(() => { const ws = utils.aoa_to_sheet([...header,...body]); const wb: WorkBook = utils.book_new(); utils.book_append_sheet(wb, ws, '원하는 시트명'); writeFileXLSX(wb, '파일명.xlsx'); }, []); return ( <div className="w-120pxr"> <Button onClick={handleExport}>Export</Button> </div> ); }; export default ExportExcel;
이렇게 시트 생성 후 파일 추출할 수도 있다.
근데 스타일을 주려고 하니까 xlsx에서는 지원하지 않는게 많아서(아마 pro를 사용해야 하는 듯;)
xlsx-js-style라이브러리를 사용했다
설치방법은 최상단에 적어뒀으니까 생략하고
import { utils, WorkBook , writeFile } from 'xlsx-js-style'; const ExportExcel = () => { const handleExport = useCallback(() => { const ws = utils.aoa_to_sheet([...header,...body]); const borderStyle = { top: { style: 'thin', color: { rgb: '000000' } }, bottom: { style: 'thin', color: { rgb: '000000' } }, left: { style: 'thin', color: { rgb: '000000' } }, right: { style: 'thin', color: { rgb: '000000' } }, }; // 헤더 스타일 header.forEach((_, colIdx) => { const addr = utils.encode_cell({ r: 0, c: colIdx }); if (ws[addr]) { ws[addr].s = { fill: { fgColor: { rgb: 'D9D9D9' } }, font: { bold: true }, border: borderStyle, alignment: { horizontal: 'center', vertical: 'center' }, }; } }); // body 스타일 for (let r = 1; r < wsData.length; r++) { for (let c = 0; c < header.length; c++) { const addr = utils.encode_cell({ r, c }); if (ws[addr]) { ws[addr].s = { border: borderStyle, alignment: { vertical: 'center', horizontal: 'left' }, }; } } } // 열 너비 const colWidths = [100, 80, 300, 80, 100, 80, 120, 150]; ws['!cols'] = header.map((_, idx) => ({ wpx: colWidths[idx] ?? 80, })); const wb: WorkBook = utils.book_new(); utils.book_append_sheet(wb, ws, '원하는 시트명'); writeFile(wb, '파일명.xlsx'); }, []); return ( <div className="w-120pxr"> <Button onClick={handleExport}>Export</Button> </div> ); }; export default ExportExcel;
여기서 스타일 적용을 위해 가~~~장 중요한건
위의 xlsx 라이브러리 사용할때와 차이점이 있다.
그 전에는 스타일을 신경쓰지 않아서 공식문서(https://docs.sheetjs.com/docs/#export-an-html-table-to-excel-xlsx)에 나온대로 writeFileXLSX를 사용했다

그런데 xlsx-js-style를 사용해도 스타일이 적용 안되고, 간단한 예제를 적용해봐도 안돼서 엄청 삽질했다..
그러던중 공식문서(https://github.com/gitbrent/xlsx-js-style/?tab=readme-ov-file#cell-style-example) 예제를 따라하는데 writeFile 를 사용하는거였다..
이렇게 간단히 해결되는 문제였다니.. 문서를 좀 더 꼼꼼히 봐야할 필요가 있다..