JavaScript로 Excel 파일 읽기

서버측의 기술없이 클라이언트 기술만으로 로컬에 저장된 엑셀 파일을 다룰 수 있는 라이브러리인 sheetjs에 대한 다양한 기능 중 엑셀 파일을 읽는 기능에 대한 JavaScript 코드를 정리해 봅니다.

이 라이브러리를 별도로 다운로드 받지 않고도 CDN을 통해 이용할 수 있습니다. 아래는 제가 이용한 CDN 접근입니다.


읽고자 하는 엑셀 파일은 다음과 같습니다.

위의 엑셀 파일을 선택하고, 선택된 엑셀 파일을 JSON 형식으로 변환해 콘솔에 출력하는 DOM 요소는 다음과 같습니다.


위의 input DOM 요소를 통해 파일을 선택할 때 발생하는 이벤트 코드는 다음과 같습니다.

function readExcel() {
    let input = event.target;
    let reader = new FileReader();

    reader.onload = function () {
        let data = reader.result;
        let workBook = XLSX.read(data, { type: 'binary' });

        workBook.SheetNames.forEach(function (sheetName) {
            console.log('SheetName: ' + sheetName);

            let rows = XLSX.utils.sheet_to_json(workBook.Sheets[sheetName]);
            console.log(JSON.stringify(rows));
        })
    };

    reader.readAsBinaryString(input.files[0]);
}

실행하고, 엑셀 파일을 선택해 보면 다음과 같은 내용이 콘솔에 표시되는 것을 확인할 수 있습니다.

SheetName: #인구수
[
   {
      "지역명":"무안군 무안읍",
      "남자":8599,
      "여자":7900,
      "가구수":6968,
      "노인수":732,
      "아저씨":1359,
      "어린이":4627
   },
   {
      "지역명":"무안군 일로읍",
      "남자":3659,
      "여자":3243,
      "가구수":3526,
      "노인수":8711,
      "아저씨":8758,
      "어린이":4099
   },

   ....

   {
      "지역명":"무안군 운남면",
      "남자":7357,
      "여자":7667,
      "가구수":3624,
      "노인수":8110,
      "아저씨":8042,
      "어린이":9618
   }
]

sheetjs 라이브러리는 엑셀을 읽는 기능 뿐만 아니라 생성도 가능하며 정교한 처리가 가능합니다.

NexGen, 공간 데이터의 분포경향 분석을 위한 밀도맵 기능

공간 분석 중, 밀도맵은 위치 데이터가 공간 상에 분포하는 경향을 매우 효과적으로 시각화할 수 있는 의사결정 지원 도구입니다. 위치 데이터의 공간 상의 위치 분포 뿐만 아니라 각 위치 데이터가 갖는 가중치값을 밀도 분석에 반영할 수 있어 위치 데이터와 통계 데이터를 조합할 수 있습니다.

밀도맵 기능의 소개를 위해 서울시의 인구 통계 데이터를 담고 있는 SHP 파일을 NexGen에 바로 불러와 밀도맵을 작성했습니다. 아래의 표는 사용한 인구 SHP 파일의 속성값에 대한 구조입니다. 통계청의 집계구 데이터를 받아 SHP 파일로 가공하였습니다.

이 데이터는 아래의 URL을 통해 다운로드 받으실 수 있습니다. 통계청에서 다운로드 받은 폴리곤 타입의 SHP 파일인 집계구 데이터와 TXT 파일인 2017년도 인구 데이터를 이용해 포인트 타입의 단일 SHP 파일로 직접 가공한 것입니다. 좌표계는 EPSG:5181입니다.



아래의 시연 동영상은 위의 인구 데이터를 활용한 NexGen의 밀도맵 기능에 대한 소개입니다.

웹 기반의 GIS 솔루션인 NexGen의 밀도맵 기능은 히트맵(HeatMap) 방식이 아닌 정규분포 방식의 알고리즘을 활용하여 고품질의 밀도맵을 작성할 수 있습니다.

대한민국 EPSG 코드

EPSG 코드는 전세계 좌표계 정의에 대한 고유한 명칭입니다. EPSG 코드에 대한 상세 정의는 prj4와 wkt라는 문자열로 되어 있으며, proj4와 EPSG의 wkt는 좌표계의 다양한 제원값을 정해진 문자열로 구성되어 있습니다. EPSG.io 라는 사이트를 통해 각 EPSG 코드에 대한 proj4와 wkt 문자열을 파악할 수 있으며, 이에 대한 글은 아래의 글을 참고하시기 바랍니다.

