Hello, 各位勇敢的小夥伴, 你們好, 我是大家的嘴強王者小五, 身體健康, 腦子沒病.前端
本人有豐富的脫髮技巧, 能讓你一躍成爲資深大咖.git
一看就會一寫就廢是本人的主旨, 菜到摳腳是本人的特色, 卑微中透着一絲絲剛強, 傻人有傻福是對我最大的安慰.github
歡迎來到
小五
的隨筆系列
之前端導出Excel在線指北
.npm
雙手奉上代碼連接 傳送門 - ajun568後端
雙腳奉上最終效果圖數組
觀前提醒工具
👺 本文最終實現效果如上圖, 具體功能爲: 導出Excel + 多個Sheet + 可合併的多行表頭
. 代碼部分採用 React+TS
做爲工具進行編寫.post
👺 安裝 xlsx.js npm install xlsx
搜索引擎
👺 寫入Excel文件: XLSX.write(workbook, writeOpts)
編碼
workbook 👇
@types string[]
: 當前 Sheet 的名稱[SheetNames]: { "!refs": "A1:G7", // 表示從 第1行第A列 到 第7行第G列 "!cols": [{wpx: 80} ... ], // 表示 列寬 80px "!rows": [{hpx: 20} ... ], // 表示 行高 20px "!merges": [{s: {r: 0, c: 2}, e: {r: 0, c: 3}} ... ], // 表示 將 第0行第2列 和 第0行第3列 進行合併 (s: start, e: end, c: column, r: row) "A1": {v: "姓名"}, // 表示第1行第A列 顯示數據爲 "姓名", 以此類推 ... ... }
writeOpts 👇
{ type, // 數據編碼, 本文采用 binary 二進制格式 bookType, // 導出類型, 本文采用 xlsx 類型 compression, // 是否使用 Gzip 壓縮 }
想要下載文件, 我小A第一個表示不服, 申請出戰 <a 標籤的 download 屬性>
經過 URL.createObjectURL(Object) 來建立下載所需的 URL. 因爲每次調用都會產生新的 URL 對象, 故使用後記得釋放, 釋放方法 URL.revokeObjectURL(FileUrl)
經過模擬 click 事件觸發 a 標籤, 以實現下載
const saveAs = (obj: Blob, fileName?: string): void => { const temp = document.createElement('a') temp.download = fileName || 'download' temp.href = URL.createObjectURL(obj) temp.click() setTimeout(() => { URL.revokeObjectURL(temp.href) }, 100) }
Mock數據: 詳細數據請跳轉 Github, 在 mock.ts
中查看
Header 部分數據格式
[ ... { key: 'animal', value: '動物', child: [ { key: 'dog', value: '狗', child: [ { key: 'corgi', value: '柯基', }, { key: 'husky', value: '哈士奇', }, ], }, { key: 'tiger', value: '老虎', }, ], }, ... ]
Data 部分數據格式
[ { name: '黃刀小五', desc: '基於搜索引擎的複製粘貼攻城獅', watermelon: '喜歡', banana: '不喜歡', corgi: '喜歡', husky: '喜歡', tiger: '不喜歡', }, ... ]
👺 分析
🧟♂️ Code
🧟♂️ Image
{ s: { // start r: x, // row c: y, // column }, e: { ... } // end }
👺 分析
tips: 本文采用的是判斷相鄰 value 值是否相等進行合併, 如有需求, 建議改寫爲對象形式加以完善.
🧟♂️ Code
🧟♂️ Image
Object.assign
進行對象合併String.fromCharCode(65 + i)
對列進行大寫字母的轉換🧟♂️ Code
🧟♂️ Image
利用 new ArrayBuffer(str) 建立一個緩衝區, 使用 new Uint8Array(buf)
引用
由於 unicode 編碼是 0~65535, 而 Uint8Array 範圍爲 0~255, 故須要按位與 0xFF, 以保持位數一致
const s2ab = (str: string): ArrayBuffer => { let buf = new ArrayBuffer(str.length) let view = new Uint8Array(buf) for (let i = 0; i !== str.length; ++i) { view[i] = str.charCodeAt(i) & 0xFF } return buf }
結合前文 準備工做 部分所講, 導出的代碼邏輯就出來了, 直接上代碼
開源版本不支持設置樣式, 如有需求, 可採用 付費版本 或使用 xlsx-style
, 使用方法與本文一致. 你們可參照文檔自行添加樣式部分.