상세 컨텐츠

본문 제목

엑셀(Excel) 파일 다루는 SheetJS

자바스크립트

by e7e 2024. 8. 1. 15:12

본문

스프링 서버사이드에서 Apache POI로 많이 다루는 Excel!~~

브라우져 클라이언트 사이드 자바스크립트로 괘닝! 다루어 보아용!~~

(항상 그냥 하디 말고, 장단점에 대해서 생각이란 걸 해 보아용~~)

 

아래 sheetjs는 유료 Pro 버젼으로 막강한 기능을 제공해 주지만, 

무료 커뮤니티 에디션으로 기본적으로 필요한 기능을 충분히 커버하고도 남는당.

괘니 한번 똑똑 방문해서 대략 눈으로 흘겨보장~~

https://docs.sheetjs.com/

 

SheetJS Community Edition | SheetJS Community Edition

SheetJS Community Edition Documentation

docs.sheetjs.com

 

맘 급한 사람들을 위한 실행 과 결과를 바로 확인 해 볼 수 있는 전체 소스

sheet2.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>E7E 엑셀</title>
    <script src="https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script>
    <style>
      h1 {
        color: yellow;
        background-color: black;
        text-align: center;
      }
      #wrapper {
        width: 60%;
        margin: 10px auto;
      }
    </style>
  </head>
  <body>
    <div id="wrapper">
      <h1>E7E와 자바스크립트로 엑셀 다루깅</h1>
      <table id="tblEx" border="1" width="400">
        <thead>
          <tr>
            <th>이름</th>
            <th>나이</th>
            <th>생일</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>김다미</td>
            <td>29</td>
            <td>1995-04-09</td>
          </tr>
          <tr>
            <td>문가영</td>
            <td>28</td>
            <td>1996-07-10</td>
          </tr>
          <tr>
            <td>고준희</td>
            <td>38</td>
            <td>1985-08-31</td>
          </tr>
        </tbody>
      </table>
      <br />
      <button id="e7eEx"><b>위 테이블 내용을 엑셀 파일롱</b></button>
      <hr />
      <h1>위에서 만든 엑셀 파일을 선택 하삼</h1>
      <input type="file" id="ejFile" value="" />
      <button id="e7eIm"><b>xlsx 읽어 table맹글깅</b></button><br />
      <div id="e7eOut" style="border: 3px solid pink; width: 400px"></div>
    </div>
    <script>
      // 전역 선언
      const e7eEx = document.querySelector("#e7eEx");
      const e7eIm = document.querySelector("#e7eIm");
      const ejFile = document.querySelector("#ejFile");
      const tblEx = document.querySelector("#tblEx");
      const e7eOut = document.querySelector("#e7eOut");

      // 엑셀파일로 출력
      const fExp = () => {
        //const wb = XLSX.utils.table_to_book(tblEx, { raw: true });

        const wb = XLSX.utils.book_new();
        const ws1 = XLSX.utils.table_to_sheet(tblEx, { raw: true });
        ws1["!cols"] = [{ width: 30 }, { width: 30 }, { width: 30 }];
        XLSX.utils.book_append_sheet(wb, ws1, "첫시트");

        const jsonData = [
          { name: "roze", role: "vocal", age: 27 },
          { name: "jenni", role: "dance", age: 28 },
          { name: "risa", role: "lab", age: 26 },
        ];
        const ws = XLSX.utils.json_to_sheet(jsonData, { raw: true });
        XLSX.utils.book_append_sheet(wb, ws, "추가 시트");

        const ws2 = {
          "!ref": "A1:A5",
          A1: { t: "s", v: "매출" }, // t는 type, v는 value
          A2: { t: "n", v: 2 },
          A3: { t: "n", v: 10 },
          A4: { t: "n", v: 12, f: "A2+A3" },
          A5: { t: "s", v: "2014-08-01" },
        };
        XLSX.utils.book_append_sheet(wb, ws2, "메롱");

        XLSX.writeFile(wb, "e7eMerong.xlsx");
      };

      // 사용자가 선택한 엑셀 파일 읽어서 table로 출력
      const fImp = () => {
        let file = ejFile.files[0];
        console.log("체킁:", file);
        if (!file) {
          alert("파일을 먼저 선택해 주삼");
          ejFile.focus();
          return; // 빠빠잉!
        }

        let fileReader = new FileReader();
        fileReader.readAsArrayBuffer(file);
        fileReader.onload = () => {
          const wb = XLSX.readFile(fileReader.result);
          console.log("체킁:", wb);
          for (let i = 0; i < wb.SheetNames.length; i++) {
            let sheetName = wb.SheetNames[i];
            let rawData = wb.Sheets[sheetName];
            let data = XLSX.utils.sheet_to_json(rawData, { raw: true });
            console.log("최종확인:", data);

            const mDiv = document.createElement("div");
            const mH1 = document.createElement("h1");
            mH1.style.color = "pink";
            mH1.style.backgroundColor = "blue";
            mH1.innerHTML = sheetName;

            const table = XLSX.utils.sheet_to_html(rawData, { raw: true });
            const tblTag = document.createElement("table");
            tblTag.border = 2;
            tblTag.width = 400;
            tblTag.innerHTML = table;

            mDiv.appendChild(mH1);
            mDiv.appendChild(tblTag);

            e7eOut.appendChild(mDiv);

            //e7eOut.innerHTML += table;
          }
          ejFile.value = "";
        };
      };
      // 클릭 이벤트 억지 등록!
      e7eEx.addEventListener("click", fExp);
      e7eIm.addEventListener("click", fImp);
    </script>
  </body>
