国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

xlsx庫實現(xiàn)純前端導(dǎo)入導(dǎo)出Excel

這篇具有很好參考價值的文章主要介紹了xlsx庫實現(xiàn)純前端導(dǎo)入導(dǎo)出Excel。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

xlsx庫實現(xiàn)純前端導(dǎo)入導(dǎo)出Excel

前言

最近做了前端導(dǎo)入、導(dǎo)出 Excel 的需求,用到了js-xlsx這個庫,該庫文檔提供的用例很少,并不是很友好。本文總結(jié)一下我是如何實現(xiàn)需求的。

需求

  • 提供一個 Excel 文件,將里面的內(nèi)容轉(zhuǎn)成 JSON 導(dǎo)入數(shù)據(jù)
  • 提供一個 JSON 文件,生成 Excel 文件并導(dǎo)出

導(dǎo)入與導(dǎo)出既可以前端做,也可以后端做。本文主要探討前端通過SheetJS/js-xlsx這個庫實現(xiàn) Excel 導(dǎo)入、導(dǎo)出功能。

技術(shù)選型

市面上的報表類產(chǎn)品大抵可以分為以下兩種:

  1. 云文檔類型產(chǎn)品
  2. 控件類型產(chǎn)品

像 SheetJS/js-xlsx、LuckySheet、Handsontable、SpreadJS 都是標準的純前端表格控件且都支持 Excel 的功能特性和 JSON 數(shù)據(jù)綁定。

最后選擇 SheetJS/js-xlsx 這個庫主要因為以下兩個原因:

  1. 社區(qū)版開源免費。也可選擇性能增強的專業(yè)版,專業(yè)版提供樣式和專業(yè)支持的附加功能。
  2. 有 30k star,維護頻率高,筆者在寫這篇文章時(5 月 10 日)該項目的上一次提交在 5 月 9 日。

基礎(chǔ)知識

新建一個 Excel 文檔,這個文檔就是workbook,而一個workbook?下可以有多個sheet。

SheetJS/js-xlsx

安裝

$ yarn add xlsx@0.16.9
復(fù)制代碼

建議跟上版本號,我第一次裝的時候沒跟上版本號沒有安裝成功。

常用的數(shù)據(jù)表格式(Common Spreadsheet Format)

js-xlsx符合常用的數(shù)據(jù)表格式(CSF)。

一般結(jié)構(gòu)

單元格地址對象的存儲格式為{c:C, r:R},其中CR分別代表的是 0 索引列和行號。例如單元格地址B5用對象{c:1, r:4}表示。

單元格范圍對象存儲格式為{s:S, e:E},其中S是第一個單元格,E是最后一個單元格。范圍是包含關(guān)系。例如范圍?A3:B7用對象{s:{c:0, r:2}, e:{c:1, r:6}}表示。

單元格對象

單元格對象是純粹的 JS 對象,它的 keys 和 values 遵循下列的約定:

Key Description
v 原始值(查看數(shù)據(jù)類型部分獲取更多的信息)
w 格式化文本(如果可以使用)
t 內(nèi)行:?b?Boolean,?e?Error,?n?Number,?d?Date,?s?Text,?z?Stub
f 單元格公式編碼為 A1 樣式的字符串(如果可以使用)
F 如果公式是數(shù)組公式,則包圍數(shù)組的范圍(如果可以使用)
r 富文本編碼 (如果可以使用)
h 富文本渲染成 HTML (如果可以使用)
c 與單元格關(guān)聯(lián)的注釋
z 與單元格關(guān)聯(lián)的數(shù)字格式字符串(如果有必要)
l 單元格的超鏈接對象 (.Target?長聯(lián)接,?.Tooltip?是提示消息)
s 單元格的樣式/主題 (如果可以使用)

如果w文本可以使用,內(nèi)置的導(dǎo)出工具(比如 CSV 導(dǎo)出方法)就會使用它。要想改變單元格的值,在打算導(dǎo)出之前確保刪除cell.w(或者設(shè)置?cell.wundefined)。工具函數(shù)會根據(jù)數(shù)字格式(cell.z)和原始值(如果可用)重新生成w文本。

真實的數(shù)組公式存儲在數(shù)組范圍中第一個單元個的f字段內(nèi)。此范圍內(nèi)的其他單元格會省略f字段。

更多詳細信息請查看文檔

前端導(dǎo)入 Excel 數(shù)據(jù)

/**
 * 將 file 轉(zhuǎn)為一個 CSF 的 JSON
 * @param {File} file
 * @returns sheet
 */
