이번 포스팅은 exceljs 라이브러리를 사용하여 엑셀 다운로드(내보내기)하는 방법을 소개합니다.
exceljs를 사용하는 이유
JavaScript에서 엑셀 다운로드를 지원하는 다양한 라이브러리가 존재하지만, exceljs 라이브러리는 엑셀의 모든 셀을 접근하여 커스텀할 수 있다는 장점이 있습니다. font, border, fill 등... 특정 행의 셀마다 스타일을 설정할 수 있으며 이미지도 엑셀로 내보낼 수 있습니다.
자세한 사용 방법은 exceljs 공식 문서에서 확인할 수 있습니다.
엑셀 다운로드 구현 방법
예제는 react에서 구현하였지만, JavaScript를 사용하는 다른 웹 프레임워크에서도 사용할 수 있습니다.
※ 주의사항
exceljs의 주의사항으로 행과 셀은 0이 아닌 1부터 시작합니다.
exceljs는 외부 라이브러리이므로 npm을 통해 다운로드합니다.
npm install express exceljs
라이브러리를 다운로드하였다면, require() 함수를 사용하여 excel.js 종속성을 추가합니다.
const Excel = require('exceljs');
엑셀 객체(workbook)를 생성합니다.
const workbook = new Excel.Workbook();
workbook이라는 엑셀 객체를 생성 후 생성자, 수정자, 생성일, 수정자 속성에 값을 설정합니다.
- creator: 생성자
- lastModifiedBy: 최종 수정자
- created: 생성일
- modified: 수정일
// 생성자
workbook.creator = '작성자';
// 최종 수정자
workbook.lastModifiedBy = '최종 수정자';
// 생성일(현재 일자로 처리)
workbook.created = new Date();
// 수정일(현재 일자로 처리)
workbook.modified = new Date();
addWorksheet()
함수를 사용하여 엑셀 시트를 추가합니다.
workbook.addWorksheet('Sheet One');
workbook.addWorksheet('Sheet Two');
workbook.addWorksheet('Sheet Three');
엑셀 시트를 접근하기 위해서는 getWorksheet()
함수를 사용하거나 배열 타입인 worksheets
속성으로 접근합니다.
// 1. getWorksheet() 함수에서 시트 명칭 전달
const sheetOne = workbook.getWorksheet('Sheet One');
// 2. getWorksheet() 함수에서 시트 인덱스 전달
const sheetTwo = workbook.getWorksheet(1);
// 3. 대괄호 표기법
const sheetThree = workbook.worksheets[2];
엑셀 시트 생성과 동시에 시트를 접근하고 싶은 경우 addWorksheet()
함수의 리턴 값을 받는 객체를 설정합니다.
const sheetOne = workbook.addWorksheet('Sheet One');
const sheetTwo = workbook.addWorksheet('Sheet Two');
const sheetThree = workbook.addWorksheet('Sheet Three');
엑셀 시트를 삭제하는 경우 removeWorksheet()
함수에 엑셀 시트 객체의 id를 전달합니다.
// 세 번째 엑셀 시트를 제거
workbook.removeWorksheet(sheetThree.id);
다음은 엑셀 시트의 셀(첫 번째 행)을 설정합니다. 가장 기본적인 속성은 header와 key 속성이며 2가지 속성 이외에도 여러 가지 속성이 존재합니다.
- header: 엑셀(첫 번째 행)에 표기되는 이름
- key: 셀에 접근하기 위한 고유한 값
// 엑셀 시트 접근(어떤 워크시트에서 작업할 건지...)
const sheetOne = workbook.getWorksheet('Sheet One');
// 컬럼 설정
// header: 엑셀에 표기되는 이름
// key: 컬럼을 접근하기 위한 key
// hidden: 숨김 여부
// width: 컬럼 넓이
// style: 셀 스타일 설정
sheetOne.columns = [
{header: '이름', key: 'name', width: 40},
{header: '성별', key: 'gender', hidden:false, width: 30},
{header: '부서코드', key: 'deptCode', width: 60},
{header: '부서명', key: 'deptName', width: 100,
// 스타일 설정
style: {
// Font 설정
font: {name: 'Arial Black', size: 20},
// Borders 설정
border: {
top: {style:'thin', color: {argb:'FF00FF00'}},
left: {style:'thin', color: {argb:'FF00FF00'}},
bottom: {style:'thin', color: {argb:'FF00FF00'}},
right: {style:'thin', color: {argb:'FF00FF00'}},
},
// Fills 설정
fill: {
type: 'pattern'
fgColor: {argb: 'FFFFFF00'},
bgColor: {argb: 'FF0000FF'}
}
}
}
]
셀에 접근해야 하는 경우 getColumn()
함수에 셀의 고유한 값인 key 또는 셀 순서를 전달합니다. getColumn()
함수의 리턴 값을 이용하여 셀의 속성을 변경할 수 있습니다.
// 컬럼 접근 방법
// 1. getColumn() 함수에 key를 전달
const colName = worksheet.getColumn('name');
// 2. getColumn() 함수에 컬럼 순서를 전달(1부터 시작함)
const colGender = worksheet.getColumn(2);
// 컬럼 접근 후 속성 변경
colGender.width = 40;
colGender.hidden = true;
엑셀에 행을 추가하는 경우 addRow()
함수를 사용합니다. 다음은 샘플 데이터를 순회하여 item을 추가하고 추가된 행의 셀 속성을 변경합니다.
// 객체의 key와 컬럼 헤더의 key와 매핑되는 데이터만 엑셀에 출력된다.
// 컬럼 헤더의 key는 name, gender, deptCode, deptName 총 4개가 존재하며, code와 entryDate는 컬럼 헤더에 없으므로 엑셀에 출력되지 않는다.
const sampleData = [
{ name: '홍길동', code: 'A100', gender: 'F', entryDate: '20200101', deptCode: 'A1000', deptName: '금융팀' },
{ name: '마이콜', code: 'A200', gender: 'F', entryDate: '20200201', deptCode: 'A2000', deptName: '자산팀' },
{ name: '둘리', code: '9999991234567', gender: 'M', entryDate: '20200301', deptCode: 'A1000', deptName: '금융팀' },
{ name: '또치', code: '9999992234567', gender: 'M', entryDate: '20200401', deptCode: 'A2000', deptName: '자산팀' }
];
const borderStyle = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
// 샘플 데이터 순회
sampleData.map((item, index) => {
// 행 추가
sheetOne.addRow(item);
// 추가된 행의 컬럼 설정(헤더와 style이 다를 경우)
// 컬럼 갯수만큼 루프
for(let loop = 1; loop <= 4; loop++) {
// 로우와 행은 0이 아닌 1부터 시작한다.
// 행은 헤더를 제외한 행부터 시작해야하므로 "index + 2"
const col = sheetOne.getRow(index + 2).getCell(loop);
col.border = borderStyle;
}
});
Blob 객체를 사용하여 엑셀을 다운로드합니다.
workbook.xlsx.writeBuffer().then((data) => {
const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
const url = window.URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
// 파일명
anchor.download = `테스트.xlsx`;
anchor.click();
window.URL.revokeObjectURL(url);
})
다음은 예제 코드입니다.
// 버튼 클릭한 경우
handleClick = ({ target, event }) => {
try {
// 엑셀 생성
const workbook = new Excel.Workbook();
// 생성자
workbook.creator = '작성자';
// 최종 수정자
workbook.lastModifiedBy = '최종 수정자';
// 생성일(현재 일자로 처리)
workbook.created = new Date();
// 수정일(현재 일자로 처리)
workbook.modified = new Date();
// addWorksheet() 함수를 사용하여 엑셀 시트를 추가한다.
// 엑셀 시트는 순차적으로 생성된다.
workbook.addWorksheet('Sheet One');
workbook.addWorksheet('Sheet Two');
workbook.addWorksheet('Sheet Three');
// 엑셀 시트를 접근하는 방법은 세 가지 방법이 존재한다.
// 1. getWorksheet() 함수에서 시트 명칭 전달
const sheetOne = workbook.getWorksheet('Sheet One');
// 2. getWorksheet() 함수에서 시트 인덱스 전달
const sheetTwo = workbook.getWorksheet(1);
// 3. 대괄호 표기법
const sheetThree = workbook.worksheets[2];
// removeWorksheet() 함수를 사용하여 엑셀 시트를 제거한다.
workbook.removeWorksheet(sheetThree.id);
// 컬럼 설정
// header: 엑셀에 표기되는 이름
// key: 컬럼을 접근하기 위한 key
// hidden: 숨김 여부
// width: 컬럼 넓이
sheetOne.columns = [
{header: '이름', key: 'name', width: 40},
{header: '성별', key: 'gender', hidden:false, width: 30},
{header: '부서코드', key: 'deptCode', width: 60},
{header: '부서명', key: 'deptName', width: 100,
// 스타일 설정
style: {
// Font 설정
font: {name: 'Arial Black', size: 20},
// Borders 설정
border: {
top: {style:'thin', color: {argb:'FF00FF00'}},
left: {style:'thin', color: {argb:'FF00FF00'}},
bottom: {style:'thin', color: {argb:'FF00FF00'}},
right: {style:'thin', color: {argb:'FF00FF00'}},
},
// Fills 설정
fill: {
type: 'pattern',
fgColor: {argb: 'FFFFFF00'},
bgColor: {argb: 'FF0000FF'}
}
}
}
]
const sampleData = [
{ name: '홍길동', code: 'A100', gender: 'F', entryDate: '20200101', deptCode: 'A1000', deptName: '금융팀' },
{ name: '마이콜', code: 'A200', gender: 'F', entryDate: '20200201', deptCode: 'A2000', deptName: '자산팀' },
{ name: '둘리', code: '9999991234567', gender: 'M', entryDate: '20200301', deptCode: 'A1000', deptName: '금융팀' },
{ name: '또치', code: '9999992234567', gender: 'M', entryDate: '20200401', deptCode: 'A2000', deptName: '자산팀' }
];
const borderStyle = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
sampleData.map((item, index) => {
sheetOne.addRow(item);
// 추가된 행의 컬럼 설정(헤더와 style이 다를 경우)
for(let loop = 1; loop <= 4; loop++) {
const col = sheetOne.getRow(index + 2).getCell(loop);
col.border = borderStyle;
col.font = {name: 'Arial Black', size: 40};
}
});
workbook.xlsx.writeBuffer().then((data) => {
const blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
const url = window.URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = `테스트.xlsx`;
anchor.click();
window.URL.revokeObjectURL(url);
})
} catch(error) {
console.error(error);
}
}
'JavaScript > JavaScript 문법' 카테고리의 다른 글
[JavaScript]파일 입출력 - FileReader 객체 (0) | 2022.01.25 |
---|---|
[JavaScript]파일 업로드 구현 (0) | 2022.01.25 |
[JavaScript]객체 배열 정렬하는 방법 (0) | 2022.01.03 |
[JavaScript]소수점 반올림하는 방법 (0) | 2021.12.24 |
[JavaScript]객체를 배열로 변환하는 방법 (0) | 2021.12.24 |
댓글