환경은 Vue.js(Nuxt)이며, 백엔드는 Node.js 입니다.
엑셀 다운로드를 구현하기 위해 만들면서 정리하기위해서 작성하였습니다.
엑셀파일(기본 베이스)가 없고, HTML코드도 없는 상태에서 다운로드를 진행하려고 만든 것이기 떄문에
조건이 다르시다면 참고만 하시면 좋을 것 같습니다.
( npm의 xlsx와 sheetJS는 다른거라 생각했는데, npm에서보니 같은 것이여서 신기했습니다. )
1. 사용한 첫 번째 방법
<template>
<div>
<button
type="button"
@click="excelDownload"
>
엑셀 다운로드
</button>
</div>
</template>
<script>
import XLSX from 'xlsx'
export default {
methods: {
excelDownload() {
const workbook = XLSX.utils.book_new() // 엑셀 생성
const firstSheet = XLSX.utils.aoa_to_sheet([
[
'이름', // A1
'전화번호', // B1
],
[
'홍길동', // A2
{ // B2
v: '01012345678',
z: '@', // 데이터 포맷 형식 지정
},
],
])
firstSheet['!cols'] = [ // 넓이 지정
{ 'width': 12 }, // A열의 넓이
{ 'width': 17 }, // B열의 넓이
]
const secondSheet = XLSX.utils.aoa_to_sheet([
[
'테스트입니다.',
],
])
secondSheet['!rows'] = [ // 높이 지정
{ 'hpx': 100 }, // 1행의 높이
]
XLSX.utils.book_append_sheet(workbook, firstSheet, '시트제목1') // 시트 보내기
XLSX.utils.book_append_sheet(workbook, secondSheet, '시트제목2')
XLSX.writeFile(workbook, 'excel_test.xlsx') // 엑셀 다운로드
},
},
}
</script>
- B2를 입력한 방식처럼 Object 타입으로 입력할 수 있는데(옵션은 맨 마지막에..), 해당 옵션에 s라는 스타일 옵션이 존재는 한다.
하지만 옵션이 적용이 안된다..
찾아보니, 커뮤니티버전에서는 스타일이 적용이 안되며, 프로버전을 사용하거나 xlsx-style과 같은 스타일 라이브러리를 추가로 설치해주어야 한다고 한다.
2. 사용한 두 번째 방법
<template>
<div>
<button
type="button"
@click="excelDownload"
>
엑셀 다운로드
</button>
</div>
</template>
<script>
import XLSX from 'xlsx'
export default {
methods: {
excelDownload() {
// 기존 테이블이 있다면 생략
let table1 = document.createElement('table')
table1.innerHTML = `
<thead></thead>
<tbody>
<tr>
<th style="background-color: #ffff00; text-align: center;">
이름
</th>
<th style="background-color: #ffff00; text-align: center;">
전화번호
</th>
</tr>
<tr>
<td style="text-align: center;">
홍길동
</td>
<td style="text-align: center;">
01099999999
</td>
</tr>
</tbody>
`
let table2 = document.createElement('table')
table2.innerHTML = `
<thead></thead>
<tbody>
<tr>
<th style="background-color: #ffff00; text-align: center; font-size"; 30px;>
안내드립니다.
</th>
</tr>
<tr>
<td style="text-align: center;">
네 드렸습니다.
</td>
</tr>
</tbody>
`
const wb = XLSX.utils.book_new()
// 기존 테이블 있다면
// let fs = XLSX.utils.table_to_sheet(document.getElemenyById('tableId'))
let fs = XLSX.utils.table_to_sheet(table1)
fs['B2'].z = '@'
let ss = XLSX.utils.table_to_sheet(table2)
ss['!rows'] = [
{ 'hpx': 100 },
]
XLSX.utils.book_append_sheet(wb, fs, '입력란')
XLSX.utils.book_append_sheet(wb, ss, '공지')
XLSX.writeFile(wb, 'excel_test2.xlsx')
},
},
}
</script>
- 직접 css를 테이블에 때려박는 하드코딩도 시도해보았다.
- 스타일이 적용될 것이라 생각하였지만, 결과는 처참히 실패하였다.
- 또한 포맷형식을 지정해주었음에도 value가 먼저 적용이 된 뒤 포맷이 들어가서 0이 사라진 상태로 출력되었다.
결론
- 내가 테이블 데이터가 있다면 두 번째 방법이 더 편하겠지만, 저처럼 데이터가 없는 빈 상태에서 만들려고 한다면 첫 번째 방법이 더 간편하다.
한번에 여러 개의 셀의 포멧을 변경할 때
// 스택오버플로우에서 본 숫자 포멧 적용하는 function
function formatColumn(worksheet, col, fmt) {
const range = XLSX.utils.decode_range(worksheet['!ref'])
for (let row = range.s.r + 1; row <= range.e.r; ++row) {
const ref = XLSX.utils.encode_cell({ r: row, c: col })
if (worksheet[ref] && worksheet[ref].t === 'n') {
worksheet[ref].z = fmt
}
}
}
Merge(셀 병합)
const merge = [
{ s: { r: 1, c: 0 }, e: { r: 1, c: 0 } }, // A2:A3
{ s: { r: 3, c: 0 }, e: { r: 4, c: 0 } }, // A4:A5
]
ws["!merges"] = merge
s: start
e: end
r: row
c: column
A1 = { r: 0, c: 0 }
C7 = { r: 6, c: 2 }
셀 오브젝트의 s (Style) 옵션
- 나중에 style이 추가된 다른 라이브러리를 사용하거나, 프로를 사용할 때를 위한 메모..
let excelCell = {
v: "VALUE",
t: "s",
s: {
fill: {
patternType: "none",
fgColor: {rgb: "FF000000"},
bgColor: {rgb: "FFFFFFFF"}
},
font: {
name: 'Times New Roman',
sz: 16,
color: {rgb: "#FF000000"},
bold: false,
italic: false,
underline: false
},
alignment: {
vertical: "center",
horizontal: "center",
indent:0,
wrapText: true
},
border: {
top: {style: "thin", color: {auto: 1}},
right: {style: "thin", color: {auto: 1}},
bottom: {style: "thin", color: {auto: 1}},
left: {style: "thin", color: {auto: 1}}
}
}
}
XLSX.utils 속 method들
생각보다 많은 method들이 존재했지만,
시간이 없어서 아직 사용해보진 못해서 아쉽다..
셀 Object 옵션
참고
[ SheetJS github : https://github.com/SheetJS/sheetjs ]
[ SheetJS docs : https://docs.sheetjs.com/ ]
'JavaScript > Vue.js' 카테고리의 다른 글
Vue.js에서 Google Classroom API 사용 메모 (0) | 2023.06.14 |
---|---|
Nuxt에서 localhost를 https로 열기 (0) | 2022.08.30 |
Vue 컴포넌트에 외부 스크립트 추가 (메모용) (0) | 2022.03.18 |
[vue-gtag] Google Analytics 공부 (0) | 2022.01.11 |
Vue.js 페이징처리(Pagination) (0) | 2021.09.08 |