JavaScript導出excel文件,並修改文件樣式

說明

由於最近須要實現前端導出 excel 文件,而且對導出文件的樣式進行一些修改,好比顏色、字體、合併單元格等,因此我找到了 xlsx-style 這個項目,它能夠對導出的 excel 文件進行一些樣式上的修改,這個項目是 SheetJS 的一個分支。其實 SheetJS 也是支持修改導出文件的樣式的,不過是在它的專業版中, SheetJS 分爲社區版專業版的,社區版是開源的,可是卻不支持修改導出文件的樣式,專業版擁有更多的功能,這其中就包括修改樣式,可是若是須要使用專業版,要郵件聯繫 SheetJS 的開發者,去諮詢價格,購買它。html

下來講說如何使用 xlsx-style ,導出 excel 文件,並修改樣式。前端

示例:node

圖片未加載

安裝

CDN:git

<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.16.0/xlsx.min.js"></script>

npm:github

npm install xlsx-style --save

若是 npm 安裝時出現以下報錯,ajax

圖片未加載

須要修改源碼:
\node_modules\xlsx-style\dist\cpexcel.js 807行把 var cpt = require('./cpt' + 'able'); 改爲 var cpt = cptable; npm

\node_modules\xlsx-style\ods.js 10行和13行把路徑改成 require('./ xlsx') 數組

圖片未加載

bower:app

bower install js-xlsx-style#beta

單元格對象、工做表對象和工做簿對象解釋

圖片未加載

Cell Object

Cell Object 指單元格對象,格式爲 {c:C, r:R},其中 C 表明列號,R 表明行號。
例如單元格 B5 用對象表示就是 {c:1, r:4}函數

單元格範圍用對象表示爲{s:S, e:E},其中 S 表示第一個單元格對象,E 表示最後一個單元格對象。
例如單元格範圍 A3:B7 由對象表示就是 {s:{c:0, r:2}, e:{c:1, r:6}}

在工做表對象中設置一個單元格對象,是以編碼後的單元格爲屬性,進行設置。
例如:

//設置A1單元格的值是123,類型是字符串,字體顏色是FF0187FA
worksheet["A1"] = {
    v: "123",
    t: "s",
    s: {
        font: {
            color: { rgb: "FF0187FA" }
        },
    }
}

v:單元格的值
t:單元格的類型 'b'布爾值、'n'數字、'e'錯誤、's'字符串、'd'日期
s:單元格的樣式

單元格的屬性不止有vts這個三個屬性,還有其餘屬性,具體看這裏,可是實現導出功能,使用這三個已經足夠了。

XLSX.utils 對象中有一些方法能夠對單元格和單元格範圍進行轉化。

//編碼行號
XLSX.utils.encode_row(2);  //"3"
//解碼行號
XLSX.utils.decode_row("2"); //1

//編碼列標
XLSX.utils.encode_col(2);  //"C"
//解碼列標 
XLSX.utils.decode_col("A"); //0

//編碼單元格
XLSX.utils.encode_cell({ c: 1, r: 1 });  //"B2"
//解碼單元格
XLSX.utils.decode_cell("B1"); //{c: 1, r: 0}

//編碼單元格範圍
XLSX.utils.encode_range({ s: { c: 1, r: 0 }, e: { c: 2, r: 8 } });  //"B1:C9"
//解碼單元格範圍
XLSX.utils.decode_range("B1:C9"); //{s:{c: 1, r: 0},e: {c: 2, r: 8}}

Worksheet Object

Worksheet Object 指工做表對象,這個對象中每一個不以!開頭的屬性,都表明一個單元格。
例如 worksheet["A1"] 返回A1單元格對象。

  • worksheet['!ref']:表示工做表範圍的字符串。

例如:

worksheet['!ref'] = "A1:B5"
  • worksheet['!cols']:存儲列對象的數組,能夠在這裏設置列寬。

例如:

//wpx 字段表示以像素爲單位,wch 字段表示以字符爲單位
worksheet['!cols'] = [
    { wpx: 200 }, //設置第1列列寬爲200像素
    { wch: 50 },  //設置第2列列寬爲50字符
];
  • worksheet['!merges']:存儲合併單元格範圍的數組。

例如:

//合併B2到D4範圍內的單元格
worksheet['!merges'] = [
    {
        s: { c: 1, r: 1 }, //B2
        e: { c: 3, r: 3 }, //D4
    }
]
  • worksheet['!freeze']:凍結單元格。

例如:

//凍結第一行和第一列:
worksheet['!freeze'] = {
    xSplit: "1",  //凍結列
    ySplit: "1",  //凍結行
    topLeftCell: "B2",  //在未凍結區域的左上角顯示的單元格,默認爲第一個未凍結的單元格
    state: "frozen"
}

如下是打印相關的設置

  • worksheet['!rowBreaks']:行分頁數組。

例如:

//第一行爲一頁,第二行和第三行爲一頁,第三行以後爲一頁
worksheet['!rowBreaks'] = [1,3]
  • worksheet['!colBreaks']:列分頁數組。

例如:

//第一列爲一頁,第二列和第三列爲一頁,第三列以後爲一頁
worksheet['!colBreaks'] = [1,3]
  • worksheet['!pageSetup']:設置縮放大小和打印方向的對象。

例如:

//縮放100%,打印方向爲縱向
worksheet['!pageSetup'] = {
    scale: '100',
    orientation: 'portrait'
}
// orientation 取值以下:
// 'portrait'  - 縱向    
// 'landscape' - 橫向
  • worksheet['!printHeader']:須要重複的第一行和最後一行索引的數組,用於分頁時重複打印表頭。

例如:

//分頁時重複打印第一行
worksheet['!printHeader'] = [1,1]

Workbook Object

Workbook Object 指工做簿對象。

  • workbook.SheetNames:存儲工做表名稱的數組。
  • workbook.Sheets:存儲工做表對象的對象。
  • workbook.Sheets[sheetname]:返回對應名稱的工做表對象。

圖片未加載

單元格樣式

設置單元格的樣式,就是設置工做表對象中的單元格對象的 s 屬性。這個屬性的值也是一個對象,它有五個屬性:fillfontnumFmtalignmentborder

