부트캠프/Front

[JavaScript, HTML, CSS] Spread Sheet 앱 만들기

혀니hyun 2025. 3. 18. 20:07

결과물

GitHub

※ 관련 강의를 참고하여 진행함

 

기능

  • Export Spreadsheet 버튼 클릭 시 엑셀 파일 다운로드
  • 셀 클릭 시 셀 위치(행, 열 값) 표현
  • 셀 클릭 시 행, 열 헤더 강조
  • 셀 내 텍스트 입력 및 저장

작업 순서

  1. spread sheet 및 cell data 만들기
    : Cell 클래스의 인스턴스 객체 생성
    : spreadsheetRow(배열)에 인스턴스 push
    : spreadsheet(배열)에 spreadsheetRow push
  2. cell 요소 만들기
  3. 만든 cell 요소를 html 코드에 넣어 화면에 spread sheet 표현하기 (DOM 조작)
  4. spread sheet의 row 행 구분하기
    : row 별 div 만들고 해당하는 cell append
  5. 헤더 만들기 & disabled
  6. 헤더 행, 열에 인덱스 넣기
  7. 헤더 스타일링
  8. 셀 클릭 이벤트 - 해당 셀 위치 반환
  9. 셀 클릭 이벤트 - 해당 헤더 강조, 이전에 강조된 부분 지우기
  10. 셀 입력(change) 이벤트 - 입력 값을 셀 객체 속성값으로 저장하기
  11. Export 버튼 클릭 이벤트 - 엑셀 파일로 만들기 위한 형태(String)로 변환하고, 엑셀 파일 다운로드하기

 

 


시행착오들 

1. 셀 객체의 column 속성 값이 '9'로만 출력되는 문제 

객체 인스턴스 변수 선언하는 위치를 바꾸니 해결되었다. 🔽

좌 = 수정 전(비정상) / 우 = 수정 후(정상)

전 = column for문 이전(39행) / 후 = column for문 내부(41행)

수정하고 보니 당연한 것이었다. 열을 이동할 때마다 newCell을 만들어줘야 하니까. 

 


2. 스프레드시트 크기가 너무 커 화면에 다 안 들어오고 스크롤 생기는 문제

정확히는 row행 <div>의 사이즈가 container를 넘어서 튀어나왔다.

display: flex; flex-shrink: 1; widht: 100%; 다 해도 안되다가,

cell(=input tag)에 display: block; widht: 100%; 을 넣었더니 해결이 됐다.

display:block은 줄바꿈 여부 설정에만 사용하는 줄 알았는데 새로운 정보를 배웠다.

 

해결에 도움이 된 글 : https://helia-17.tistory.com/15

 


레슨런

  • JS FE 작업 방식을 익혔다.
    만들려는 요소의 데이터를 먼저 만들기(배열, 객체 등) => 요소 만들고 html에 추가 => 이벤트 정의
  • 이벤트를 적용하는 패턴(?)을 익혔다.
    예를 들면, 특정 이벤트 발생 => 해당 요소의 classList에 키워드 추가 => css에서 해당 class 스타일링
  • 잘 몰랐던 문법
    • 입력 이벤트: onchange
    • filter() 메서드: 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환 (= 필터링)
    • map() 메서드: 배열 내 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환
    • join() 메서드: 배열의 모든 요소를 쉼표나 지정된 구분 문자열로 구분하여 연결한 새 문자열을 만들어 반환

  • 엑셀 파일 Export하기
const exportBtn = document.querySelector('#export-btn');
exportBtn.onclick = function(e) {
    // 엑셀 파일로 만들기 위한 형태(String)으로 변환하기
    let csv = '';
    for (let i=0 ; i<spreadsheet.length ; i++){
        if(i==0) continue; //1행 헤더 부분 제외하기 위함
        csv += spreadsheet[i]
                    .filter(item => !item.isHeader)
                    .map(item => item.data)
                    .join(",") + "\r\n";
    }
    
    // 엑셀 파일 다운로드하기
    const csvObj = new Blob([csv]);
    const csvUrl = URL.createObjectURL(csvObj);
    const a = document.createElement("a");
    a.href = csvUrl;
    a.download = "Spreadsheet File Name.csv"
    a.click();
}

 

회고

  • 객체, 배열, 이벤트, 반복문 다양하게 응용할 수 있었다. 문법이 계속 헷갈렸는데 조금 익숙해질 수 있었던 것 같다.
  • 강의에서 단계별 작업 내용만 보고 혼자 먼저 코딩을 했다. 혼자 계속 수정, 수정, 수정...하면서 문법과 개념을 조금이나마 더 잘 이해하게 되었고, 내가 뭘 알고 뭘 모르는지 알게 됐다. 대신 오래 걸리긴 참 오래 걸렸다.