Developer's Development
[HTML] Sheet.js & xspreadsheet.js 엑셀 미리보기 본문
파일 미리보기 및 다운로드 포스팅에서 이어지는 이야기
2023.12.29 - [개발/JAVA] - [JAVA] 파일 미리보기 및 다운로드
Case)
서버에 업로드된 파일 경로와 원래 파일명(확장자 포함)을 전달받아 복호화(내용 복호화/원래 파일명, 원래 확장자로 변경)해서 미리보기 및 다운로드
이번 포스팅은 엑셀 파일의 미리보기만을 목적으로 하기에, 암/복호화 및 다른 확장자의 복호화 및 미리보기에 관련한 내용은 생략
Reference
https://lts0606.tistory.com/m/228
https://github.com/SheetJS/sheetjs
https://developer-talk.tistory.com/842
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를 사용해야 한다.
- SheetJS Demo URL : https://docs.sheetjs.com/docs/demos/grid/xs
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편으로 올릴 예정!
'개발 > HTML' 카테고리의 다른 글
[HTML] Luckysheet.js 엑셀 미리보기 (1) | 2024.04.15 |
---|---|
[HTML] docx-preview.js 워드 미리보기 (0) | 2024.03.13 |
[HTML] selectbox control (jQuery) (3) | 2023.11.22 |
[HTML] checkbox control (jQuery/search area) (0) | 2023.05.02 |
[HTML] button onclick event가 먹지 않을 때 (0) | 2023.02.13 |