js xlsx使用說明(主要講導(dǎo)出表格與設(shè)置表頭相關(guān))

workbook: 可以理解為XLSX對(duì)excel文件描述的一個(gè)對(duì)象究驴,可通過 XLSX.utils.book_new()來創(chuàng)建弟胀,該方法返回workbook對(duì)象

worksheet:可以理解為XLSX對(duì) excelsheet的描述的一個(gè)對(duì)象像棘,可通過 XLSX.utils.aoa_to_sheetXLSX.utils.json_to_sheetXLSX.utils.table_to_sheet 等方法創(chuàng)建男旗,下面會(huì)具體講每個(gè)方法的使用趁啸。

cellAddress: 單元格的地址對(duì)象 { c: number, r: number }强缘,其中c表示column(列)r表示row(行)都是從0開始,即左上角的單元格地址是{c: 0, r: 0} ---> A1

打印worksheet對(duì)象不傅,可以看到描述的相關(guān)信息例如

{
   !cols: []
   !fullref: "A1:C3"
   !ref: "A1:C3"
   !rows: []
   A1: {t: "s", v: "第一列A"}
   A2: {t: "s", v: "1-1A"}
   A3: {t: "s", v: "2-1A"}
   B1: {t: "s", v: "第二列A"}
   B2: {t: "s", v: "1-2A"}
   B3: {t: "s", v: "2-2A"}
   C1: {t: "s", v: "第三列A"}
   C2: {t: "s", v: "1-3A"}
   C3: {t: "s", v: "2-3A"}
}

其中 !ref描述了這個(gè)表格的范圍(range)旅掂,第一個(gè)單元格是A1最后一個(gè)單元格是C3,下面的A1,A2,A3,B1...就是每個(gè)單元格的描述 ttype蛤签,表示類型辞友,即s就是string型。vvalue震肮,表示值称龙,每個(gè)單元格的數(shù)據(jù)。我們可以通過設(shè)置這個(gè)!ref屬性來截取表格的部分輸出戳晌。

表格的表頭會(huì)用A1鲫尊,B1,C1...的v值沦偎,所以如果想更改表頭疫向,可以遍歷更改上面的值。

比如通過json_to_sheet轉(zhuǎn)化booksheet對(duì)象豪嚎,字段的A1搔驼,B1,C1....等單元格中的是字段的key侈询,此時(shí)我們可能希望表頭是中文的舌涨,那么我們就需要把worksheet中的A1,B1扔字,C1...的v值改為我們想要的

可以看到單元格在上面都是字母+數(shù)字來描述的囊嘉,下面幾個(gè)方法可以把這種字母+數(shù)字轉(zhuǎn)化為數(shù)值

注意:excel中 列以 A開始温技,行以1開始,在XLSX中轉(zhuǎn)化為數(shù)值后行與列都是0開始

  • encode_row / decode_row 轉(zhuǎn)化行號(hào)

  • encode_col / decode_col 轉(zhuǎn)化列號(hào)

  • encode_cell / decode_cell 轉(zhuǎn)化單元格號(hào)

  • encode_range / decode_range 轉(zhuǎn)化表格范圍

后面會(huì)舉例說明

還有一些方法:

let wb_out = XLSX.write(workbook, opt) //將excel描述對(duì)象寫入扭粱,返回指定的數(shù)據(jù)對(duì)象
然后通過let _blob = new Blob([wb_out],{type: 'application/octet-stream'})轉(zhuǎn)為Blob對(duì)象
最后下載舵鳞,用到了FileSaver,通過FileSaver下載導(dǎo)出
import FileSaver from 'file-saver'
FileSaver.saveAs(_blob), '統(tǒng)計(jì)表.xlsx')
案例數(shù)據(jù)
//html
<table id="table">
   <thead>
    <tr>
     <th>第一列A</th>
     <th>第二列A</th>
     <th>第三列A</th>
    </tr>
   </thead>
   <tbody>
    <tr>
     <td>1-1A</td>
     <td>1-2A</td>
     <td>1-3A</td>
    </tr>
    <tr>
     <td>2-1A</td>
     <td>2-2A</td>
     <td>2-3A</td>
    </tr>
   </tbody>
</table>
XLSX.utils.table_to_book()