EPSG.io를 통한 proj4 문자열 얻기

아울러 아래는 대한민국에서 자주 사용하는 EPSG 코드에 대한 proj4 문자열을 정리한 것입니다. 향후에도 지속적으로 내용을 추가/보완하도록 할 것입니다.

EPSG:4166, ESPG:4326

+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs 

WGS84 타원체의 경위도 좌표계입니다. 흔히 GPS 등의 기본 좌표계입니다.

EPSG:2097

+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs +towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43

Bessel 1841 타원체의 한국 중부원점 TM 직각 좌표계입니다.

EPSG:5174

+proj=tmerc +lat_0=38 +lon_0=127.0028902777778 +k=1 +x_0=200000 +y_0=500000 +ellps=bessel +units=m +no_defs +towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43

일본의 기준점으로 끌어다 사용했다는 (개인적으로 사실이라고 해도 믿고 싶지 않지만?) 좌표계로, 일본에 지진이 발생하여 해당 기준점이 틀어진 만큼 보정된 좌표계입니다. 타원체는 Bessel 1841이며 TM 직각좌표계입니다. 폐기해야할 좌표계입니다. 개인적으로는 Bessel 타원체를 사용하는 모든 좌표계는 폐기하고 범세계적으로 GRS80 타원체로 통일해 사용해야 한다고 생각합니다.

ESPG:5178

+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=bessel +units=m +no_defs +towgs84=-115.80,474.99,674.11,1.16,-2.31,-1.63,6.43

Bessel 1841 타원체의 UTM-K 직각 좌표계입니다.

EPSG:5179 – 네이버 지도에서 사용함

+proj=tmerc +lat_0=38 +lon_0=127.5 +k=0.9996 +x_0=1000000 +y_0=2000000 +ellps=GRS80 +units=m +no_defs

GRS80 타원체의 UTM-K 직각 좌표계입니다. 네이버(v3)와 도로명주소 DB에서 사용하는 좌표계입니다.

ESPG:5181 – 카카오맵에서 사용함

+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=500000 +ellps=GRS80 +units=m +no_defs

GRS80 타원체의 한국 중부원점이며 Y 축으로 500000미터만큼 이동시킨 좌표계입니다. 카카오 맵에서 사용하는 좌표계입니다.

EPSG:5186

+proj=tmerc +lat_0=38 +lon_0=127 +k=1 +x_0=200000 +y_0=600000 +ellps=GRS80 +units=m +no_defs

GRS80 타원체의 한국 중부원점이며 Y 축으로 600000미터만큼 이동시킨 좌표계입니다. 국가에서 제공하는 DXF나 NGI 형식의 공간데이터가 이 좌표계를 이용합니다. 중부원점이외에도 서부, 동부, 동해원점이 있으며 각각 EPSG:5185, EPSG:5187, EPSG:5188입니다.

EPSG:3857, EPSG:900913, EPSG:102113 – 네이버(v5), 구글맵, VWorld지도에서 사용함

+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs

구글맵, VWorld 지도에서 사용하는 좌표계입니다. TM 방식의 좌표계가 아니므로 거리 측정에 사용할 수 없는 좌표계입니다.

아울러 아래의 글은 자바스크립트 기반의 좌표계 라이브러리에 대한 설명입니다.

Proj4js

끝으로 앞서 언급한 몇가지 EPSG 코드에 대한 .prj 파일을 공유합니다.


Javascript 기반의 압축 라이브러리, jszip

웹에서는 로컬에 저장된 여러 개의 파일을 사용하기 위해서는 사용자가 해당 파일들을 모두 마우스를 통한 직접적인 선택 행위가 적용되어야 보안상에 문제가 발생하지 않습니다. 이에 대한 대안은 여러개의 파일을 하나의 파일로 묶아 압축하고 압축된 파일 하나에만 이러한 사용자의 선택 행위가 적용되도록 하는 것입니다. 물론 네트워크를 통한 파일의 접근에는 이러한 문제가 발생하지 않습니다.

여튼, 여러 개의 파일이 하나로 묶인, 하나의 압축 파일로써 zip을 처리할 수 있는 자바스크립트 기반의 라이브러리가 몇가지 되는데.. 그중 제가 사용한 라이브러리를 소개합니다. 바로 jszip인데요. 아래의 해맑고 환하게 웃는 인상좋은 개발자의 github에 방문해 다운로드 받을 수 있습니다.