</html>

 

아래와 같은 결과가 보일 거시다앙!~~ (안 보인다면, 복사/붙여넣기 해랑.. 오타당!)

 

결과를 눈으로 확인했다면  뽀인또만 쓰러지지 않을 정도로 짚고 가장!

 

설치 쉽당.(그냥 아래 cdn 넣으면 된당!)

    <script src="https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js"></script>

 

화면에 있는 table 내용을 엑셀 파일로 맹글기(바로 workbook으롱...)

      <table id="tblEx" border="1" width="400">
        <thead>
          <tr>
            <th>이름</th>
            <th>나이</th>
            <th>생일</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>김다미</td>
            <td>29</td>
            <td>1995-04-09</td>
          </tr>
          <tr>
            <td>문가영</td>
            <td>28</td>
            <td>1996-07-10</td>
          </tr>
          <tr>
            <td>고준희</td>
            <td>38</td>
            <td>1985-08-31</td>
          </tr>
        </tbody>
      </table>
      <script>
      const tblEx = document.querySelector("#tblEx");
      const wb = XLSX.utils.table_to_book(tblEx, { raw: true });
      XLSX.writeFile(wb, "e7eMerong.xlsx");
      </script>

 

workbook생성 후, table을  sheet로 맹글고(sheet이름 줄 수 있음)

