본문 바로가기
Study/라이브러리

[라이브러리] exceljs를 활용하여 JS데이터를 엑셀 파일로 추출해 보자.

by 박히밍 2023. 6. 28.
반응형

[라이브러리] exceljs를 활용하여 JS데이터를 엑셀 파일로 추출해 보자.

 

서론

사내에서 React 환경에서 CMS 개발 파트 담당하다보니, 드디어 테이블 데이터를 추출하여 엑셀 파일로 다운로드 받을 수 있는 기능을 구현하게 되었다. 넘넘 신나고 재밌서..! 😎

 

 

exceljs를 활용하여 JS데이터를 엑셀 파일로 추출해 보자.

 

 

 


 

 

 

 

exceljs란?

exceljs란 javascript에서 데이터를 엑셀로 추출 및 조작할 수 있는 node 환경 라이브러리로, 특정 셀의 스타일을 커스텀하고 합칠 수 있는 장점이 있는 라이브러리이다.

 

 

 

공식문서 링크

npm exceljs 링크

 

exceljs

Excel Workbook Manager - Read and Write xlsx and csv Files.. Latest version: 4.3.0, last published: 2 years ago. Start using exceljs in your project by running `npm i exceljs`. There are 1010 other projects in the npm registry using exceljs.

www.npmjs.com

 

 

npm file-saver 링크

 

file-saver

An HTML5 saveAs() FileSaver implementation. Latest version: 2.0.5, last published: 3 years ago. Start using file-saver in your project by running `npm i file-saver`. There are 4053 other projects in the npm registry using file-saver.

www.npmjs.com

 

 

 

 


 

 

 

설치방법

npm i exceljs 

npm i file-saver

exceljs는 데이터를 excel 형식으로 데이터를 조작 가공하여 파일을 생성할 뿐 클라이언트단에서 자체 다운로드 기능을 제공하지 않기 때문에 exceljs를 다운로드 하신 뒤에는 file-saver를 다운로드 해서 사용해주세요.

 

 

 

 

import 방식

import * as Excel from "exceljs/dist/exceljs.min.js";
import { saveAs } from "file-saver";

 

 

 

 

 

기본 사용법

// 여러 엑셀 시트를 포함하는 하나의 workbook(단위) 생성
const wb = new Excel.Workbook();

// 엑셀 sheet 생성
const sheet = wb.addWorksheet("sheet name");

참고: cell의 width나 height 단위는 픽셀이 아닌 너비 기준이다.

 

 

 

 

 


 

 

 

 

 

적용 예제

import * as Excel from "exceljs/dist/exceljs.min.js";
import { saveAs } from "file-saver";

// 데이터 배열 
const list = [
  {
    orderNum: "A309012",
    menu: "햄버거",
    price: 12000,
    date: "2023-05-01",
  },
  {
    orderNum: "B882175",
    menu: "아메리카노(ice)",
    price: 1900,
    date: "2023-05-17",
  },
  {
    orderNum: "B677919",
    menu: "떡볶이",
    price: 6000,
    date: "2023-05-28",
  },
  {
    orderNum: "A001092",
    menu: "마라탕",
    price: 28000,
    date: "2023-06-12",
  },
  {
    orderNum: "A776511",
    menu: "후라이드치킨",
    price: 18000,
    date: "2023-06-12",
  },
  {
    orderNum: "A256512",
    menu: "고급사시미",
    price: 289900,
    date: "2023-06-12",
  },
  {
    orderNum: "C114477",
    menu: "단체도시락",
    price: 1000000,
    date: "2023-06-19",
  },
];

// TH에 들어갈 텍스트 데이터
const headers = ["주문번호", "메뉴", "가격", "주문날짜"];
// TH width, 단위는 cell의 width나 height 단위는 픽셀이 아닌 엑셀의 너비 기준이다.
const headerWidths = [40, 16, 16, 24];

function App() {
  const downloadList = async (rows) => {
    try {
      //console.log(rows);
			
			// workbook 생성
      const wb = new Excel.Workbook();
			// sheet 생성
      const sheet = wb.addWorksheet("배달 주문 내역");

      // 상단 헤더(TH) 추가
      const headerRow = sheet.addRow(headers);
      // 헤더의 높이값 지정
      headerRow.height = 30.75;
      // 각 헤더 cell에 스타일 지정
      headerRow.eachCell((cell, colNum) => {
        styleHeaderCell(cell);
        sheet.getColumn(colNum).width = headerWidths[colNum - 1];
      });

      // 각 Data cell에 데이터 삽입 및 스타일 지정
      rows.forEach(({ orderNum, menu, price, date }) => {
        const rowDatas = [orderNum, menu, price, date];
        const appendRow = sheet.addRow(rowDatas);

        appendRow.eachCell((cell, colNum) => {
          styleDataCell(cell, colNum);
          if (colNum === 1) {
            cell.font = {
              color: { argb: "ff1890ff" },
            };
          }
          if (colNum === 3) {
            cell.numFmt = "0,000";
          }
        });
      });

      // 파일 생성
      const fileData = await wb.xlsx.writeBuffer(); //writeBuffer는 프로미스를 반환하므로 async-await을 사용해야 한다.
      const blob = new Blob([fileData], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      });
      saveAs(blob, `배달 주문 내역`);
    } catch (error) {
      console.log(error);
    }
  };
  return (
    <div className="App">
      <button onClick={() => downloadList(list)} style={{
          padding: "4px 8px",
          background: "#0f8107",
          fontSize: "1.5em",
          color: "#fff",
          border: 0,
          cursor: "pointer",
        }}>📑 엑셀 추출</button>
    </div>
  );
}

const styleHeaderCell = (cell) => {
  cell.fill = {
    type: "pattern",
    pattern: "solid",
    fgColor: { argb: "ffebebeb" },
  };
  cell.border = {
    bottom: { style: "thin", color: { argb: "-100000f" } },
    right: { style: "thin", color: { argb: "-100000f" } },
  };
  cell.font = {
    name: "Arial",
    size: 12,
    bold: true,
    color: { argb: "ff252525" },
  };
  cell.alignment = {
    vertical: "middle",
    horizontal: "center",
    wrapText: true,
  };
};

const styleDataCell = (cell) => {
  cell.fill = {
    type: "pattern",
    pattern: "solid",
    fgColor: { argb: "ffffffff" },
  };
  cell.border = {
    bottom: { style: "thin", color: { argb: "-100000f" } },
    right: { style: "thin", color: { argb: "-100000f" } },
  };
  cell.font = {
    name: "Arial",
    size: 10,
    color: { argb: "ff252525" },
  };
  cell.alignment = {
    vertical: "middle",
    horizontal: "center",
    wrapText: true,
  };
};

export default App;

 

엑셀 파일이 다운로드 되는 모습

 

 

다운로드 된 엑셀 파일 데이터의 모습

반응형