const analyseExcelToJson = (file) => {
 ?return new Promise((resolve, reject) => {
 ? ?if (file instanceof File) {
 ? ? ?const reader = new FileReader();
?
 ? ? ?reader.onloadend = (progressEvent) => {
 ? ? ? ?const arrayBuffer = reader.result;
?
 ? ? ? ?const options = { type: 'array' };
 ? ? ? ?const workbook = XLSX.read(arrayBuffer, options);
?
 ? ? ? ?const sheetName = workbook.SheetNames;
 ? ? ? ?const sheet = workbook.Sheets[sheetName];
?
 ? ? ? ?resolve(sheet);
 ? ?  };
 ? ? ?reader.readAsArrayBuffer(file);
 ?  } else {
 ? ? ?reject(new Error('入?yún)⒉皇?File 類型'));
 ?  }
  });
};
復(fù)制代碼

這里先用FileReaderfile轉(zhuǎn)換成ArrayBuffer,再用xlsx.read()轉(zhuǎn)換成workbook。由于FileReader是異步讀取,所以用promise處理了一下。最終可以看到 Excel 處理后生成了這樣的一

所以需要對analyseExcelToJson這個方法做一些修改,修改后如下:

/**
 * 將 file 轉(zhuǎn)為一個 CSF 的 JSON
 * @param {File} file
 * @returns sheets
 */
const analyseExcelToJson = (file) => {
 ?return new Promise((resolve, reject) => {
 ? ?if (file instanceof File) {
 ? ? ?const reader = new FileReader();
?
 ? ? ?reader.onloadend = (progressEvent) => {
 ? ? ? ?const arrayBuffer = reader.result;
?
 ? ? ? ?const options = { type: 'array' };
 ? ? ? ?const workbook = XLSX.read(arrayBuffer, options);
?
 ? ? ? ?const sheetNames = workbook.SheetNames;
 ? ? ? ?const result = sheetNames.map((sheetName) => workbook.Sheets[sheetName]);
 ? ? ? ?resolve(result);
 ? ?  };
 ? ? ?reader.readAsArrayBuffer(file);
 ?  } else {
 ? ? ?reject(new Error('入?yún)⒉皇?File 類型'));
 ?  }
  });
};
復(fù)制代碼

讀取數(shù)據(jù)按鈕方法如下:

由于我用了Promise.all用來處理讀取多個 Excel,所以看到外面又用數(shù)組包了一層。至此,簡單的前端導(dǎo)入 Excel 數(shù)據(jù)已經(jīng)全部實現(xiàn)了。

順帶一提,如果想要在頁面中展示sheet,可以使用XLSX.utils.sheet_to_html。

前端導(dǎo)出 Excel 文件

導(dǎo)出一般分為兩種:

  1. 數(shù)據(jù)導(dǎo)出 Excel
  2. 頁面表格導(dǎo)出 Excel

數(shù)據(jù)導(dǎo)出 Excel

前端在寫前端導(dǎo)入 Excel 數(shù)據(jù)方法,最后返回的其實是workbooksheet的集合。那么導(dǎo)出 Excel 文件便是將sheet拼成一個workbook導(dǎo)出即可。另外,導(dǎo)出的難點在于寫成 Excel 之后要立馬下載,而XLSX.writeFile直接幫我們實現(xiàn)這一步了。

/**
 *
 * @param {Array} sheets sheet的集合
 * @param {String} fileName 下載時文件名稱
 */
const exportExcelBySheets = (sheets, fileName = 'example.xlsx') => {
 ?const SheetNames = [];
 ?const Sheets = {};
 ?const workbook = { SheetNames, Sheets };
?
 ?sheets.forEach((sheet, i) => {
 ? ?const name = `sheet${i + 1}`;
 ? ?SheetNames.push(name);
 ? ?Sheets[name] = sheet;
  });
?
 ?return XLSX.writeFile(workbook, fileName, { type: 'binary' });
};
復(fù)制代碼

假設(shè)數(shù)據(jù)并非CSF而是如下的二維數(shù)組:

const ddArray = [
  ['S', 'h', 'e', 'e', 't', 'J', 'S'],
  [1, 2, 3, 4, 5],
];
復(fù)制代碼

可以使用方法如下:

/**
 *
 * @param {Array} workSheetData 二維數(shù)組
 * @param {String} fileName 下載時文件名稱
 */