jszip 라이브러리 이외에도 이를 좀더 쉽게 사용하기 위해서 jszip-utils 라이브러리도 함께 받았는데, 위의 그림에서 이 2개의 라이브러리에 대한 다운로드는 파랑색 외곽선 박스로 언급해 두었습니다.

사용코드는 아래와 같습니다. 만약 자바스크립트의 promise라는 개념을 이해하고 있다면 매우 심플하고 직관적이라는 것을 알 수 있습니다. IO 처리이므로 당연이 비동기방식으로 처리됩니다. 과거 버전에서는 동기 방식도 지원했던거 같은데, 제거된 것 같습니다.





위의 코드에서는 압축 파일 안에 저장된 하나 하나의 파일에 순차적으로 접근해서 압축을 풀고, 풀어진 데이터를 ArrayBuffer 타입으로 전달받도록 21번 째 코드가 file.async(“arraybuffer”)라고 지정되어 있으나, arraybuffer 대신 string, blob로도 지정하여 각각 텍스트, BLOB 타입으로도 전달받을 수 있습니다.

현대의 웹은 무한한 접근성이라는 장점은 있으나 여전이 데스크탑 환경에 비해 처리 속도가 느리지만, 이런 문제점 조차도 웹어셈블리 등의 다양한 기술을 통해 극복해 나가고 있습니다. 향후 몇년안에 모든 프로그램은 서비스화될 것이라고 생각되고, 프로그램의 서비스화에는 JavaScript라는 핵심적인 언어가 중추적인 역할을 할 것입니다.

NexGen, 웹 GIS에서 로컬 데이터 파일 활용

웹기반의 GIS 시스템은 지도탐색, 주소검색, 길찾기 등과 같은 매우 편리한 기능을 제공하며 인터넷이 되는 환경이라면 쉽게 접근하여 사용할 수 있습니다. 그러나 보다 높은 수준의 GIS 기능을 원하는 전문 사용자나 특화된 업무를 GIS에 접목하고자 하는 사용자에게는 많이 부족합니다.

이러한 사용자들이 느끼는 웹 GIS 기능의 결핍은 웹 GIS 보다는 여전이 QGIS나 ArcGIS 등과 같은 Application 형태의 GIS 프로그램들을 선택하게 합니다. 하지만 웹 GIS는 Desktop GIS가 갖지 못하는 장점을 제공합니다. 설치 없이 URL을 통해 바로 접속해 사용할 수 있다는 편의성, 기본적으로 제공되는 완벽하고 아름다운 배경맵, 완벽한 주소검색과 길찾기 등의 기능은 사용자가 별도의 설정 없이 바로 사용할 수 있습니다.

반면 웹 GIS의 단점은 서버 측에서 제공하지 않은 데이터의 사용에 큰 제약이 존재합니다. 예를 들어서, 사용자가 자신만의 노하우가 반영된 의미있고 유용한 결과를 공간 데이터 파일로 제작했다면, 이 공간 데이터 파일을 웹 GIS의 배경지도에 중첩해 보고, 다양한 편의 기능에 적용하여 활용하고 싶은 경우가 있습니다. 이런 요구사항은 웹 GIS의 기능성에 비례하여 커집니다.

만약 사용자가 QGIS, ArcGIS 또는 공간 분석 툴을 이용해 생성한 공간 데이터 파일을 웹 GIS에서 완벽하게 활용할 수 있다면 앞서 언급한 사용자의 요구사항은 상당 부분 충족될 것입니다. 바로 웹 GIS 기반 시스템인 NexGen은 사용자가 자신의 로컬 PC에 저장된 공간 데이터 파일을 바로 활용할 수 있습니다.

아래는 사용자가 보유한 SHP 파일들을 NexGen의 배경지도 위에 중첩하고 그리기 심벌과 라벨 들을 설정하는 예를 시연하고 있습니다.

위의 예는 단순히 SHP 파일을 통한 지도 구성 정도의 데모이지만, SHP 파일을 활용할 수 있음으로 해서 SHP 파일이 제공하는 공간 데이터를 웹 GIS에서 제공하는 다른 기능과 융합하여 다양하게 활용될 수 있습니다.

덧붙여 아래의 글은 외부 파일로 CSV를 통한 통계지도를 저작하는 NexGen의 기능 소개입니다.

넥스젠(NexGen)의 통계지도 기능