Developer's Development

[HTML] Sheet.js & xspreadsheet.js 엑셀 미리보기 본문

개발/HTML

[HTML] Sheet.js & xspreadsheet.js 엑셀 미리보기

mylee99 2024. 2. 5. 20:41

파일 미리보기 및 다운로드 포스팅에서 이어지는 이야기

2023.12.29 - [개발/JAVA] - [JAVA] 파일 미리보기 및 다운로드

 

[JAVA] 파일 미리보기 및 다운로드

javax.crypto 파일 암/복호화 포스팅에서 이어지는 이야기 2023.11.15 - [개발/JAVA] - [JAVA] javax.crypto 파일 암/복호화 [JAVA] javax.crypto 파일 암/복호화 Case) 파일 업로드 시, 암호화(내용 암호화/파일명 난수

developer-mylee.tistory.com

 

Case)
서버에 업로드된 파일 경로와 원래 파일명(확장자 포함)을 전달받아 복호화(내용 복호화/원래 파일명, 원래 확장자로 변경)해서 미리보기 및 다운로드
이번 포스팅은 엑셀 파일의 미리보기만을 목적으로 하기에, 암/복호화 및 다른 확장자의 복호화 및 미리보기에 관련한 내용은 생략

 

Reference

https://lts0606.tistory.com/m/228

 

Javascript를 활용하여 엑셀파일을 웹에서 테이블로(Javascript read excel file, sheetjs, javascript parsing excel)

엑셀파일의 내용을 읽어와서 표를 구현해야되는 경우가 종종 있다. 예전에는 이러한 요구사항을 해결하려면, 서버에서 엑셀파일을 읽어서 json 형식으로 리턴하고..리턴된 형식의 데이터를 가져

lts0606.tistory.com

https://github.com/SheetJS/sheetjs

 

GitHub - SheetJS/sheetjs: 📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/sheetjs

📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/sheetjs - GitHub - SheetJS/sheetjs: 📗 SheetJS Spreadsheet Data Toolkit -- New home https://git.sheetjs.com/SheetJS/she...

github.com

https://developer-talk.tistory.com/842

 

[JavaScript]XMLHttpRequest 사용 방법

XMLHttpRequest란? JavaScript에서 XMLHttpRequest 객체를 사용하여 서버에 동기 또는 비동기식 요청을 보낼 수 있으며, 요청에 대한 응답 정보를 웹 페이지에 로드할 수 있습니다. 따라서, 웹 페이지를 다시

developer-talk.tistory.com

 

1. 엑셀 파일을 불러와서 HTML로 시트 전체를 보여주는 방식까지 완료한 코드
HTML
<div id="grid"></div>
<td>
    <th:block th:if="${row.fileExt eq 'pdf'} or ${row.fileExt eq 'jpg'} or ${row.fileExt eq 'png'} or ${row.fileExt eq 'xlsx'}">
        <button th:if="${row.fileExt eq 'pdf'} or ${row.fileExt eq 'jpg'} or ${row.fileExt eq 'png'}" th:onclick="goDownload([[${row.filePath}]], [[${row.orgFileNm}]], 'Y', 'N')" type="button">미리보기</button>
        <button th:unless="${row.fileExt eq 'pdf'} or ${row.fileExt eq 'jpg'} or ${row.fileExt eq 'png'}" th:onclick="goDownload([[${row.filePath}]], [[${row.orgFileNm}]], 'N', 'Y')" type="button">미리보기</button>
    </th:block>
    <th:block th:unless="${row.fileExt eq 'pdf'} or ${row.fileExt eq 'jpg'} or ${row.fileExt eq 'png'} or ${row.fileExt eq 'xlsx'}">
        <button class="fileDisabled" type="button" disabled>미리보기</button>
    </th:block>
</td>

<form id="fileDecryptForm">
	<input type="hidden" name="encryptedFilePath"/>
	<input type="hidden" name="decryptedFile"/>
	<input type="hidden" name="previewYn"/>
</form>
jQuery
//파일 복호화
goDownload = function ( filePath, orgFileNm, previewYn, excelYn ) {
    if (excelYn == "Y") {
        const request = new XMLHttpRequest();
        request.open('POST', '/fileDownload', true);
        request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        request.send("encryptedFilePath="+filePath+"&decryptedFile="+orgFileNm+"&previewYn="+previewYn+"&excelYn="+excelYn);
        request.responseType = 'blob';
        request.onload = function () {
            if(request.status === 200) {
                const blob = new Blob([request.response], {type: 'application/xlsx'});
                if(blob.size > 0) {
                    gridExcelToWeb(blob, $("#grid"));
                } else {
                    alert("처리중 오류가 발생하였습니다.");
                }
            }
        };
    } else {
        $fileDecryptForm.find("[name=encryptedFilePath]").val(filePath);
        $fileDecryptForm.find("[name=decryptedFile]").val(orgFileNm);
        $fileDecryptForm.find("[name=previewYn]").val(previewYn);
        $fileDecryptForm.attr({"action":"/fileDownload","target":"_blank","method":"post"}).submit();
    }
}