通過把頁面上已有的表格dom節(jié)點(diǎn)傳入(也可以動(dòng)態(tài)js生成),直接返回一個(gè)workbook對(duì)象

let wb = XLSX.utils.table_to_book(document.getElementById('table'));
let wb_out = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'})
FileSaver.saveAs(new Blob([wb_out], {type: 'application/octet-stream'}), '統(tǒng)計(jì)表.xlsx');
XLSX.utils.table_to_sheet()

把頁面上已有的表格dom節(jié)點(diǎn)傳入(也可以動(dòng)態(tài)js生成)琢蛤,直接返回一個(gè)worksheet對(duì)象

let ws = XLSX.utils.table_to_sheet(document.getElementById('table'))
//創(chuàng)建一個(gè)workbook對(duì)象
let wb = XLSX.utils.book_new()
//把worksheet對(duì)象添加進(jìn)workbook對(duì)象蜓堕,第三個(gè)參數(shù)是excel中sheet的名字
XLSX.utils.book_append_sheet(wb, ws, 'sheet1')
//接下來就是寫入,下載導(dǎo)出
let wb_out = XLSX.write(wb, {bookType: 'xlsx', type: 'array'})
FileSaver.saveAs(new Blob([wb_out], {type: 'application/octet-stream'}), '統(tǒng)計(jì)表.xlsx')
XLSX.utils.sheet_add_dom()

給worksheet對(duì)象追加一個(gè)表格dom

//得到一個(gè)worksheet對(duì)象
let ws = XLSX.utils.table_to_sheet(document.getElementById('table'))
//追加一個(gè)表格dom到 worksheet對(duì)象
//origin 默認(rèn)值是從表格的最開始即A1開始追加博其,會(huì)覆蓋前一個(gè)表格
//origin:-1 表示從上一個(gè)表格的末尾行追加
//origin: {c:4, r:0} cellAddress 會(huì)從這個(gè)單元格的位置開始追加
XLSX.utils.sheet_add_dom(ws, document.getElementById('另一個(gè)table'), {origin: {c: 4, r: 0}})

//接下來就跟上面步驟一樣了
//創(chuàng)建一個(gè)workbook對(duì)象
let wb = XLSX.utils.book_new()
//把worksheet對(duì)象添加進(jìn)workbook對(duì)象俩滥,第三個(gè)參數(shù)是excel中sheet的名字
XLSX.utils.book_append_sheet(wb, ws, 'sheet1')
//接下來就是寫入,下載導(dǎo)出
let wb_out = XLSX.write(wb, {bookType: 'xlsx', type: 'array'})
FileSaver.saveAs(new Blob([wb_out], {type: 'application/octet-stream'}), '統(tǒng)計(jì)表.xlsx')

XLSX.utils.json_to_sheet(data)

通過json數(shù)據(jù)轉(zhuǎn)成一個(gè)worksheet對(duì)象

let data = [
    {
        name: 'Eric',
        age: '20',
        hobby: 'ball',
        sex: 'boy'
    },
    {
        name: 'Lucy',
        age: '22',
        hobby: 'draw',
        sex: 'girl'
    },
    {
        name: 'Selina',
        age: '27',
        hobby: 'run',
        sex: 'girl'
    },
]
// 把json轉(zhuǎn)為worksheet對(duì)象
let ws = XLSX.utils.json_to_sheet(data)
// 創(chuàng)建workbook對(duì)象
let wb = XLSX.utils.book_new()
// 添加worksheet 到 workbook
XLSX.utils.book_append_sheet(wb, ws, 'sheet')
// 寫出 arraybuffer 數(shù)據(jù)
let wb_out = XLSX.write(wb, {bookType: 'xlsx', type: 'array'})
// 構(gòu)建Blob對(duì)象
let _blob = new Blob([wb_out], {type: 'application/octet-stream'})
//下載
FileSaver(_blob, '統(tǒng)計(jì)表.xlsx')
XLSX.utils.aoa_to_sheet(data)

aoa_to_sheetjson_to_sheet用法差不多贺奠,aoaarray of array二維數(shù)組