const exportExcelByDoubleDimensArray = (workSheetData, fileName = 'example.xlsx') => {
 ?const ws = XLSX.utils.aoa_to_sheet(workSheetData);
 ?const workSheetName = 'MySheet';
 ?const workbook = XLSX.utils.book_new();
?
 ?XLSX.utils.book_append_sheet(workbook, ws, workSheetName);
 ?return XLSX.writeFile(workbook, fileName, { type: 'binary' });
};
復(fù)制代碼

頁面表格導(dǎo)出 Excel

將頁面中的表格導(dǎo)出 Excel,應(yīng)該是更加常見的情況。我們增加一個 Element-ui 的基礎(chǔ)表格如下:

導(dǎo)出方法如下:

/**
 * 將 table 轉(zhuǎn)換成 Excel 導(dǎo)出
 * @param {*} el table 的根 dom 元素
 * @param {*} fileName 下載時文件名稱
 */
const exportExcelByTable = (el, fileName = 'example.xlsx') => {
 ?if (!el) {
 ? ?throw new Error('沒有獲取到表格的根 dom 元素');
  }
 ?const options = { raw: true };
 ?const workbook = XLSX.utils.table_to_book(el, options);
?
 ?return XLSX.writeFile(workbook, fileName, { type: 'binary' });
};
復(fù)制代碼

頁面中使用的話,通過ref拿到組件實例,將$elVue 實例的根 DOM 元素作為入?yún)⒓纯伞?/p>

exportExcelByTable(this.$refs.table.$el);
復(fù)制代碼

踩坑

只用簡單表格作為示例的話,似乎一切都很完美。然而,我在使用Element-ui table做復(fù)雜表格時,踩了一些坑。

  1. 當(dāng)且不僅當(dāng)表的內(nèi)容為input、select這類組件而非普通的數(shù)據(jù)時,導(dǎo)出的 Excel 內(nèi)容為空
  2. 將表頭合并后,導(dǎo)出 Excel 仍能看到被合并的表頭那一列。
  3. 使用fixed屬性固定列時,導(dǎo)出的 Excel 數(shù)據(jù)會重復(fù)。

由于XLSX.utils.table_to_book這個方法實際上是將dom元素轉(zhuǎn)化為workbook,這些坑都可以歸類為獲取到的?dom元素不對。

表頭合并

為了更好理解,我先講表頭合并的問題。由于Element-ui table并沒有提供表頭合并的方法,我實際是通過修改rowspancolspan來實現(xiàn)跨行跨列,再使用display: none;這個css屬性將原先位置的元素隱藏。如下圖所示:

圖中“ID”的colspan為 2,“姓名”被我設(shè)置了display: none;。如果直接用我們之前表格導(dǎo)出 Excel 的方法,會發(fā)現(xiàn)雖然導(dǎo)出"ID"正確地變?yōu)榱藘闪?,但是“姓名”列并沒有隱藏。由此可以得出結(jié)論:display: none;并不會影響 Excel 的獲取。

所以我在項目中對于被隱藏的表頭會添加cell-hide這個css類來隱藏被合并的表頭。

.cell-hide {
  display: none;
}
復(fù)制代碼

然后在下載報表前,將合并的表頭dom刪除。

document.querySelectorAll('.cell-hide').forEach((item) => {
  item.parentNode.removeChild(item);
});

// 下面就可以正常下載了
復(fù)制代碼

內(nèi)容為組件

同樣利用**display: none;并不會影響 Excel 的獲取**的特性可以解決問題 1,只需在table-column中通過插槽增加被隱藏的dom,就可以正常拿到值了。代碼如下:

<el-table ref="table" :data="tableData" style="width: 600px; margin: 0 auto">
      <el-table-column prop="date" label="日期" width="180"> </el-table-column>
      <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
      <el-table-column prop="address" label="地址">
        <template slot="header">
          <span>地址</span>
        </template>
        <template slot-scope>
          <el-input :value="123" />
          <span style="display: none">123</span>
        </template>
      </el-table-column>
    </el-table>
復(fù)制代碼

使用fixed屬性固定表格列

先來看下,如果完全不處理,直接使用導(dǎo)出會是什么結(jié)果。以下面的 table2 為例,“日期”列被固定,導(dǎo)出的 excel 內(nèi)容重復(fù)。

exportExcelByTable(this.$refs.table2.$el);
復(fù)制代碼

xlsx庫實現(xiàn)純前端導(dǎo)入導(dǎo)出Excel