//엑셀
gridExcelToWeb = function (file, target) {
    const reader = new FileReader();
    reader.onload = function (evt) {
        if (evt.target.readyState == FileReader.DONE) {
            let data = evt.target.result;
            data = new Uint8Array(data);
            
            //받아온 데이터를 이용하여 워크북 생성
            const workbook = XLSX.read(data, {type: 'array'});

            workbook.SheetNames.forEach(function (sheetName) {
                const toHtml = XLSX.utils.sheet_to_html(workbook.Sheets[sheetName], {header: ''});
                target.append(toHtml);
            });
        }
    };
    reader.readAsArrayBuffer(file);
}

 

 

Sheet.js(xlsx.full.min.js)는 엑셀의 파일을 읽어 내용을 뿌리는 것까지만 가능하고,

실제 엑셀 같은 UI로 웹에서 스프레드시트를 만들기 위해선 xspreadsheet.js 및 css를 사용해야 한다.

 

x-spreadsheet | SheetJS Community Edition

With a familiar UI, x-spreadsheet is an excellent choice for a modern editor.

docs.sheetjs.com

 

 

 

2. 엑셀 파일을 불러와서 xspreadsheet.js를 사용해 엑셀 UI에 내용을 뿌리는 방식까지 완료한 코드
jQuery

"gridExcelToWeb" 함수는 FileReader를 사용하여 엑셀 파일을 읽고, 해당 파일의 데이터를 XLSX 라이브러리를 통해 읽어옴. 여기에 "x-spreadsheet"를 사용하여 엑셀 미리보기를 구현하는 코드를 추가할 수 있음.

//gridExcelToWeb 호출 부분 변경
gridExcelToWeb(blob, orgFileNm);

//엑셀 파일 처리
gridExcelToWeb = function (file, orgFileNm) {
    const reader = new FileReader();
    reader.onload = function (evt) {
        if (evt.target.readyState == FileReader.DONE) {
            let data = evt.target.result;
            data = new Uint8Array(data);
            const workbook = XLSX.read(data, {type: 'array'});

            //시트를 나타낼 영역 생성
            var newWindow = window.open('', '_blank');
            $(window).on("beforeunload", function () {
                newWindow = null;
            });
            newWindow.document.write("<html><head><link rel='stylesheet' href='/css/xspreadsheet.css'>" +
                    "<script src='/js/xlsx.full.min.js'><\/script>" +
                    "<script src='/js/xspreadsheet.js'><\/script>" +
                    "<title>"+orgFileNm+"</title>" +
                    "</head><body></body></html>");
            const XPORT = document.createElement('div');
            var xspr = new x_spreadsheet(XPORT);

            //시트 컨테이너를 대상 엘리먼트에 추가
            newWindow.document.body.appendChild(XPORT);

            var out = [];
            //각 시트마다 작업 수행
            workbook.SheetNames.forEach( function (name) {
                var o = { name: name, rows: {} };
                var ws = workbook.Sheets[name];

                //시트 데이터 배열로 변환(aoa 변수에 저장)
                var aoa = XLSX.utils.sheet_to_json(ws, { raw: false, header:1 });

                //셀 데이터 및 스타일 가져오기
                aoa.forEach( function(r, i) {
                    var cells = {};
                    r.forEach( function(c, j) {
                        cells[j] = ({ text: c });

                        //셀 스타일 가져와서 적용
                        var cellAddr = XLSX.utils.encode_cell({r: i, c: j});
                        var cellStyle = ws[cellAddr] ? ws[cellAddr].s : null;
                        if(cellStyle) {
                            applyCellStyle(cells[j], cellStyle);
                        }
                    });
                    o.rows[i] = { cells: cells };
                });
                out.push(o);
            });

            //xspreadsheet에 데이터 로드
            xspr.loadData(out);
        }
    };
    //파일을 ArrayBuffer로 읽어오기
    reader.readAsArrayBuffer(file);
}

 

이렇게 하면 엑셀 파일의 셀 스타일을 제외한, 글자 내용을 불러오는 것까진 정상적으로 작동한다.

xspreadsheet의 .s function을 사용해 셀 스타일을 정상적으로 읽어와야 하는데 자꾸 안 돼서 찾아보니,

셀 스타일의 활용을 위해선 Pro 버전 구매를 해야 하는 것 같기도 하다.

결론은 새롭게 luckysheet.js로 처음부터 다시 코딩하는 중. 완료하면 2편으로 올릴 예정!

Comments