excel中的單元格坐標(biāo)(A1)轉(zhuǎn)化為XLSX中的數(shù)值
console.log(XLSX.utils.encode_col(1))  // B
console.log(XLSX.utils.decode_col('A'))  // 0
console.log(XLSX.utils.encode_row(1))  // 2
console.log(XLSX.utils.decode_row('1'))  // 0
console.log(XLSX.utils.encode_cell({c:0,r:0}))  // A1
console.log(XLSX.utils.decode_cell('A2')) // {c: 0, r: 1}
console.log(XLSX.utils.decode_range('A1:B2')) // {e: {c: 1, r: 1},s: {c: 0, r: 0}}
console.log(XLSX.utils.encode_range({s: {c:0,r:0},e: {c:1,r: 1}})) //A1:B2
自定義表頭
let source = [
    {
        name: 'Eric',
        age: '20',
        hobby: 'ball',
        sex: 'boy',
        eat: 'apple',
        extra: '多余的'
    },
    {
        name: 'Eric',
        age: '20',
        hobby: 'ball',
        sex: 'boy',
        eat: 'apple',
        extra: '多余的'
    },
    {
        name: 'Eric',
        age: '20',
        hobby: 'ball',
        sex: 'boy',
        eat: 'apple',
        extra: '多余的'
    },
]

// 需求:
// 原始數(shù)據(jù)比我們多一列 extra霜旧,我們需要剔除該列
// 原始數(shù)據(jù)的key會(huì)作為表頭,我們需要轉(zhuǎn)為中文

let field = ['name','age','hobby','sex','eat']
let label = {
    name: '名字',
    age: '年齡',
    hobby: '愛好',
    sex: '性別',
    eat: '吃'
}
// 找到最后一列的編號(hào)(一共是5列儡率,最后一列的編號(hào)是4挂据,轉(zhuǎn)換后是E)
let lastCol = XLSX.utils.encode_col(field.length - 1)
// 找到最后一行的編號(hào)(一共3行數(shù)據(jù),還有表頭占了一行儿普,所以最后一行的編號(hào)是3崎逃,轉(zhuǎn)換后是 4)
let lastRow = XLSX.utils.encode_row(source.length)

const ws = XLSX.utils.json_to_sheet(
    source,
    {
        header: field //通過設(shè)置field可以把這個(gè)field排在前頭,后續(xù)截取表格的時(shí)候眉孩,把尾部不需要的剔除
    }
)
// 找出 這個(gè)表格的 單元格 范圍
const range = XLSX.utils.decode_range(ws['!ref'])
// 重新設(shè)置 單元格范圍个绍,剔除不需要的(數(shù)據(jù)中的extra)列
ws['!ref'] = `A1:${lastCol}${lastRow}`

// 找到worksheet中 A1,B1,C1...等設(shè)置表頭的字段,替換為上方label對(duì)應(yīng)的數(shù)據(jù)
for (let c = range.s.c; c <= range.e.c; c++) {
    const header = XLSX.utils.encode_col(c) + '1'
    ws[header].v = label[ws[header].v]
}

// 最后 ws就是我們需要的worksheet
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末浪汪,一起剝皮案震驚了整個(gè)濱河市巴柿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌死遭,老刑警劉巖广恢,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異呀潭,居然都是意外死亡钉迷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門钠署,熙熙樓的掌柜王于貴愁眉苦臉地迎上來糠聪,“玉大人,你說我怎么就攤上這事谐鼎〗Ⅲ。” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長夭苗。 經(jīng)常有香客問我,道長隔缀,這世上最難降的妖魔是什么题造? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮猾瘸,結(jié)果婚禮上界赔,老公的妹妹穿的比我還像新娘。我一直安慰自己牵触,他們只是感情好淮悼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著揽思,像睡著了一般袜腥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钉汗,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天羹令,我揣著相機(jī)與錄音,去河邊找鬼损痰。 笑死福侈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的卢未。 我是一名探鬼主播肪凛,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼辽社!你這毒婦竟也來了伟墙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤滴铅,失蹤者是張志新(化名)和其女友劉穎远荠,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體失息,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡譬淳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盹兢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邻梆。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绎秒,靈堂內(nèi)的尸體忽然破棺而出浦妄,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布剂娄,位于F島的核電站蠢涝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏阅懦。R本人自食惡果不足惜和二,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耳胎。 院中可真熱鬧惯吕,春花似錦、人聲如沸怕午。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郁惜。三九已至堡距,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兆蕉,已是汗流浹背吏颖。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恨樟,地道東北人半醉。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像劝术,于是被迫代替她去往敵國和親缩多。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容