原因還是出在dom上,打印出 table 和 table2 的dom比較發(fā)現(xiàn),table2 多了css類為el-table__fixed的這個節(jié)點。

我的處理方法是先克隆節(jié)點,確保后續(xù)操作不會影響頁面中的 table2。通過遍歷克隆出的新節(jié)點,找到.el-table__fixed這個節(jié)點并刪除,最后返回新節(jié)點,發(fā)現(xiàn)可以輸出正常的 Excel 文件。具體代碼如下:

 exportExcelByTable2() {
   const newEl = this.removeFixedDom(this.$refs.table2.$el);
   exportExcelByTable(newEl);
 }

 removeFixedDom(el) {
   const newEl = el.cloneNode(true);

   newEl.childNodes.forEach((node) => {
     if (node.className === 'el-table__fixed') {
       node.parentNode.removeChild(node);
     }
   });
   return newEl;
 }
復(fù)制代碼

總結(jié)

js-xlsx這個庫功能很強大且使用簡單,足以應(yīng)付一般的導(dǎo)出導(dǎo)出需求,如果有美化導(dǎo)出 Excel 樣式的需求需要選擇 pro 版本。開發(fā)的難度主要在于閱讀提供用例不足且冗長的文檔。使用時注意維護好WorkbookSheet對象即可,LuckySheet、SpreadJS 也是類似的思路。?文章來源地址http://www.zghlxwxcb.cn/news/detail-401771.html

