二進制數組實戰 - 純前端導出Excel文件

以往在處理數據導出相關工做時,我的習慣使用腳本語言來完成,例如nodejs、ruby等,但它們對環境都有必定依賴。在瀏覽器的環境下,如何完成該類型操做?下面會給出一種簡單且兼容性較好的方案。html

Excel的基本概念

在進行Excel導出以前,先介紹一下它的基本概念:前端

  • Workbook 每一個Workbook對應一個Excel文件node

  • Worksheet 一個Excel文件中能夠同時包含多個Worksheet數組

使用工具

此次咱們會選用SheetJS來進行Excel表格的導出 瀏覽器

這是一個同時適用於Browser/Nodejs環境的電子表格編輯庫,主要功能包括:ruby

  • 讀取並解析Excel文件
  • 編輯表格內容
  • 將數據以Excel文件形式導出

操做流程

使用SheetJS進行Excel文件的導出大體能夠分爲如下幾步:bash

Step1.組織數據

首先咱們將須要導出的數據組織好,推薦使用模板引擎生成,最終造成一個table節點,形如:網絡

<table id="user_info">
    	<thead>
    		<tr>
    			<th>序號</th>
    			<th>名字</th>
    			<th>性別</th>
    			<th>愛好</th>
    		</tr>
    	</thead>
    	<tbody>
    		<tr>
    			<td>1</td>
    			<td>Alice</td>
    			<td>女</td>
    			<td>看電影</td>
    		</tr>
    		<tr>
    			<td>2</td>
    			<td>Zacks</td>
    			<td>男</td>
    			<td>看書</td>
    		</tr>
    	</tbody>
    </table>
複製代碼

Step2.使用SheetJS將dom節點或html文本轉換成Workbook

// 生成一個新的workbook,而後往workbook追加worksheet
const cleanWorkbook = XLSX.utils.book_new();
const table = document.getElementById('user_info');
const worksheet = XLSX.utils.table_to_sheet(table);
XLSX.utils.book_append_sheet(cleanWorkbook, worksheet, "sheet2");

// 只須要一個worksheet的時候能夠直接read method生成workbook,此時worksheet名稱默認爲"Sheet1"
const directWorkbook = XLSX.read(table.outerHTML, {
	type: 'string'
});

複製代碼

Step3.將workbook轉換爲二進制

const stringToArrayBuffer = function (string) {
	const buffer = new ArrayBuffer(string.length);
	const view = new Uint8Array(buffer);
	for (let i = 0, i !== string.length; ++i) {
		view[i] = string.charCodeAt(i) & 0xFF;
	}
	return buffer;
}
const ab = stringToArrayBuffer(XLSX.write(cleanWorkbook, {
	bookType: 'xlsx',
	type: 'binary'
}));
const tmpDown = new Blob([ab], { type: '' });
複製代碼

Step4.觸發Excel文件的自動下載

const a = document.createElement('a');
// 利用URL.createObjectURL()方法爲a元素生成blob URL
a.href = URL.createObjectURL(tmpDown)  // 建立對象超連接
a.download = 'demo.xlsx';
a.click();
複製代碼

就這樣,瀏覽器就會將生成的Excel文件自動下載到本地,下面是實際效果。 架構

二進制數組

在上面的例子裏面,咱們使用了ArrayBuffer進行二進制數據的操縱,下面簡單展開一下:app

使用過WebGL的同窗應該知道,這是瀏覽器與顯卡之間的通訊接口,爲了知足JavaScript與顯卡之間大量且實時的數據交換,它們之間的通訊數據必須是二進制,而不能是傳統的文本格式。若是以文本格式傳遞一個32位整數,兩端都要進行數據轉換,這個部分的時間損耗是不可忽略的,所以願景仍是可以直接傳輸二進制數據,二進制數組就是在這個背景之下誕生的。

它的組成有如下三部分:

  • ArrayBuffer對象: 表明內存之中的一段二進制數據,但不能直接操做,必須經過創建視圖來進行數據操縱。
  • TypedArray對象: 經過傳遞ArrayBuffer的實例生成對應的內存視圖,視圖的數據格式共有9種,例如:Uint8Array(無符號8位整數)數組視圖, Int16Array(16位整數)數組視圖, Float32Array(32位浮點數)數組視圖。
  • DataView對象: 與TypedArray對象相似,不一樣的地方在於這個對象能夠自定義格式和字節序,好比第一個字節是Uint8(無符號8位整數)、第二個字節是Int16(16位整數)、第三個字節是Float32(32位浮點數)等等。
const stringToArrayBuffer = function (string) {
    const buffer = new ArrayBuffer(string.length);
    const view = new Uint8Array(buffer);
    for (let i = 0, i !== string.length; ++i) {
        view[i] = string.charCodeAt(i) & 0xFF;
    }
    return buffer;
}
複製代碼

在這個轉換函數裏面,咱們先是經過ArrayBuffer申請了一段與待轉換字符串字節數等長的內存,而後經過創建Uint8的視圖將二進制數據按字節裝載到這段內存裏面,這就是一個比較簡單的js二進制數據操縱例子。

小結

經過上面的介紹,咱們能夠發現純前端進行數據導出仍是比較簡單的。 在平常的使用中,咱們須要針對不一樣場景來進行技術選型,從架構搭建的成原本看,純前端的實現方案可以在不依賴服務端能力和網絡的狀況下完成數據導出。雖然如此,數據量較大的時候,站在性能及用戶交互體驗的角度考慮,在服務端完成會是更優雅的解法。

相關文章
相關標籤/搜索