sheet를 workbook에 추가하는 방식.... (

      <table id="tblEx" border="1" width="400">
        <thead>
          <tr>
            <th>이름</th>
            <th>나이</th>
            <th>생일</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>김다미</td>
            <td>29</td>
            <td>1995-04-09</td>
          </tr>
          <tr>
            <td>문가영</td>
            <td>28</td>
            <td>1996-07-10</td>
          </tr>
          <tr>
            <td>고준희</td>
            <td>38</td>
            <td>1985-08-31</td>
          </tr>
        </tbody>
      </table>
      <script>
        const wb = XLSX.utils.book_new();
        const ws1 = XLSX.utils.table_to_sheet(tblEx, { raw: true });
        ws1["!cols"] = [{ width: 30 }, { width: 30 }, { width: 30 }];
        XLSX.utils.book_append_sheet(wb, ws1, "첫시트");
        XLSX.writeFile(wb, "e7eMerong.xlsx");
      </script>

 

잠시 시선 주기 (컬럼 넓이 세팅)

        const ws1 = XLSX.utils.table_to_sheet(tblEx, { raw: true });
        ws1["!cols"] = [{ width: 30 }, { width: 30 }, { width: 30 }];

 

JSON 배열 데이터를 엑셀 시트로 맹글어성 workbook에 추가하깅.

       const jsonData = [
          { name: "roze", role: "vocal", age: 27 },
          { name: "jenni", role: "dance", age: 28 },
          { name: "risa", role: "lab", age: 26 },
        ];
        const ws = XLSX.utils.json_to_sheet(jsonData, { raw: true });
        XLSX.utils.book_append_sheet(wb, ws, "추가 시트");

 

JSON 테이터 컬럼 지정, 타입지정, 값지정(계산식까징) 형식으로 시트로 맹글어 추가하깅.

        const ws2 = {
          "!ref": "A1:A5",
          A1: { t: "s", v: "매출" }, // t는 type, v는 value
          A2: { t: "n", v: 2 },
          A3: { t: "n", v: 10 },
          A4: { t: "n", v: 12, f: "A2+A3" },
          A5: { t: "s", v: "2014-08-01" },
        };
        XLSX.utils.book_append_sheet(wb, ws2, "메롱");

 

사용자가 input type=file에서 골라 준 엑셀 파일 읽어서 table로 출력하는 함수(fImp) 맹글깅

 // 사용자가 선택한 엑셀 파일 읽어서 table로 출력
      const fImp = () => {
        let file = ejFile.files[0];
        console.log("체킁:", file);
        if (!file) {
          alert("파일을 먼저 선택해 주삼");
          ejFile.focus();
          return; // 빠빠잉!
        }

        let fileReader = new FileReader();
        fileReader.readAsArrayBuffer(file);
        fileReader.onload = () => {
          const wb = XLSX.readFile(fileReader.result);
          console.log("체킁:", wb);
          for (let i = 0; i < wb.SheetNames.length; i++) {
            let sheetName = wb.SheetNames[i];
            let rawData = wb.Sheets[sheetName];
            let data = XLSX.utils.sheet_to_json(rawData, { raw: true });
            console.log("최종확인:", data);

            const mDiv = document.createElement("div");
            const mH1 = document.createElement("h1");
            mH1.style.color = "pink";
            mH1.style.backgroundColor = "blue";
            mH1.innerHTML = sheetName;

            const table = XLSX.utils.sheet_to_html(rawData, { raw: true });
            const tblTag = document.createElement("table");
            tblTag.border = 2;
            tblTag.width = 400;
            tblTag.innerHTML = table;

            mDiv.appendChild(mH1);
            mDiv.appendChild(tblTag);

            e7eOut.appendChild(mDiv);

            //e7eOut.innerHTML += table;
          }
          ejFile.value = "";
        };
      };

 

조급함에만 지지 않고, 차분히 누네 히믈 주어,  뽀인또 라인을 찾는 다면,

생각보다 어렵진 않을 거시당.

누니 좋은 사람은 알아 차렸을 거시당.  XLSX.utils로 시작하는 것이 

핵심 역할을 한다는 것을 .... 천재!~~

바로 그 유틸함수들이 아래 링크에 잘 정리되어 설명되어 있당.

필요한 것이 있는지 한번 여유롭게 방문해 보고, 대략 어떤 것들이 지원되는지 확인해 두장!

 

https://docs.sheetjs.com/docs/api/utilities/

 

Utility Functions | SheetJS Community Edition

The utility functions in this section fall into two categories:

docs.sheetjs.com


 

추하고 못되고 못된  진실 일 수록 

화려하고 때깔 좋은 거짓의 옷을 입고

주변을 어슬렁 거린다.

 

참되고 맑고 맑은 진실은

직설적이고 가볍고 투명하당.

 

거짓의 옷에 익숙해진 왜곡된 눈을 가진

그들에겐 진실이 거짓이당.

 

진실을 직접 마주할 용기가 없어

진실을 확인한 적이 없어서당.

 

거짓의 옷을  매일 갈아입는

못생긴 진실에 일침을 가하고

스스로를 파워 업 하자

진실은 스스로 그 의도를 전할 거시당.

용기 내어 진실의 손을 잡아보장.

 

 

https://www.youtube.com/watch?v=aiHSVQy9xN8

관련글 더보기