到了這里,關(guān)于xlsx庫實現(xiàn)純前端導(dǎo)入導(dǎo)出Excel的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 純前端實現(xiàn) 導(dǎo)入 與 導(dǎo)出 Excel

    純前端實現(xiàn) 導(dǎo)入 與 導(dǎo)出 Excel

    最近經(jīng)常在做 不規(guī)則 Excel 的導(dǎo)入,或者一些普通 Excel 的導(dǎo)出,當(dāng)前以上說的都是純前端來實現(xiàn);下面我們來聊聊經(jīng)常用到的Excel導(dǎo)出與導(dǎo)入的實現(xiàn)方案,本文實現(xiàn)技術(shù)棧以 Vue2 + JS 為例 導(dǎo)入分類: 調(diào)用 API 完全由后端來解析數(shù)據(jù),清洗數(shù)據(jù),前端只負責(zé)調(diào)用 API ; 前端解析

    2024年02月09日
    瀏覽(28)
  • Vue前端實現(xiàn)excel的導(dǎo)入、導(dǎo)出、打印功能

    導(dǎo)入導(dǎo)出依賴: npm install xlsx@0.16.9 npm install xlsx-style@0.8.13 --save 安裝xlsx-style,運行報錯 This relative module was not found: ./cptable in ./node_modules/xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js 解決報錯 在node_modulesxlsx-styledistcpexcel.js 807行 的 var cpt = require(\\\'./cpt\\\' + \\\'able\\\'); 改為: var cpt = cptable; 打印

    2023年04月08日
    瀏覽(23)
  • Vue3 exceljs庫實現(xiàn)前端導(dǎo)入導(dǎo)出Excel

    Vue3 exceljs庫實現(xiàn)前端導(dǎo)入導(dǎo)出Excel

    最近在開發(fā)項目時需要批量導(dǎo)入和導(dǎo)出Excel數(shù)據(jù),在實現(xiàn)這個需求時,我們既可以在前端完成數(shù)據(jù)解析和文件生成工作,也可以通過前端發(fā)起導(dǎo)入以及導(dǎo)出請求后,后端實現(xiàn)解析文件流解析文件內(nèi)容以及生成文件并提供下載鏈接的功能。 相較于后端處理Excel數(shù)據(jù)而言,使用前

    2024年03月14日
    瀏覽(18)
  • 【vue導(dǎo)入導(dǎo)出Excel】vue簡單實現(xiàn)導(dǎo)出和導(dǎo)入復(fù)雜表頭excel表格功能【純前端版本和配合后端版本】

    【vue導(dǎo)入導(dǎo)出Excel】vue簡單實現(xiàn)導(dǎo)出和導(dǎo)入復(fù)雜表頭excel表格功能【純前端版本和配合后端版本】

    前言 這是一個常用的功能,就是導(dǎo)入和導(dǎo)出excel表格 但是時常會遇到一些復(fù)雜表頭的表格導(dǎo)出和導(dǎo)入 比如我這個案例里面的三層表頭的表格。 網(wǎng)上看了下發(fā)現(xiàn)了一個非常簡單導(dǎo)出和導(dǎo)入方法 當(dāng)然這個是純前端的版本,會出現(xiàn)分頁不好下載的情況。所以實際工作中,導(dǎo)出還是

    2024年02月11日
    瀏覽(27)
  • vue3前端excel導(dǎo)出;組件表格,自定義表格導(dǎo)出;Vue3 + xlsx + xlsx-style

    vue3前端excel導(dǎo)出;組件表格,自定義表格導(dǎo)出;Vue3 + xlsx + xlsx-style

    當(dāng)畫面有自定義的表格或者樣式過于復(fù)雜的表格時,導(dǎo)出功能可以由前端實現(xiàn) 1. 使用的插件 : sheet.js-xlsx 文檔地址:https://docs.sheetjs.com/ 中文地址:https://geekdaxue.co/read/SheetJS-docs-zh/README.md xlsx-style:https://www.npmjs.com/package/xlsx-style 2. 安裝引用 安裝插件-vue3 引用插件 3. 組件表格

    2024年04月26日
    瀏覽(30)
  • vue導(dǎo)入導(dǎo)出excel、設(shè)置單元格背景色、文字居中、合并單元格、設(shè)置列寬(使用xlsx庫和xlsx-style庫)

    xlsx 是由 SheetJS 開發(fā)的一個處理excel文件的npm庫 適用于前端開發(fā)者實現(xiàn)導(dǎo)入導(dǎo)出excel文件的經(jīng)典需求 為了區(qū)別于xlsx文件,突出其應(yīng)用語言,該庫通常又被稱為 js-xlsx 需要以下步驟: 安裝 xlsx 庫 你可以使用 npm 包管理器安裝 xlsx 庫,也可以將 xlsx 下載到本地,然后在 HTML 文件中

    2024年02月16日
    瀏覽(20)
  • 前端使用xlsx-js-style導(dǎo)出Excel文件并修飾單元格樣式

    前端使用xlsx-js-style導(dǎo)出Excel文件并修飾單元格樣式

    安裝 導(dǎo)出 excel 較常見的 js 庫是之一是 xlsx, xlsx 算是基礎(chǔ)版本,不能對單元格進行樣式(對齊方式、文字顏色、背景顏色等)的修飾,如果需要修飾單元格,可使用 xlsx-js-style 引入 需要導(dǎo)出的數(shù)據(jù)源 將數(shù)據(jù)源轉(zhuǎn)成需要的二維數(shù)組 定義 Excel 表頭 將定義好的表頭添加到 body

    2023年04月08日
    瀏覽(23)
  • 前端excel文件處理,vue2 、file-saver、xlsx, excel文件生成與excel文件鏈接數(shù)據(jù)導(dǎo)出

    前端excel文件處理,vue2 、file-saver、xlsx, excel文件生成與excel文件鏈接數(shù)據(jù)導(dǎo)出

    安裝插件 如使用TS開發(fā),可安裝file-saver的TypeScript類型定義 下載文件流 本地文件下載 文件下載(列寬自適應(yīng)) 表格顯示,每列列寬自適應(yīng) xlsx文件鏈接數(shù)據(jù)導(dǎo)出 方法調(diào)用

    2024年02月11日
    瀏覽(28)
  • 前端導(dǎo)入導(dǎo)出excel記錄

    前端模塊的導(dǎo)入導(dǎo)出excel功能,大體分為兩個邏輯。 前端使用導(dǎo)入組件,獲取excel,交給 后端處理 前端使用導(dǎo)入組件,獲取excel,自己 解析數(shù)據(jù) ,然后調(diào)用數(shù)據(jù)存儲的方法。 我們分別對這兩種方法進行記錄。 導(dǎo)出 組件: 方法: api: util: 導(dǎo)入 組件: 方法: 工具方法: 導(dǎo)

    2024年02月12日
    瀏覽(30)
  • 【前端】批量導(dǎo)入和導(dǎo)出Excel數(shù)據(jù)

    【前端】批量導(dǎo)入和導(dǎo)出Excel數(shù)據(jù)

    excel導(dǎo)入功能需要使用npm包 xlsx ,所以需要安裝 xlsx 插件,讀取和寫入都依賴她 vue-element-admin模板提供了一個導(dǎo)入excel數(shù)據(jù)的文件,我們只需用即可 代碼地址: https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/UploadExcel/index.vue 將vue-element-admin提供的導(dǎo)入功能新建一個組件

    2024年02月09日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包