-
要完成導(dǎo)出樣式如下圖
- 1-4行:標(biāo)題
- 5-12行:項(xiàng)目的基本信息 inputProData
- 13-20行:項(xiàng)目的指標(biāo)信息 indexsArray(每種指標(biāo)的數(shù)量不固定)
-
需要的數(shù)據(jù)和格式:
2.1 inputProData是個(gè)對(duì)象{}恬试,基本信息以鍵值對(duì)的方式存在inputProData對(duì)象中轴踱。
2.2 indexsArray是個(gè)數(shù)組[], 每一條指標(biāo)信息對(duì)應(yīng)一個(gè)indexsArray[i]莉掂。
具體數(shù)據(jù)格式如下圖袋毙。ps:這里假設(shè)已獲取了下圖這些數(shù)據(jù)。
- HTML
- 這里講1.單條導(dǎo)出2.批量導(dǎo)出砸烦,單條導(dǎo)出從頁面獲取數(shù)據(jù)導(dǎo)出成excel弃鸦,批量導(dǎo)出從后臺(tái)獲取數(shù)據(jù)。批量導(dǎo)出是導(dǎo)出一個(gè)excel多個(gè)工作簿sheet
- 按鈕綁定事件如下圖幢痘。
<span onclick="doInputImport()">單條導(dǎo)出</span>
<span onclick="doInputeExp()">批量導(dǎo)出</span>
- 要引入 'jszip', 'bolb', 'xlsx', 'fileSaver' JS!!! jszip引用要放在最前面唬格。
- JS
- 單條導(dǎo)入
先定義一個(gè)exlFun 對(duì)象,存放關(guān)于excel導(dǎo)出的方法
var exlFun = {};
//后面格式轉(zhuǎn)換要用到
var capital = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var digit = [1, 26, 676, 17576];
var capital_zero = "-0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
單條導(dǎo)入方法:doInputImport
doInputImport= function(){
//TODO 1.從頁面獲取數(shù)據(jù) 標(biāo)題數(shù)據(jù)通過項(xiàng)目名稱拼湊
var inputProData = operateData.getDataFromDiv('inputProInfo');//基本信息
var indexsArray = viewModel.indexsGridDataTable.getSimpleData();//指標(biāo)信息
//TODO 2.拼湊excel數(shù)據(jù)數(shù)據(jù)格式并導(dǎo)出 PRJ_NAME存放項(xiàng)目名稱
exlFun.creatExcel(inputProData,indexsArray,null,inputProData.PRJ_NAME+"項(xiàng)目支出績效目標(biāo)申報(bào)表",'nobatch');
}
exlFun.creatExcel:
//創(chuàng)建excel并導(dǎo)出(這里因?yàn)閷?shí)際項(xiàng)目原因颜说,將批量導(dǎo)出和單條導(dǎo)出寫一起了购岗,可以先只看非批量的導(dǎo)出)
/**
* inputProData:項(xiàng)目基本信息(批量處理時(shí)inputProData傳的是所有要導(dǎo)出項(xiàng)目的信息,包括每個(gè)項(xiàng)目的基本信息和指標(biāo)信息)
* indexsArray:項(xiàng)目指標(biāo)信息
* opt:可為空null
* fileName:excel文件名稱
* type
**/
exlFun.creatExcel = function(inputProData,indexsArray,opt,fileName,type){
opt = opt || {};
if(type == 'nobatch'){//非批量
opt.proData = inputProData;//存放項(xiàng)目信息
opt.indexsData = indexsArray;//存放指標(biāo)信息
//文件名稱(如果未傳fileName,以導(dǎo)出文件加日期命名)
fileName = fileName || "導(dǎo)出文件" + getCurrentDate() + ".xlsx";
if (fileName.slice(-5).toLowerCase() != '.xlsx') {
fileName = fileName + ".xlsx";
}
//將網(wǎng)頁項(xiàng)目數(shù)據(jù)轉(zhuǎn)換成excle數(shù)據(jù)格式sheet
var sheet = exlFun.getExcelSheet(opt, fileName);
//導(dǎo)出(下載)excel
exlFun.saveExcelFile(sheet, fileName);
}else{//批量
var sheets = [];var proNames = [];//分開存放每個(gè)項(xiàng)目sheet
//獲取不同項(xiàng)目的基本數(shù)據(jù)
for(var i=0; i<inputProData.length; i++){
var proData = inputProData[i].targetPro;
var indexsData = inputProData[i].targetIdx;
//將數(shù)據(jù)的null-->''
comFun.dealUndefine(proData);
comFun.dealArrOrObjUndefine(indexsData);
////將網(wǎng)頁項(xiàng)目數(shù)據(jù)轉(zhuǎn)換成excle數(shù)據(jù)格式sheet
opt.proData = proData;//項(xiàng)目信息
opt.indexsData = indexsData;//指標(biāo)信息
var sheet = exlFun.getExcelSheet(opt, fileName);
//將單個(gè)項(xiàng)目sheet放入sheets數(shù)組
sheets.push(sheet);
proNames.push(proData.PRJ_NAME);
}
//文件名
fileName = fileName || "導(dǎo)出文件" + getCurrentDate() + ".xlsx";//文件名稱
if (fileName.slice(-5).toLowerCase() != '.xlsx') {
fileName = fileName + ".xlsx";
}
//導(dǎo)出(下載)excel多個(gè)工作簿sheet
exlFun.saveBatchExcelFile(sheets,fileName,proNames);//opt放所有sheets
}
}
exlFun.getExcelSheet:
exlFun.getExcelSheet = function(opt, fileName){
var maxHeadRow = 4;//表頭 4行
var maxHeadCol = 9;//表格 9列 :A-I
//excel總行數(shù):表頭+指標(biāo)數(shù)據(jù)行數(shù)+指標(biāo)標(biāo)題行數(shù)+項(xiàng)目信息行數(shù)
var rowsLength = maxHeadRow + opt.indexsData.length + 1 + 8;
opt.maxHeadCol = 9;
var colWidth = [];//存放列寬
var rowHeight = [];//存放行高
var sheet = {
'!merges': [],//存放單元格合并信息
'A2': {//標(biāo)題放在A2單元格门粪,見圖1 (標(biāo)題=項(xiàng)目名稱+fileName文件名稱)
v: opt.proData.PRJ_NAME+fileName.replace(".xlsx",""),
},
'A3': {
v: "( 2018年度)",
},
'!ref': 'A1:I4',
}
//設(shè)置標(biāo)題單元格樣式style 加粗喊积,黑色,居中顯示
sheet["A2"].s = { font: { sz: 14, bold: true, color: { rgb: "000000" } },
alignment: {horizontal: "center" ,vertical: "center"}
/* fill: { bgColor: { indexed: 64 }, fgColor: { rgb: "FFFF00" } }*/
};
sheet["A3"].s = { font: { sz: 14, bold: false, color: { rgb: "000000" } },
alignment: {horizontal: "center" ,vertical: "center"}
};
//獲取不同指標(biāo)級(jí)的行數(shù)
var indexsTypeNum = exlFun.getIndexTypeNum(opt.indexsData);
//獲取合并單元格信息
var sheet = exlFun.getMerges(sheet,rowsLength,indexsTypeNum);
// console.log(sheet['!merges']);
//將項(xiàng)目基本信息加入sheet
sheet = exlFun.getExcelProData (opt,sheet);
//將項(xiàng)目指標(biāo)信息加入sheet
sheet = exlFun.getExcelIndexsData(opt,sheet,rowsLength,maxHeadCol,indexsTypeNum)
//設(shè)置excel范圍 :A1:I34
sheet['!ref'] = 'A1:' + exlFun.index2ColName(maxHeadCol) + rowsLength;
sheet["!cols"] = colWidth;
sheet["!rows"] = rowHeight;
//設(shè)置列寬為100
for(var n = 0; n < maxHeadCol; n++){
sheet['!cols'].push({
wpx: 100
});
}
sheet.maxHeadRow = maxHeadRow;/excel表頭標(biāo)題行數(shù)
sheet.maxHeadCol = maxHeadCol;//excel列數(shù)
sheet.rowLenght = opt.indexsData.length + 1 + 8;//excel行數(shù)
return sheet;
}
//index轉(zhuǎn)為列名玄妈,如:28 轉(zhuǎn)為 AB
exlFun.index2ColName = function(index) {
var colName = "";
var j = 0;
for (var i = digit.length - 1; i >= 0; i--) {
j = Math.floor(index / digit[i]);
if (j > 0) {
colName += capital[j - 1];
index = index % digit[i];
} else {
if (colName.length > 0) {
colName += "0"
}
}
}
colName = colName.split("");
for (var x = colName.length - 1; x >= 0; x--) {
if (colName[x] == "0") {
//向高位借位處理0
if (colName.join("").substring(0, x).replace(/0/g, "") != "") {
colName[x] = "Z";
colName[x - 1] = capital_zero[capital_zero.indexOf(colName[x - 1]) - 1];
} else {
break;
}
} else if (colName[x] == "-") { //向高位借位乾吻,還低位的借位
colName[x] = "Y";
colName[x - 1] = capital_zero[capital_zero.indexOf(colName[x - 1]) - 1];
}
}
return colName.join("").replace(/0/g, "");
}
合并單元格 exlFun.getMerges:
例如:項(xiàng)目名稱單元格A5,從第0行拟蜻,第0列開始绎签,在第0行,第3列結(jié)束酝锅。這路合并信息都是從0開始計(jì)算诡必。單元格合并信息為:
sheet['!merges'].push({//項(xiàng)目名稱
s: {r: 0, c: 0},//s指start:開始,r指row:行 搔扁,c指col:列
e: {r: 0, c: 2}//e指end:結(jié)束
})
/**
* sheet:excel數(shù)據(jù)擒权,存放sheet['!merges']
* rowsLength:行數(shù)
* indexsTypeNum:不同級(jí)次的指標(biāo)個(gè)數(shù)
**/
exlFun.getMerges = function(sheet,rowsLength,indexsTypeNum){
for(var i=0; i<rowsLength-1; i++){
//行合并 - 項(xiàng)目信息
if(i == 0 || i == 1){//row:1-2 col:0-8
sheet['!merges'].push({
s: {r: i+1, c: 0},
e: {r: i+1, c: 8}
})
}else if(i == 2 ){
}else if(i == 3){//row:4 col:0-2 / 3-8
sheet['!merges'].push({
s: {r: i+1, c: 0},
e: {r: i+1, c: 2}
});
sheet['!merges'].push({
s: {r: i+1, c: 3},
e: {r: i+1, c: 8}
});
}else if(i == 4 || i == 5){//row:5-6 col:0-2 / 3-4 / 5-6 / 7-8
sheet['!merges'].push({
s: {r: i+1, c: 0},
e: {r: i+1, c: 2}
});
sheet['!merges'].push({
s: {r: i+1, c: 3},
e: {r: i+1, c: 4}
});
sheet['!merges'].push({
s: {r: i+1, c: 5},
e: {r: i+1, c: 6}
});
sheet['!merges'].push({
s: {r: i+1, c: 7},
e: {r: i+1, c: 8}
});
}else if(i == 6 || i == 7 || i == 8){//row:7-9 col:0-2/5-6/7-8
sheet['!merges'].push({
s: {r: i+1, c: 5},
e: {r: i+1, c: 6}
});
sheet['!merges'].push({
s: {r: i+1, c: 7},
e: {r: i+1, c: 8}
});
}else if(i == 9 || i == 10){//row:10-11 col:1-4/5-8
sheet['!merges'].push({
s: {r: i+1, c: 1},
e: {r: i+1, c: 4}
});
sheet['!merges'].push({
s: {r: i+1, c: 5},
e: {r: i+1, c: 8}
});
}else{//row:12-end col:6-7
sheet['!merges'].push({
s: {r: i+1, c: 6},
e: {r: i+1, c: 7}
});
}
}
//列合并-一二級(jí)指標(biāo)
var indexsMer = exlFun.getColMer(indexsTypeNum);
for(var m=0; m<indexsMer.length; m++){
sheet['!merges'].push(indexsMer[m]);
}
//項(xiàng)目信息
sheet['!merges'].push({//項(xiàng)目資金
s: {r: 7, c: 0},
e: {r: 9, c: 2}
})
sheet['!merges'].push({//總體目標(biāo)
s: {r: 10, c: 0},
e: {r: 11, c: 0}
})
//指標(biāo)信息
sheet['!merges'].push({//績效指標(biāo)
s: {r: 12, c: 0},
e: {r: rowsLength-1, c: 0}
})
sheet['!merges'].push({//總體目標(biāo)
s: {r: 10, c: 0},
e: {r: 11, c: 0}
})
return sheet
}
項(xiàng)目基本信息加入sheet :exlFun.getExcelProData
//獲取excel項(xiàng)目數(shù)據(jù),這個(gè)也是根據(jù)excel模板(有固定數(shù)據(jù)和動(dòng)態(tài)數(shù)據(jù))
exlFun.getExcelProData = function(opt,sheet){
var proDatas = opt.proData;
sheet['A5'] = {"v": "項(xiàng)目名稱"};//固定
sheet['A6'] = {"v": "主管部門及代碼"};
sheet['A7'] = {"v": "項(xiàng)目屬性"};
sheet['A8'] = {"v": "項(xiàng)目資金(萬元)"};
sheet['A11'] = {"v": "總體目標(biāo)"};
sheet['A13'] = {"v": "績效指標(biāo) "};
sheet['B11'] = {"v": "中期目標(biāo)(20××年—20××+n年)"};
sheet['B13'] = {"v": "一級(jí)指標(biāo)"};
sheet['C13'] = {"v": "二級(jí)指標(biāo)"};
sheet['D8'] = {"v": "中期資金總額"};
sheet['D9'] = {"v": "其中:財(cái)政撥款"};
sheet['D10'] = {"v": "其他資金"};
sheet['D13'] = {"v": "三級(jí)指標(biāo)"};
sheet['D5'] = {"v": proDatas.PRJ_NAME};//項(xiàng)目名稱 動(dòng)態(tài)
sheet['D6'] = {"v": proDatas.MGR_DEPT_CODE+proDatas.MGR_DEPT_NAME};//主管部門代碼名稱
sheet['D7'] = {"v": proDatas.PRJ_KIND};//項(xiàng)目屬性
sheet['E13'] = {"v": "指標(biāo)值"};
sheet['E8'] = {"v": proDatas.MTT_AMOUNT};//中期資金總額
sheet['E9'] = {"v": proDatas.MTF_AMOUNT};//其中:財(cái)政撥款
sheet['E10'] = {"v": proDatas.MTO_AMOUNT};//其他資金
sheet['F6'] = {"v": "實(shí)施單位"};
sheet['F7'] = {"v": "項(xiàng)目期"};
sheet['F8'] = {"v": "年度資金總額"};
sheet['F9'] = {"v": "其中:財(cái)政撥款"};
sheet['F10'] = {"v": "其他資金"};
sheet['F11'] = {"v": "年度目標(biāo)"};
sheet['F13'] = {"v": "二級(jí)指標(biāo)"};
sheet['G13'] = {"v": "三級(jí)指標(biāo)"};
sheet['H6'] = {"v": proDatas.EXEC_DEPT_NAME};//實(shí)施單位
sheet['H7'] = {"v": "開始-結(jié)束"};//項(xiàng)目期
sheet['H8'] = {"v": proDatas.YT_AMOUNT};// 年度資金總額
sheet['H9'] = {"v": proDatas.YF_AMOUNT};//其中:財(cái)政撥款
sheet['H10'] = {"v": proDatas.YO_AMOUNT};//其他資金
sheet['I13'] = {"v": "指標(biāo)值"};
return sheet//返回sheet
}
獲取excel指標(biāo)數(shù)據(jù): exlFun.getExcelIndexsData
exlFun.getExcelIndexsData = function(opt,sheet,rowsLength,maxHeadCol,indexsTypeNum){
var proDatas = opt.indexsData;
var indexsIndex = exlFun.getRowIndexs(indexsTypeNum);//指標(biāo)行數(shù)下標(biāo)
var indexsRow1 = indexsIndex.indexRows1;
var indexsRow2 = indexsIndex.indexRows2;
console.log();
var lengths1 = indexsTypeNum.levelLength1;//[14,7]
var lengths2 = indexsTypeNum.levelLength2;//[14,7]
for (var r = 0; r <= rowsLength; r++) {//r:excel行
for (var c = 0; c < maxHeadCol; c++) {//c:excel列
var addrIndex = exlFun.index2ColName(c + 1);//A-I
if(r >= 13){//指標(biāo)開始行
for(var a=0; a<indexsRow1.length; a++){
if( (indexsRow1[a]+1) == r && (addrIndex == 'B') ){//一級(jí)指標(biāo)
sheet[addrIndex + r] = {"v": proDatas[r-14].LEVEL1_INDEX};
}
}
for(var b=0; b<indexsRow2.length; b++){
if( (indexsRow2[b]+1) == r && (addrIndex == 'C' || addrIndex == 'F') ){//二級(jí)指標(biāo)
sheet[addrIndex + r] = {"v": proDatas[r-14].LEVEL2_INDEX};
}
}
if(r > 13){//14...
for(var o=0; o<proDatas.length; o++){//三級(jí)指標(biāo)和指標(biāo)值
sheet['D' + r] = {"v": proDatas[r-14].LEVEL3_INDEX};
sheet['E' + r] = {"v": proDatas[r-14].INDEX_VAL};
sheet['G' + r] = {"v": proDatas[r-14].LEVEL3_INDEX_YEAR};
sheet['I' + r] = {"v": proDatas[r-14].INDEX_VAL_YEAR};
}
}
}
}
}
return sheet
}
單條導(dǎo)出:exlFun.saveExcelFile
//利用Blob將數(shù)據(jù)轉(zhuǎn)換成excel格式
exlFun.saveExcelFile = function(sheet, fileName){
var wb = {
SheetNames: ['Sheet1'],
Sheets: {
'Sheet1': sheet
}
};
var wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};
//要引入xlsx.js
var wbout = XLSX.write(wb, wopts);
saveAs(new Blob([s2ab(wbout)], {type: ""}), fileName);
}
//String轉(zhuǎn)換為ArrayBuffer
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;
}
其他處理指標(biāo)數(shù)據(jù)的方法:
//獲取不同類型指標(biāo)數(shù)量
exlFun.getIndexTypeNum = function(indexsData){
var levelLength = {};
levelLength.levelLength1 = [];//不同一級(jí)指標(biāo)的個(gè)數(shù)
levelLength.levelLength2 = [];//不同二級(jí)指標(biāo)的個(gè)數(shù)
var index1 = 0,index2 = 0;
for(var i=0; i<indexsData.length; i++){
var num1 = 0;var num2 = 0;
if(indexsData[i].LEVEL1_INDEX){
if(i!=0){//不是第一個(gè) 指標(biāo)一
num1 = i-index1;//指標(biāo)個(gè)數(shù)
index1 = i;
levelLength.levelLength1.push(num1);
}
}
if(indexsData[i].LEVEL2_INDEX){
if(i!=0){//不是第一個(gè) 指標(biāo)二
num2 = i-index2;//指標(biāo)個(gè)數(shù)
index2 = i;
levelLength.levelLength2.push(num2);
}
}
if(i == indexsData.length-1){//判斷最后一行指標(biāo)
if(!indexsData[i].LEVEL1_INDEX){//最后一行沒有指標(biāo)一
num1 = i+1-index1;
index1 = i;
levelLength.levelLength1.push(num1);
}else{
levelLength.levelLength1.push(1);//最后一行單獨(dú)的指標(biāo)一
}
if(!indexsData[i].LEVEL2_INDEX){
num2 = i+1-index2;
index2 = i;
levelLength.levelLength2.push(num2);
}else{
levelLength.levelLength2.push(1);
}
}
}
return levelLength
}
//獲取一二級(jí)指標(biāo)名稱的行數(shù)
exlFun.getRowIndexs = function(indexsTypeNum){
var rowIndex = {};
var lengths1 = indexsTypeNum.levelLength1;//[14,7]
var lengths2 = indexsTypeNum.levelLength2;//[14,7]
var indexRows1 = exlFun.getRowIndex(lengths1);
var indexRows2 = exlFun.getRowIndex(lengths2);
rowIndex.indexRows1 = indexRows1;
rowIndex.indexRows2 = indexRows2;
return rowIndex
}
//獲取某級(jí)指標(biāo)名稱行下標(biāo)
exlFun.getRowIndex = function(lengths){
var startRow = 13;
var n = 0,rows = [];
rows.push(startRow);
for(var k=0; k<lengths.length-1; k++){
n = lengths[k];
startRow = startRow + n;
rows.push(startRow);
}
return rows
}
//指標(biāo)單元格信息
exlFun.getColMer = function(indexsTypeNum){
var startRow1 = 13;
var startRow2 = 13;
var lengths1 = indexsTypeNum.levelLength1;//一級(jí)指標(biāo)數(shù)量數(shù)組[14,6]
var lengths2 = indexsTypeNum.levelLength2;//一級(jí)指標(biāo)數(shù)量數(shù)組[14,6]
var n = lengths1[0];
var m = lengths2[0];
var indexsMer = [];
for(var k=1; k<=lengths1.length; k++){
//13~26/27~33(end) -->col:1
var indexMer1 = {
s: {r: startRow1, c: 1},
e: {r: startRow1 + n - 1, c: 1}//TODO r:i+產(chǎn)出指標(biāo)/效果指標(biāo)個(gè)數(shù) 12+14=26 26+7=33
};
startRow1 = startRow1 +n;
n = lengths1[k];
indexsMer.push(indexMer1);
}
for(var k=1; k<=lengths2.length; k++){
//13~16/17~19/20~22 -->col:2 /5
var indexMer2 = {
s: {r: startRow2, c: 2},
e: {r: startRow2 + m - 1, c: 2}//TODO r:i+產(chǎn)出指標(biāo)/效果指標(biāo)個(gè)數(shù) 12+14=26 26+7=33
};
var indexMer3 = {
s: {r: startRow2, c: 5},
e: {r: startRow2 + m - 1, c: 5}//TODO r:i+產(chǎn)出指標(biāo)/效果指標(biāo)個(gè)數(shù) 12+14=26 26+7=33
};
startRow2 = startRow2 +m;
m = lengths2[k];
indexsMer.push(indexMer2);
indexsMer.push(indexMer3);
}
return indexsMer
}
- 批量導(dǎo)出
批量導(dǎo)出就獲取數(shù)據(jù)的方法阁谆、 exlFun.saveExcelFile方法略有不同。
/**
* 批量導(dǎo)出
*/
doBatchExp = function(){
//TODO 1.根據(jù)CHR_ID從后臺(tái)獲取數(shù)據(jù)
var currViewModel = comFun.getCurrViewModel();//判斷當(dāng)前活動(dòng)頁
ids = currViewModel.gridData.getSimpleData({//獲取選擇的行CHR_ID
type : 'select',
fields : [ 'CHR_ID' ]
});
if (ids == 0) {
ip.ipInfoJump("請(qǐng)至少選擇一條數(shù)據(jù)愉老!", "error");
return;
}
var batchProDatas = [];//存放不同項(xiàng)目數(shù)據(jù)
ids.forEach(function(obj){
//TODO 從后臺(tái)獲取每條數(shù)據(jù)的項(xiàng)目信息和指標(biāo)信息场绿,放在detailsObj
var detailsObj = ajaxObj.batchExp(obj.CHR_ID);
batchProDatas.push(detailsObj);
})
//TODO 批量導(dǎo)出,方法同單條導(dǎo)出嫉入,參數(shù)意義不同
exlFun.creatExcel(batchProDatas,null,null,"項(xiàng)目支出績效目標(biāo)申報(bào)表",'batch');
}
利用Blob將數(shù)據(jù)轉(zhuǎn)換成excel格式 -- 批量:exlFun.saveBatchExcelFile
exlFun.saveBatchExcelFile = function(sheetArr,fileName,proNames){
var wb = {
SheetNames: [],
Sheets: {},
};
for(var i=0; i<sheetArr.length; i++ ){
wb.SheetNames.push('Sheet'+(i+1));
wb.Sheets['Sheet'+(i+1)] = sheetArr[i]
//以下代碼可以替換頁簽(工作簿名稱)焰盗,但要保證名稱一定不同
/*wb.SheetNames.push(proNames[i]);
wb.Sheets[proNames[i]] = sheetArr[i];*/
}
var wopts = {bookType: 'xlsx', bookSST: false, type: 'binary'};
var wbout = XLSX.write(wb, wopts);//xlsx.js
saveAs(new Blob([s2ab(wbout)], {type: ""}), fileName);
}
//String轉(zhuǎn)換為ArrayBuffer
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;
}