vue element 導(dǎo)出excel表格(前端實(shí)現(xiàn)excel合并單元格)

npm install --save xlsx file-saver


創(chuàng)建@/vendor/Export2Excel.js:

require('script-loader!file-saver');

require('script-loader!@/vendor/Blob'); //在vendor文件加下建立Blob.js淆九,代碼在最下方

import XLSXfrom 'xlsx'


function datenum(v, date1904) {

if (date1904) v +=1462;

var epoch =Date.parse(v);

return (epoch -new Date(Date.UTC(1899,11,30))) / (24 *60 *60 *1000);

}

function sheet_from_array_of_arrays(data, opts) {

var ws = {};

var range = {s: {c:10000000,r:10000000},e: {c:0,r:0}};

for (var R =0;R != data.length; ++R) {

for (var C =0;C != data[R].length; ++C) {

if (range.s.r >R)range.s.r =R;

if (range.s.c >C)range.s.c =C;

if (range.e.r

if (range.e.c

var cell = {v: data[R][C]};

if (cell.v ==null)continue;

var cell_ref = XLSX.utils.encode_cell({c:C,r:R});

if (typeof cell.v ==='number')cell.t ='n';

else if (typeof cell.v ==='boolean')cell.t ='b';

else if (cell.v instanceof Date) {

cell.t ='n';

cell.z = XLSX.SSF._table[14];

cell.v =datenum(cell.v);

}

else cell.t ='s';

ws[cell_ref] =cell;

}

}

if (range.s.c <10000000)ws['!ref'] = XLSX.utils.encode_range(range);

return ws;

}

function Workbook() {

if (!(this instanceof Workbook))return new Workbook();

this.SheetNames = [];

this.Sheets = {};

}

function s2ab(s) {

var buf =new ArrayBuffer(s.length);

var view =new Uint8Array(buf);

for (var i =0;i != s.length; ++i)view[i] = s.charCodeAt(i) &0xFF;

return buf;

}

// 單列合并數(shù)據(jù)加工

//在tableData數(shù)據(jù)中對colName列進(jìn)行加工(header:['xx','yy',...],mergeRule:[2,1,1,3,2,1...])

// 返回格式 newTableDatas = [[列頭s], ["abc", "ss", "yyy", 0], [null, "xx", "y", 1], ["bca", "xxx", "yy", 1], [null, "xxx", "yy", 1]]

// 返回格式 newMergeRules = [{"e":{"r":2,"c":0}, "s":{"r":1,"c":0}},{"e":{"r":4,"c":0}, "s":{"r":3,"c":0}}]

function formatTableData(header,tableDatas,mergeRules,colIndex,colName){

var newTableDatas = [header]// 第一行為列頭,

? var newMergeRules= []//加工合并規(guī)則

? var currRowIndex =1 // 因?yàn)榈谝恍袨榱蓄^所以起始為1

? var mergeIndexs = [currRowIndex]// 因?yàn)榈谝恍袨榱蓄^所以起始為1,為創(chuàng)建newTableDatas使用

? for(var i=0;i

var endRowIndex =currRowIndex + mergeRules[i] -1

? ? var merge = {"e":{"r":endRowIndex,"c": colIndex},"s":{"r":currRowIndex,"c":colIndex}}

newMergeRules.push(merge)

currRowIndex =currRowIndex + mergeRules[i]

mergeIndexs.push(currRowIndex)

}

for(var i=0;i

var currRow = tableDatas[i]

if(mergeIndexs.indexOf(i+1) === -1){

currRow[colName] =null //合并的數(shù)據(jù) 但不是第一行時(shí)潜支,此列賦值null

? ? }

var newTabRow = []

for (var j in currRow) {

newTabRow.push(currRow[j])

}

newTableDatas.push(newTabRow)

}

return [newTableDatas,newMergeRules]

}




@/vendor/Blob.js:

export function export_data_to_excel(header,tableDatas,mergeRules,colIndex,colName,excelName) {

var oo =formatTableData(header,tableDatas,mergeRules,colIndex,colName);

var ranges =oo[1];

/* original data */

? var data =oo[0];

var ws_name ="SheetJS";

var wb =new Workbook(),ws =sheet_from_array_of_arrays(data);

/* add ranges to worksheet */

// ws['!cols'] = ['apple', 'banan'];

? ws['!merges'] =ranges;

/* add worksheet to workbook */

? wb.SheetNames.push(ws_name);

wb.Sheets[ws_name] =ws;

var wbout = XLSX.write(wb, {bookType:'xlsx',bookSST:false,type:'binary'});

saveAs(new Blob([s2ab(wbout)], {type:"application/octet-stream"}), excelName+".xlsx")

}


(function (view) {

"use strict";

view.URL = view.URL || view.webkitURL;

if (view.Blob && view.URL) {

try {

new Blob;

return;

}catch (e) {}

}

// Internally we use a BlobBuilder implementation to base Blob off of

// in order to support older browsers that only have BlobBuilder

? ? var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {

var

? ? ? ? ? ? ? ? get_class =function(object) {

return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];

}

,FakeBlobBuilder =function BlobBuilder() {

this.data = [];

}

,FakeBlob =function Blob(data, type, encoding) {

this.data = data;

this.size = data.length;

this.type = type;

this.encoding = encoding;

}

,FBB_proto =FakeBlobBuilder.prototype

,FB_proto =FakeBlob.prototype

,FileReaderSync = view.FileReaderSync

,FileException =function(type) {

this.code =this[this.name = type];

}

,file_ex_codes = (

"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "

? ? ? ? ? ? ? ? ? ? +"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"

? ? ? ? ? ? ? ? ).split(" ")

,file_ex_code =file_ex_codes.length

,real_URL = view.URL || view.webkitURL || view

,real_create_object_URL =real_URL.createObjectURL

? ? ? ? ? ? ? ? ,real_revoke_object_URL =real_URL.revokeObjectURL

? ? ? ? ? ? ? ? ,URL =real_URL

? ? ? ? ? ? ? ? ,btoa = view.btoa

? ? ? ? ? ? ? ? ,atob = view.atob

? ? ? ? ? ? ? ? ,ArrayBuffer = view.ArrayBuffer

,Uint8Array = view.Uint8Array

;

FakeBlob.fake =FB_proto.fake =true;

while (file_ex_code--) {

FileException.prototype[file_ex_codes[file_ex_code]] =file_ex_code +1;

}

if (!real_URL.createObjectURL) {

URL = view.URL = {};

}

URL.createObjectURL =function(blob) {

var

? ? ? ? ? ? ? ? ? ? type = blob.type

? ? ? ? ? ? ? ? ? ? ,data_URI_header

? ? ? ? ? ? ? ? ? ? ;

if (type ===null) {

type ="application/octet-stream";

}

if (blobinstanceof FakeBlob) {

data_URI_header ="data:" +type;

if (blob.encoding ==="base64") {

return data_URI_header +";base64," + blob.data;

}else if (blob.encoding ==="URI") {

return data_URI_header +"," +decodeURIComponent(blob.data);

}if (btoa) {

return data_URI_header +";base64," +btoa(blob.data);

}else {

return data_URI_header +"," +encodeURIComponent(blob.data);

}

}else if (real_create_object_URL) {

return real_create_object_URL.call(real_URL, blob);

}

};

URL.revokeObjectURL =function(object_URL) {

if (object_URL.substring(0,5) !=="data:" &&real_revoke_object_URL) {

real_revoke_object_URL.call(real_URL, object_URL);

}

};

FBB_proto.append =function(data/*, endings*/) {

var bb =this.data;

// decode data to a binary string

? ? ? ? ? ? ? ? if (Uint8Array && (datainstanceof ArrayBuffer || datainstanceof Uint8Array)) {

var

? ? ? ? ? ? ? ? ? ? ? ? str =""

? ? ? ? ? ? ? ? ? ? ? ? ,buf =new Uint8Array(data)

,i =0

? ? ? ? ? ? ? ? ? ? ? ? ,buf_len =buf.length

;

for (;i

str +=String.fromCharCode(buf[i]);

}

bb.push(str);

}else if (get_class(data) ==="Blob" ||get_class(data) ==="File") {

if (FileReaderSync) {

var fr =new FileReaderSync;

bb.push(fr.readAsBinaryString(data));

}else {

// async FileReader won't work as BlobBuilder is sync

? ? ? ? ? ? ? ? ? ? ? ? throw new FileException("NOT_READABLE_ERR");

}

}else if (datainstanceof FakeBlob) {

if (data.encoding ==="base64" &&atob) {

bb.push(atob(data.data));

}else if (data.encoding ==="URI") {

bb.push(decodeURIComponent(data.data));

}else if (data.encoding ==="raw") {

bb.push(data.data);

}

}else {

if (typeof data !=="string") {

data +="";// convert unsupported types to strings

? ? ? ? ? ? ? ? ? ? }

// decode UTF-16 to binary string

? ? ? ? ? ? ? ? ? ? bb.push(unescape(encodeURIComponent(data)));

}

};

FBB_proto.getBlob =function(type) {

if (!arguments.length) {

type =null;

}

return new FakeBlob(this.data.join(""), type,"raw");

};

FBB_proto.toString =function() {

return "[object BlobBuilder]";

};

FB_proto.slice =function(start, end, type) {

var args =arguments.length;

if (args <3) {

type =null;

}

return new FakeBlob(

this.data.slice(start,args >1 ? end :this.data.length)

, type

,this.encoding

);

};

FB_proto.toString =function() {

return "[object Blob]";

};

FB_proto.close =function() {

this.size =this.data.length =0;

};

return FakeBlobBuilder;

}(view));

view.Blob =function Blob(blobParts, options) {

var type = options ? (options.type ||"") :"";

var builder =new BlobBuilder();

if (blobParts) {

for (var i =0,len = blobParts.length;i

builder.append(blobParts[i]);

}

}

return builder.getBlob(type);

};

}(typeof self !=="undefined" &&self ||typeof window !=="undefined" &&window ||this.content ||this));

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辅肾,隨后出現(xiàn)的幾起案子陪毡,更是在濱河造成了極大的恐慌米母,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毡琉,死亡現(xiàn)場離奇詭異铁瞒,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)桅滋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門精拟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人虱歪,你說我怎么就攤上這事蜂绎。” “怎么了笋鄙?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵师枣,是天一觀的道長。 經(jīng)常有香客問我萧落,道長践美,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任找岖,我火速辦了婚禮陨倡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘许布。我一直安慰自己兴革,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著杂曲,像睡著了一般庶艾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擎勘,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天咱揍,我揣著相機(jī)與錄音,去河邊找鬼棚饵。 笑死煤裙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的噪漾。 我是一名探鬼主播硼砰,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼怪与!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缅疟,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤分别,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后存淫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耘斩,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年桅咆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了括授。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岩饼,死狀恐怖荚虚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情籍茧,我是刑警寧澤版述,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站寞冯,受9級特大地震影響渴析,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吮龄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一俭茧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漓帚,春花似錦母债、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漓踢。三九已至,卻和暖如春漏隐,著一層夾襖步出監(jiān)牢的瞬間喧半,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工青责, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挺据,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓脖隶,卻偏偏與公主長得像扁耐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子产阱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

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

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,029評論 0 2
  • 不支持上傳文件婉称,所以就復(fù)制過來了。作者信息什么的都沒刪构蹬。對前端基本屬于一竅不通王暗,所以沒有任何修改,反正用著沒問題就...
    全棧在路上閱讀 1,960評論 0 2
  • 感恩今天是周一庄敛,早上5點(diǎn)多就起來給女兒做飯俗壹,要送她去上學(xué)。感恩女兒夸我做的早餐好吃藻烤,感恩女兒這段時(shí)間學(xué)習(xí)的心態(tài)很好...
    武丹yoyo閱讀 199評論 0 4
  • 初見绷雏,一眼透過萬年。 他的容顏亙古不變怖亭,三千銀發(fā)涎显,紫衫翩躚。 凝眸回首兴猩,他目光流轉(zhuǎn)棺禾,掠過千年的風(fēng)塵而來,扣響她心間...
    與子同說閱讀 2,159評論 9 18
  • 昨晚睡覺前打開了阿加莎的這本無人生還峭跳,劇情太精彩膘婶,居然一口氣看完了,看到一點(diǎn)多蛀醉,困悬襟。 讀這本阿婆的經(jīng)典小說,首先映...
    eeMY9n閱讀 1,948評論 0 0