樣式屬性 子屬性 描述
fill patternType PatternTypes 圖案樣式
bgColor COLOR_SPEC 背景色,設置填充時的圖案顏色
fgColor COLOR_SPEC 前景色,單元格的背景顏色
font name 表示字體名稱的字符串 字體名稱,默認值是 "Calibri"
sz 表示字號的數字 字號
color COLOR_SPEC 字體顏色
bold truefalse 加粗
underline truefalse 下劃線
italic truefalse 傾斜
strike truefalse 刪除線
vertAlign 'superscript''subscript' 上標 或 下標
numFmt 字符串或數字 對數字類型的單元格進行格式化
alignment vertical "bottom""center""top" 垂直對齊
horizontal "left""center""right" 水平對齊
wrapText true false 自動換行
readingOrder 012 文字方向
textRotation 數字,0180255 (默認爲0 文本旋轉角度
45 逆時針旋轉45度
90 逆時針旋轉90度
135 順時針旋轉45度
180 順時針旋轉90度
255 垂直排列
border top { style: BORDER_STYLE, color: COLOR_SPEC } 上邊框樣式
bottom { style: BORDER_STYLE, color: COLOR_SPEC } 下邊框樣式
left { style: BORDER_STYLE, color: COLOR_SPEC } 左邊框樣式
right { style: BORDER_STYLE, color: COLOR_SPEC } 右邊框樣式
diagonal { style: BORDER_STYLE, color: COLOR_SPEC } 對角線樣式
diagonalUp truefalse 上對角線
diagonalDown truefalse 下對角線

PatternTypes

PatternTypes 指填充時的圖案樣式,取值以下:

none
solid
darkGray
mediumGray
lightGray
gray125
gray0625
darkHorizontal
darkVertical
darkDown
darkUp
darkGrid
darkTrellis
lightHorizontal
lightVertical
lightDown
lightUp
lightGrid
lightTrellis

Excel 中點擊單元格,選擇設置單元格格式,點擊填充會出現圖案樣式選項。

圖片未加載

COLOR_SPEC

COLOR_SPEC 指設定顏色的對象,取值以下:

圖片未加載

numFmt

樣式屬性 numFmt 的做用是對數字類型的單元格進行格式化。在 xlsx-style 中內置一個 table_fmt 對象,這個對象存儲了一些進行格式化的規則。

var table_fmt = {
    0: 'General',
    1: '0',
    2: '0.00',
    3: '#,##0',
    4: '#,##0.00',
    9: '0%',
    10: '0.00%',
    11: '0.00E+00',
    12: '# ?/?',
    13: '# ??/??',
    14: 'm/d/yy',
    15: 'd-mmm-yy',
    16: 'd-mmm',
    17: 'mmm-yy',
    18: 'h:mm AM/PM',
    19: 'h:mm:ss AM/PM',
    20: 'h:mm',
    21: 'h:mm:ss',
    22: 'm/d/yy h:mm',
    37: '#,##0 ;(#,##0)',
    38: '#,##0 ;[Red](#,##0)',
    39: '#,##0.00;(#,##0.00)',
    40: '#,##0.00;[Red](#,##0.00)',
    45: 'mm:ss',
    46: '[h]:mm:ss',
    47: 'mmss.0',
    48: '##0.0E+0',
    49: '@',
    56: '"上午/下午 "hh"時"mm"分"ss"秒 "'
};

numFmt 的取值以下:

  • 一、table_fmt 對象的屬性值。

例如:

worksheet["A1"].s.numFmt = "0.00%";
  • 二、table_fmt 對象的屬性名對應的數字。

例如:

worksheet["A1"].s.numFmt = 0;
  • 三、Excel 內置規則對應的字符串。

例如:

worksheet["A1"].s.numFmt = "yyyy/m/d h:mm";

Excel 中對應的操做就是,右鍵單元格,選擇設置單元格格式,選擇自定義,選擇 yyyy/m/d h:mm 類型。
圖片未加載

  • 四、若是熟悉 Excel 中的自定義格式,可使用自定義格式的字符串。

例如:

//單元格輸入1時顯示男,輸入0時顯示女 
worksheet["A1"].s.numFmt = '[=1]"男";[=0]"女"';

Excel 中對應的操做就是,右鍵單元格,選擇設置單元格格式,選擇自定義,在類型中輸入 [=1]"男";[=0]"女"
圖片未加載

readingOrder

樣式屬性 alignment 的子屬性 readingOrder 表示單元格的文字方向。語言的閱讀與書寫順序並不都是從左到右的,好比阿拉伯語就是從右到左的。

readingOrder 的取值以下:

  • 0:根據內容決定
  • 1:從左到右
  • 2:從右到左

Excel 中對應的操做就是,右鍵單元格,選擇設置單元格格式,在對齊選項中設置文字方向。

圖片未加載

BORDER_STYLE

BORDER_STYLE 是用來設置邊框樣式的一個字符串,可用取值以下:

  • thin

圖片未加載

  • medium

圖片未加載

  • thick

圖片未加載

  • dotted

圖片未加載

  • hair

圖片未加載

  • dashed

圖片未加載

  • mediumDashed

圖片未加載

  • dashDot

圖片未加載

  • mediumDashDot

圖片未加載

  • dashDotDot

圖片未加載

  • mediumDashDotDot

圖片未加載

  • slantDashDot

圖片未加載

  • double

圖片未加載

合併單元格的邊框是合併區域內的每一個單元格指定的。所以,若是須要設置3x3單元格合併後的單元格邊框,須要爲8個不一樣的單元格設置邊框:

  • 左側單元格的左邊框
  • 右側單元格的右邊框
  • 頂部單元格的上邊框
  • 底部單元格的下邊框

導出文件

xlsx-style 有兩個輸出數據的方法 writewriteFile 方法,須要注意的是 writeFile 方法須要基於 node 環境纔可使用。

XLSX.write(workbook, wopts);
XLSX.writeFile(workbook, filename, wopts);

filename:
writeFile 方法須要傳入 filename 參數,也就是要建立文件的名稱,也能夠是路徑。
例如:

XLSX.writeFile(workbook, "out.xlsx", wopts);
XLSX.writeFile(workbook, "./folder/out.xlsx", wopts);

wopts:

屬性名 默認值 描述
type 輸出數據類型(請參見下面的輸出類型)
cellDates false 將日期存儲爲類型'd'(默認爲'n')
bookSST false 是否生成共享字符串表
bookType 'xlsx' 工做簿的類型(xlsxxlsmxlsb)
showGridLines true 是否顯示網格線
Props null 工做簿的屬性

type:

描述
"base64" Base64編碼
"binary" 二進制字符串
"buffer" nodejs 緩衝區
"file" 直接建立文件(node 環境下有效)

若是使用 write 方法須要設置 type 屬性,並且若是設置 type 屬性爲 file,還須要在 wopts 參數中增長一個 file 屬性,值是要建立文件的路徑。

若是使用 writeFile 方法不須要設置 type 屬性,由於在 xlsx-style源碼中已經將 type 屬性設置爲 file 了, 並且使用這個方法,也不須要在 wopts 參數中設置 bookType 屬性,由於 bookType 是經過第二個參數 filename 來判斷的。

bookSST:
bookSST 設置爲 true 時會生成共享字符串表。
SST 指共享字符串表,一個工做簿可能有成千上萬個包含字符串(非數字)數據的單元格。而這些單元格中可能有許多重複數據。實現共享字符串表是爲了經過僅讀取和寫入重複數據一次來提升打開和保存文件的性能。
更詳情的解釋能夠參閱如下內容:
Working with the shared string table (Open XML SDK)
Exporting to excel using xlsx library and SST

Props:

Props 能夠設置爲一個對象,存入如下與工做簿相關的信息:

屬性名 描述
"title" 標題
"subject" 主題
"creator" 建立者
"keywords" 關鍵字
"description" 描述

設置這些屬性後,在 Excel 中點擊文件,選擇信息,而後點擊屬性,而後再點擊高級屬性,最後選擇摘要就能夠看到了。

圖片未加載

圖片未加載

圖片未加載

使用 write 方法實現下載:

var wopts = { bookType: 'xlsx', type: 'binary' };
var wbout = XLSX.write(workbook, wopts);

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;
}
var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });

function saveAs(obj, filename) {
    var link = document.createElement("a");
    link.download = filename;
    link.href = URL.createObjectURL(obj);
    link.click();
    URL.revokeObjectURL(obj);
}
saveAs(blob, "out.xlsx");

原理就是,把 write 方法輸出的數據,用 s2ab 方法轉爲 Uint8Array 對象,而後經過 new Blob 再獲得一個 Blob 對象,再經過 URL.createObjectURL 方法將 Blob 對象 做爲參數,獲得一個對象URL,最後把對象URL設置爲臨時的一個 a 連接的 href 屬性值,實現下載功能。

使用 writeFile 方法實現下載:

XLSX.writeFile(workbook, "out.xlsx");

雖然看上去使用 writeFile 方法要比 write 方法簡單不少,可是要注意 writeFile 方法只能在 node 環境下使用。

總結

前端導出 excel 文件,並修改導出文件樣式的功能最重要的就是準備好符合結構的工做簿對象(Workbook Object),在這個步驟設定好要導出文件的樣式,然後面的步驟都是固定的函數,就比較簡單了。

文中 Excel 相關的截圖,均是在 Microsoft Excel 2016 版截取的,不一樣版本的 Excel 顯示可能稍有不一樣。

相關文章
相關標籤/搜索