整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          如何用Excel制作一張能在網(wǎng)上瀏覽的動(dòng)態(tài)數(shù)據(jù)報(bào)表

          如今各類BI產(chǎn)品大行其道,“數(shù)據(jù)可視化”成為一個(gè)熱門詞匯。相比價(jià)格高昂的各種BI軟件,用Excel來(lái)制作動(dòng)態(tài)報(bào)表就更加經(jīng)濟(jì)便捷。今天小編就將為大家介紹一下如何使用葡萄城公司的純前端表格控件——SpreadJS來(lái)實(shí)現(xiàn)一個(gè)Excel動(dòng)態(tài)報(bào)表:

          實(shí)現(xiàn)步驟

          1.在原始數(shù)據(jù)的基礎(chǔ)上生成數(shù)據(jù)透視表

          制作這樣的數(shù)據(jù)大屏首先必須要明確目的,比如在這里圍繞銷售金額制作一個(gè)數(shù)據(jù)大屏,首先點(diǎn)擊數(shù)據(jù)源,然后點(diǎn)擊插入找到數(shù)據(jù)透視表,隨后將年份放在行字段,然后將銷售金額放在值字段,因?yàn)樵谶@里數(shù)值比較大,可以選擇銷售金額這一列數(shù)據(jù),然后按快捷鍵Ctrl 1調(diào)出格式窗口,點(diǎn)擊自定義,將類型設(shè)置為0!.0,這樣的話就變?yōu)榱巳f(wàn)元顯示,然后在設(shè)計(jì)中找到總計(jì),選擇對(duì)行和列禁用,將數(shù)據(jù)透視表中的總計(jì)禁用掉。

          2.根據(jù)數(shù)據(jù)生成圖表

          選擇數(shù)據(jù)區(qū)域,然后在圖表中找到餅圖,隨后為餅圖添加數(shù)據(jù)標(biāo)簽,緊接著點(diǎn)擊標(biāo)簽按Ctrl + 1調(diào)出格式窗口,勾選類別名稱然后將分隔符設(shè)置為新的文本行,最后將無(wú)用的圖例刪掉即可,至此的第一個(gè)圖表就制作完畢了。

          為了添加更多圖表,復(fù)制剛才設(shè)置的數(shù)據(jù)透視表,在復(fù)制的數(shù)據(jù)透視表中將年份這個(gè)字段拖走,然后將省份這個(gè)字段放在行字段,最后將數(shù)字更改為萬(wàn)元顯示,然后插入一個(gè)橫向的條形圖,將無(wú)用的圖例刪除掉即可。需要注意的是,你需要設(shè)置幾個(gè)圖表,就需要復(fù)制幾次數(shù)據(jù)透視表,更改為自己需要的字段,最后插入圖表,在這里就以3個(gè)為例跟大家演示制作方法。

          為了讓多張圖表能夠聯(lián)動(dòng)變化,點(diǎn)擊數(shù)據(jù)透視表,在工具欄中找到插入切片器,然后分別勾選,年份,省份,廠商點(diǎn)擊確定,這樣的話就插入了3個(gè)切片器,隨后將他們更改下大小放在合適的位置即可。隨后點(diǎn)擊一個(gè)切片器,在切片器選項(xiàng)中選擇鏈接到報(bào)表,勾選其他的兩個(gè)報(bào)表即可,以此類推,其余的2個(gè)切片器也需要這樣設(shè)置,設(shè)置完畢后就制作完畢了。

          至此,一張簡(jiǎn)單的可視化數(shù)據(jù)報(bào)表就制作好了。有時(shí)候,制作好的可視化報(bào)表需要通過(guò)網(wǎng)絡(luò)讓更多的人查閱,那么有什么好辦法呢?

          實(shí)現(xiàn)在線化

          下面小編為大家介紹如何使用借助SpreadJS實(shí)現(xiàn)在線化查看:

          首先打開SpreadJS的學(xué)習(xí)指南:

          按照學(xué)習(xí)指南上的代碼進(jìn)行編程實(shí)踐:

          <!DOCTYPE html>
          <html>
          <head>
            <meta charset='UTF-8'>
            <title>Spread-CDN</title>
            <link rel='icon' href='./assets/images/logo.png' type='image/x-icon'>
            <link
              href='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets/styles/gc.spread.sheets.excel2013white.css'
              rel='stylesheet' type='text/css' />
            <script type='text/javascript'
                    src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets/dist/gc.spread.sheets.all.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-print/dist/gc.spread.sheets.print.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-excelio/dist/gc.spread.excelio.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-io/dist/gc.spread.sheets.io.min.js'></script>
            <script
              src='https://cdn.grapecity.com.cn/SpreadJS/package-contents/16.2.2/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js'></script>
            <script>
              GC.Spread.Common.CultureManager.culture('zh-cn')
            </script>
            <style>
                * {
                    margin: 0;
                    padding: 0;
                }
          
                #app {
                    overflow: hidden;
                }
          
                #spread-container {
                    width: 100vw;
                    height: 100vh;
                }
            </style>
          </head>
          <body>
          <input type="file" id="file"/>
          <div id='app'>
            <div id='spread-container'></div>
          </div>
          
          <script>
            const spread = new GC.Spread.Sheets.Workbook('spread-container')
            let sheet = spread.getActiveSheet()
            const fileElement = document.querySelector('#file')
            fileElement.addEventListener('change', function (e) {
              const file = e.target.files[0]
              spread.import(file, ()=>{
                fileElement.style.display = 'none'
              })
            })
          </script>
          </body>
          </html>

          這里使用<input type="file" />來(lái)選擇本地文件,在成功導(dǎo)入后將該元素隱藏,以便在全屏預(yù)覽報(bào)表時(shí)沒(méi)有多余元素干擾。想導(dǎo)入其他模板時(shí),只需刷新頁(yè)面,用來(lái)選擇模板文件的按鈕就又出現(xiàn)了。

          最后導(dǎo)入在Excel中制作好的報(bào)表模板,一張可在線瀏覽的動(dòng)態(tài)Excel報(bào)表就大功告成了。

          總結(jié)

          文章只是簡(jiǎn)單演示,沒(méi)有加復(fù)雜的樣式,如果您想做出更好的顯示效果,可以充分調(diào)用自己的藝術(shù)細(xì)胞,做出更加美觀炫酷的動(dòng)態(tài)報(bào)表,甚至做一個(gè)數(shù)據(jù)大屏也是可以實(shí)現(xiàn)的,如果您對(duì)的SpreadJS感興趣的話,也歡迎訪問(wèn)SpreadJS官網(wǎng)。

          想在網(wǎng)站上展示 Excel 數(shù)據(jù)時(shí),將Excel 轉(zhuǎn)換為 HTML 是最佳選擇。Excel 非常適合組織數(shù)據(jù),而 HTML 表格則非常適合網(wǎng)頁(yè)。因此,我們將在本篇文章中講解如何將 Excel 電子表格轉(zhuǎn)換為 HTML 表格,此外,我們還將討論具有內(nèi)置人工智能功能的轉(zhuǎn)換器工具。

          第 1 部分:如何在 Windows 和 Mac 上將 Excel 轉(zhuǎn)換為 HTML?

          市面上有兩種可以信賴的流行工具,包括 UPDF PDF 編輯器和 MS Excel,這兩種工具都為 Windows 和 Mac 平臺(tái)上的用戶提供了有效的轉(zhuǎn)換功能。我們?cè)谙旅娓敿?xì)地解釋了這些工具。

          方式 1. 通過(guò) UPDF 將 Excel 導(dǎo)出為 HTML

          UPDF是將 Excel 導(dǎo)出為 HTML 的首選,因?yàn)樗浅?煽浚粌H可以轉(zhuǎn)換 PDF,還可以轉(zhuǎn)換各種其他文件類型,包括 Excel 到 HTML。

          UPDF 的突出功能之一是它能夠保持原始文檔的質(zhì)量和格式。它甚至能夠識(shí)別掃描文檔, 即用OCR 功能將文檔轉(zhuǎn)換為可編輯文本。用它將 Excel 轉(zhuǎn)換為 HTML 文件的步驟如下:

          第1步:打開UPDF工具并創(chuàng)建PDF

          首先,啟動(dòng) UPDF 程序,然后,在左上角找到“文件”選項(xiàng)卡并單擊它。然后,向下移動(dòng)到“創(chuàng)建”選項(xiàng)并將光標(biāo)置于打開“創(chuàng)建”選項(xiàng)。從列表中選擇“從Excel 創(chuàng)建 PDF”,找到電子表格并將其打開。

          第 2 步:導(dǎo)出轉(zhuǎn)換后的電子表格并保存

          導(dǎo)入 Excel 文件后它將轉(zhuǎn)換為 PDF 格式。然后,前往右側(cè)面板并點(diǎn)擊“導(dǎo)出 PDF”按鈕。接下來(lái),從提供的列表中選擇“HTML”,然后根據(jù)需要繼續(xù)自定義“文檔語(yǔ)言”、“頁(yè)面范圍”和文本識(shí)別設(shè)置。最后,按“導(dǎo)出”按鈕將轉(zhuǎn)換后的 HTML 文件存儲(chǔ)在 Windows 或 Mac 上。

          方式 2. 通過(guò) Microsoft Excel 將 Excel 轉(zhuǎn)換為HTML

          使用 Microsoft Excel 將 Excel轉(zhuǎn)換為 HTML 非常方便,只需幾個(gè)簡(jiǎn)單的步驟,并且這個(gè)方法會(huì)保留電子表格的結(jié)構(gòu)、格式和公式,其他人可以輕松查看數(shù)據(jù)并與之交互。請(qǐng)按照以下步驟進(jìn)行簡(jiǎn)單的 Excel 到 HTML 轉(zhuǎn)換:

          第 1 步:使用 MS Excel 打開文件

          首先,在 Windows 或 Mac 上瀏覽所需的電子表格,然后使用 MS Excel 打開它。接下來(lái),點(diǎn)擊 Excel 界面左上角的“文件”選項(xiàng)卡,從給定的選項(xiàng)中選擇“另存為”,然后雙擊“此電腦”選項(xiàng)。

          第 2 步:另存文件

          上述步驟將打開“另存為”對(duì)話框,輸入所需的“文件名”,然后從“另存為類型”下拉列表中選擇“HTML”,然后點(diǎn)擊對(duì)話框中的“保存”按鈕。

          第 2 部分:如何免費(fèi)在線將 Excel 轉(zhuǎn)換為 HTML?

          這個(gè)方法可以很好地快速且高效地在線將 Excel 導(dǎo)出為 HTML,將用到Convertio 和 Zamzar 兩個(gè)頂級(jí)的免費(fèi)工具。

          方式 1. 通過(guò) Convertio 免費(fèi)在線將 Excel 導(dǎo)出為 HTML

          Convertio 是一個(gè)超級(jí)簡(jiǎn)單的在線工具,可以幫助轉(zhuǎn)換不同類型的文件,可以輕松轉(zhuǎn)換文檔、圖像、視頻、音頻文件和電子書,而且不需要下載或安裝任何東西。讓我們看一下在線將 Excel 轉(zhuǎn)換為 HTML 的簡(jiǎn)單步驟:

          第 1 步: 在網(wǎng)絡(luò)瀏覽器中訪問(wèn) Convertio 的網(wǎng)站

          在頂部欄中查找“轉(zhuǎn)換”選項(xiàng)并單擊它,會(huì)出現(xiàn)具有擴(kuò)展功能的菜單,從列表中選擇“文檔轉(zhuǎn)換器”。

          第 2 步: 導(dǎo)入 Excel 電子表格

          有兩種選擇:使用文件資源管理器從電腦上傳或直接從 Google Drive 或 Dropbox 導(dǎo)入。導(dǎo)入 Excel 文件后,找到“收件人”選項(xiàng)旁邊的下拉菜單,單擊它并從“文檔”旁邊的可用轉(zhuǎn)換格式中選擇“HTML”。

          第 3 步: 選擇所需的輸出格式后,單擊“轉(zhuǎn)換”選項(xiàng)

          單擊后轉(zhuǎn)換過(guò)程開始,完成后將看到“下載”按鈕,只需單擊它即可將轉(zhuǎn)換后的 HTML 文件保存到電腦。

          方法 2. 通過(guò) Zamzar 在線將 Excel 轉(zhuǎn)換為 HTML

          Zamzar 是一款我強(qiáng)烈推薦的在線工具,它可以輕松地將 Excel 轉(zhuǎn)換為HTML。由于其簡(jiǎn)約易上手的界面,Zamzar 是滿足所有文件轉(zhuǎn)換需求的首選,且這個(gè)軟件無(wú)需注冊(cè)就能使用。但它也存在一些限制,允許轉(zhuǎn)換的最大文件大小為 2GB,支持最多 25 個(gè)文件批量轉(zhuǎn)換。現(xiàn)在,讓我們深入研究下面提到的將 Excel 轉(zhuǎn)換為 HTML 的簡(jiǎn)單步驟:

          第 1 步:打開計(jì)算機(jī)的網(wǎng)絡(luò)瀏覽器并導(dǎo)航至 Zamzar 的網(wǎng)站

          找到“選擇文件”按鈕并按下。然后,可以從計(jì)算機(jī)中選擇所需的 Excel 文件。但是,將文件拖放到指定區(qū)域會(huì)更加方便。

          第 2 步: Excel 文件成功上傳后,選擇輸出格式

          選擇“HTML”作為轉(zhuǎn)換格式,單擊“立即轉(zhuǎn)換”按鈕,Zamzar 將開始轉(zhuǎn)換過(guò)程。轉(zhuǎn)換完成后,將出現(xiàn)“下載”按鈕,單擊它即可開始下載轉(zhuǎn)換后的 HTML 文件。

          第三部分:總結(jié)

          這篇文章我們講了幾種工具來(lái)快速、輕松地將 Excel 轉(zhuǎn)換為 HTML,幾種工具對(duì)比下來(lái),我們強(qiáng)烈推薦 UPDF 編輯器,它能夠?qū)?Excel 轉(zhuǎn)換為 HTML,并提供強(qiáng)大的 AI 功能,讓用戶可以方便快捷地查查詢自己想要的操作步驟。

          需求場(chǎng)景

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

          相較于后端處理Excel數(shù)據(jù)而言,使用前端導(dǎo)入導(dǎo)出可以提供更高的實(shí)時(shí)性,用戶可以直接在瀏覽器中觸發(fā)導(dǎo)出操作,無(wú)需等待后端處理。且可以在前端完成數(shù)據(jù)生成以及數(shù)據(jù)校驗(yàn)處理工作,大大減輕后端服務(wù)器的壓力,大幅增強(qiáng)用戶體驗(yàn)。

          具體的技術(shù)方案選型主要看業(yè)務(wù)場(chǎng)景,如果對(duì)于小型數(shù)據(jù)集、實(shí)時(shí)性需求較高的導(dǎo)入導(dǎo)出操作,優(yōu)先考慮前端實(shí)現(xiàn)。而對(duì)于大型數(shù)據(jù)集、需要業(yè)務(wù)邏輯處理、以及安全性要求高的場(chǎng)景,則后端處理更為合適。

          技術(shù)方案

          xlsx與xlsx-style組合方案:xlsx 是目前前端最常用的Excel解決方案,又叫做SheetJS,但社區(qū)版不支持修改Excel的樣式,需要購(gòu)買Pro版才可以,如果需要修改導(dǎo)出的Excel文件樣式,需要結(jié)合xlsx-style庫(kù)一起使用。但遺憾的是xlsx庫(kù)已經(jīng)兩年多不更新,而xlsx-style上一個(gè)版本更是8年前發(fā)布,目前已經(jīng)不再推薦使用該方案。

          exceljs與file-saver方案:exceljs是一款免費(fèi)開源支持導(dǎo)入導(dǎo)出Excel 操作工具,并且可以實(shí)現(xiàn)樣式的修改以及 Excel 的高級(jí)功能,是非常值得推薦的一個(gè)處理 Excel 的庫(kù),file-saver可以實(shí)現(xiàn)保存文件到本地。本文以exceljs與file-saver操作xlsx格式文件為例介紹如何具體上手使用。

          exceljs介紹

          ExcelJS是一個(gè)用于在Node.js和瀏覽器中創(chuàng)建、讀取和修改Excel文件的強(qiáng)大JavaScript庫(kù)。它提供了豐富的功能和靈活的API,使你能夠在你的應(yīng)用程序中處理和操作Excel文件。

          下面是一些ExcelJS庫(kù)的關(guān)鍵特性和功能:

          1. 創(chuàng)建和修改Excel文件:ExcelJS允許你創(chuàng)建新的Excel工作簿,并在其中添加工作表、行和單元格。你可以設(shè)置單元格的值、樣式、數(shù)據(jù)類型以及其他屬性。
          2. 讀取和解析Excel文件:ExcelJS支持讀取和解析現(xiàn)有的Excel文件。你可以將Excel文件加載到工作簿中,然后訪問(wèn)工作表、行和單元格的數(shù)據(jù)。
          3. 導(dǎo)出和保存Excel文件:ExcelJS可以將工作簿保存為Excel文件,支持多種格式,如XLSX、XLS和CSV。你可以將工作簿保存到本地文件系統(tǒng)或?qū)⑵浒l(fā)送到客戶端以供下載。
          4. 處理復(fù)雜的Excel功能:ExcelJS支持處理復(fù)雜的Excel功能,如公式、圖表、數(shù)據(jù)驗(yàn)證、條件格式和保護(hù)工作表等。你可以根據(jù)需要設(shè)置和操作這些功能。
          5. 支持自定義樣式和格式:ExcelJS允許你自定義單元格、行、列和工作表的樣式和格式。你可以設(shè)置字體、顏色、填充、邊框、對(duì)齊方式以及數(shù)字和日期格式等。

          參考文檔

          npm倉(cāng)庫(kù)地址:https://www.npmjs.com/package/exceljs

          官方中文文檔地址:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md

          快速上手

          安裝依賴

          exceljs用于Excel數(shù)據(jù)處理,file-sever用于保存到本地文件。

          npm i exceljs
          npm i file-saver

          導(dǎo)出Excel

          讓我們先從簡(jiǎn)單的數(shù)據(jù)導(dǎo)出開始,快速體驗(yàn)如何使用exceljs導(dǎo)出Excel文件,需要注意的是在瀏覽器環(huán)境中運(yùn)行 JavaScript,瀏覽器的安全策略通常不允許直接訪問(wèn)讀寫本地文件系統(tǒng)。在這種情況下,需要通過(guò)其他方式將文件轉(zhuǎn)換為buffer數(shù)據(jù),在導(dǎo)出Excel時(shí)使用FileSaver.js庫(kù)將緩沖區(qū)數(shù)據(jù)保存到文件中。

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 175, "體重": 74},
              {"姓名": "李四", "年齡": 22, "身高": 177, "體重": 84},
              {"姓名": "王五", "年齡": 53, "身高": 155, "體重": 64}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          </script>
          
          <style scoped lang="scss">
          
          </style>

          當(dāng)我們點(diǎn)擊導(dǎo)出excel按鈕時(shí),調(diào)用exportFile函數(shù),完成excel文件下載,下載后的文件內(nèi)容如下:


          導(dǎo)入Excel

          導(dǎo)入excel文件時(shí),同樣使用FileReader的readAsArrayBuffer方法,將文件轉(zhuǎn)換為二進(jìn)制字符串,然后從buffer中加載數(shù)據(jù)并解析。

          <template>
            <input
                type="file"
                accept=".xls,.xlsx"
                class="upload-file"
                @change="importExcel($event)"/>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          // 導(dǎo)出excel文件
          const importExcel = (event) => {
            //獲取選擇的文件
            const files = event.target.files
            //創(chuàng)建Workbook實(shí)例
            const workbook = new ExcelJS.Workbook();
            // 使用FileReader對(duì)象來(lái)讀取文件內(nèi)容
            const fileReader = new FileReader()
            // 二進(jìn)制字符串的形式加載文件
            fileReader.readAsArrayBuffer(files[0])
            fileReader.onload = ev => {
              console.log(ev)
              // 從 buffer中加載數(shù)據(jù)解析
              workbook.xlsx.load(ev.target.result).then(workbook => {
                // 獲取第一個(gè)worksheet內(nèi)容
                const worksheet = workbook.getWorksheet(1);
                // 獲取第一行的標(biāo)題
                const headers = [];
                worksheet.getRow(1).eachCell((cell) => {
                  headers.push(cell.value);
                });
                console.log("headers", headers)
                // 創(chuàng)建一個(gè)空的JavaScript對(duì)象數(shù)組,用于存儲(chǔ)解析后的數(shù)據(jù)
                const data = [];
                // 遍歷工作表的每一行(從第二行開始,因?yàn)榈谝恍型ǔJ菢?biāo)題行)
                for (let rowNumber = 2; rowNumber <= worksheet.rowCount; rowNumber++) {
                  const rowData = {};
                  const row = worksheet.getRow(rowNumber);
                  // 遍歷當(dāng)前行的每個(gè)單元格
                  row.eachCell((cell, colNumber) => {
                    // 獲取標(biāo)題對(duì)應(yīng)的鍵,并將當(dāng)前單元格的值存儲(chǔ)到相應(yīng)的屬性名中
                    rowData[headers[colNumber - 1]] = cell.value;
                  });
                  // 將當(dāng)前行的數(shù)據(jù)對(duì)象添加到數(shù)組中
                  data.push(rowData);
                }
                console.log("data", data)
              })
            }
          }
          </script>
          
          <style scoped lang="scss">
          
          </style>

          上傳文件后,解析內(nèi)容如下所示:

          進(jìn)階操作

          添加數(shù)據(jù)

          我們可以通過(guò)columns方法添加列標(biāo)題并定義列鍵和寬度,設(shè)置好表頭后,我們可以直接通過(guò)addRow方法,根據(jù)key值去添加每一行的數(shù)據(jù)。

          參考文檔:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E5%88%97

          完整代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 添加表頭列數(shù)據(jù)
            sheet1.columns = [
              {header: "姓名", key: "name", width: 20},
              {header: "年齡", key: "age", width: 10},
              {header: "身高", key: "height", width: 10},
              {header: "體重", key: "weight", width: 10},
            ];
            // 添加內(nèi)容列數(shù)據(jù)
            sheet1.addRow({sort: 1, name: "張三", age: 18, height: 175, weight: 74});
            sheet1.addRow({sort: 2, name: "李四", age: 22, height: 177, weight: 88});
            sheet1.addRow({sort: 3, name: "王五", age: 53, height: 155, weight: 62});
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          添加數(shù)據(jù)后導(dǎo)出文件效果如下:

          讀取數(shù)據(jù)

          我們可以使用getRow方法,傳入指定行參數(shù)讀取行數(shù)據(jù)。

          使用getColumn方法,傳入鍵、字母、id參數(shù)讀取列數(shù)據(jù)。

          使用eachCell方法可以遍歷每個(gè)單元格內(nèi)容。

          參考文檔:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E8%A1%8C

          代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 添加表頭列數(shù)據(jù)
            sheet1.columns = [
              {header: "姓名", key: "name", width: 20},
              {header: "年齡", key: "age", width: 10},
              {header: "身高", key: "height", width: 10},
              {header: "體重", key: "weight", width: 10},
            ];
            // 添加內(nèi)容列數(shù)據(jù)
            sheet1.addRow({sort: 1, name: "張三", age: 18, height: 175, weight: 74});
            sheet1.addRow({sort: 2, name: "李四", age: 22, height: 177, weight: 88});
            sheet1.addRow({sort: 3, name: "王五", age: 53, height: 155, weight: 62});
            // 讀取行數(shù)據(jù)
            sheet1.getRow(1).eachCell((cell, rowIdx) => {
              console.log("行數(shù)據(jù)", cell.value, rowIdx);
            });
            // 讀取列數(shù)據(jù),可以通過(guò)鍵(name),字母(B)和基于id(1)的列號(hào)訪問(wèn)單個(gè)列
            sheet1.getColumn("name").eachCell((cell, rowIdx) => {
              console.log("列數(shù)據(jù)", cell.value, rowIdx);
            });
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          效果

          樣式

          在導(dǎo)出excel文件時(shí),默認(rèn)沒(méi)有任何樣式的,為了美觀我們需要添加樣式,而exceljs支持修改表格樣式,具體內(nèi)容可參考文檔https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E6%A0%B7%E5%BC%8F

          例如,我們需要設(shè)置所有單元格居中對(duì)齊,并添加邊框。并分別指定標(biāo)題行和內(nèi)容行字體大小、背景顏色、行高屬性,代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 175, "體重": 74},
              {"姓名": "李四", "年齡": 22, "身高": 177, "體重": 84},
              {"姓名": "王五", "年齡": 53, "身高": 155, "體重": 64}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 修改所有單元格樣式
            // 遍歷每一行
            sheet1.eachRow((row, rowNumber) => {
              // 遍歷每個(gè)單元格
              row.eachCell((cell) => {
                // 設(shè)置邊框樣式
                cell.border = {
                  top: {style: 'thin'},
                  left: {style: 'thin'},
                  bottom: {style: 'thin'},
                  right: {style: 'thin'}
                };
                // 設(shè)置居中對(duì)齊
                cell.alignment = {
                  vertical: 'middle',
                  horizontal: 'center'
                };
              });
            });
            // 獲取標(biāo)題行數(shù)據(jù)
            const titleCell = sheet1.getRow(1);
            // 設(shè)置行高為30
            titleCell.height = 30
            // 設(shè)置標(biāo)題行單元格樣式
            titleCell.eachCell((cell) => {
              // 設(shè)置標(biāo)題行背景顏色為黃色
              cell.fill = {
                type: 'pattern',
                pattern: 'solid',
                fgColor: {argb: 'FFFF00'}
              };
              // 設(shè)置標(biāo)題行字體
              cell.font = {
                color: {argb: 'FF0000'}, //顏色為紅色
                bold: true,// 字體粗體
                size: 18 // 設(shè)置字體大小為18
              };
            })
            // 獲取第二行到最后一行的內(nèi)容數(shù)據(jù)
            const bodyRows = sheet1.getRows(2, sheet1.rowCount);
            // 處理內(nèi)容行的數(shù)據(jù)
            bodyRows.forEach((bodyRow) => {
              // 設(shè)置行高為20
              bodyRow.height = 20
              bodyRow.eachCell((cell) => {
                cell.font = {
                  size: 16 // 設(shè)置內(nèi)容行字體大小為16
                };
              });
            });
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          導(dǎo)出Excel樣式效果如下所示,已經(jīng)成功按我們指定的樣式導(dǎo)出了文件:

          篩選

          在很多的時(shí)候我們需要對(duì)表格中每一列的數(shù)據(jù)進(jìn)行篩選,比如直接篩選姓名等列信息,我們可以通過(guò) autoFilter 來(lái)添加篩選。參考文檔:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E8%87%AA%E5%8A%A8%E7%AD%9B%E9%80%89%E5%99%A8

          代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 175, "體重": 74},
              {"姓名": "李四", "年齡": 22, "身高": 177, "體重": 84},
              {"姓名": "王五", "年齡": 53, "身高": 155, "體重": 64}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 單列篩選
            // sheet1.autoFilter = "A1";
            // 多個(gè)列篩選
            sheet1.autoFilter = "A1:C1";
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          導(dǎo)入后的效果如下,在姓名、年齡、身高列添加了篩選按鈕:

          公式值

          參考文檔:exceljs/README_zh.md at 5bed18b45e824f409b08456b59b87430ded023ab · exceljs/exceljs · GitHub

          我們可以直接對(duì)表格中的數(shù)據(jù)進(jìn)行公式計(jì)算,比如 求和(SUM)平均數(shù)(AVERAGE) 等。

          例如我們需要計(jì)算平均值、最大值、指定公式時(shí),代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 1.75, "體重": 74},
              {"姓名": "李四", "年齡": 22, "身高": 1.77, "體重": 84},
              {"姓名": "王五", "年齡": 53, "身高": 1.55, "體重": 64}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 添加單元格
            sheet1.getCell("E1").value = "BMI指數(shù)";
            sheet1.getCell("F1").value = "平均身高";
            sheet1.getCell("G1").value = "最大體重";
            // 計(jì)算平均身高
            sheet1.getCell("F2").value = {formula: "=AVERAGE(C2:C4)"};
            // 計(jì)算最大體重
            sheet1.getCell("G2").value = {formula: "=MAX(D2:D4)"};
            // 計(jì)算BMI指數(shù)
            // 獲取第5列對(duì)象
            const BMIRange = sheet1.getColumn(5)
            BMIRange.eachCell((cell) => {
              console.log("cell", cell)
              console.log(cell.row)
              // 從第二列開始添加計(jì)算公式
              if (cell.row >= 2) {
                sheet1.getCell("E" + cell.row).value = {formula: "D" + cell.row + "/" + "(C" + cell.row + "*" + "C" + cell.row + ")"};
              }
            })
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          導(dǎo)出Excel文件效果如下,E列已經(jīng)自動(dòng)替換為公式計(jì)算。

          合并單元格

          表格的合并應(yīng)該是業(yè)務(wù)需求中最頻繁的功能。當(dāng)然這一功能使用 xlsx 也可以實(shí)現(xiàn),我們只需要使用mergeCells方法,傳入合并單元格范圍參數(shù)即可。

          參考文檔:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC

          具體代碼實(shí)現(xiàn)如下所示:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 175, "體重": 74},
              {"姓名": "李四", "年齡": 18, "身高": '未知', "體重": '未知'},
              {"姓名": "王五", "年齡": 53, "身高": '未知', "體重": '未知'},
              {"姓名": "趙六", "年齡": 12, "身高": '未知', "體重": '未知'}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 上下合并單元格
            sheet1.mergeCells("B2:B3");
            // 左右合并單元格
            sheet1.mergeCells("C3:D3");
            // 范圍合并單元格
            sheet1.mergeCells("C4:D5");
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>
          

          單元格合并后導(dǎo)出文件效果如下:

          數(shù)據(jù)驗(yàn)證

          有時(shí)候我們需要為某個(gè)單元格添加數(shù)據(jù)可以方便直接下拉選擇指定的值,此時(shí)就需要使用數(shù)據(jù)驗(yàn)證功能,傳入可填寫的選項(xiàng)列表。

          參考文檔:https://github.com/exceljs/exceljs/blob/HEAD/README_zh.md#%E6%95%B0%E6%8D%AE%E9%AA%8C%E8%AF%81

          例如我們對(duì)是否注冊(cè)列添加數(shù)據(jù)驗(yàn)證,可填值為"是、否、未知",具體代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 1.75, "體重": 74, "是否注冊(cè)": ''},
              {"姓名": "李四", "年齡": 22, "身高": 1.77, "體重": 84, "是否注冊(cè)": ''},
              {"姓名": "王五", "年齡": 53, "身高": 1.55, "體重": 64, "是否注冊(cè)": ''}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 獲取第5列對(duì)象
            const VerificationRange = sheet1.getColumn(5)
            VerificationRange.eachCell((cell) => {
              // 從第二列開始添加數(shù)據(jù)驗(yàn)證規(guī)則
              if (cell.row >= 2) {
                sheet1.getCell("E" + cell.row).dataValidation = {
                  type: "list",
                  allowBlank: true,
                  formulae: ['"是,否,未知"']
                };
              }
            })
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>
          

          導(dǎo)出的excel文件效果如下:

          條件格式化

          我們可以為指定單元格添加條件格式,對(duì)滿足條件的單元格設(shè)置指定的樣式。

          參考文檔:exceljs/README_zh.md at 5bed18b45e824f409b08456b59b87430ded023ab · exceljs/exceljs · GitHub

          例如為年齡大于18歲單元格進(jìn)行紅色標(biāo)注,代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
          </template>
          
          <script setup>
          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          // 導(dǎo)出excel文件
          const exportExcel = () => {
            // 創(chuàng)建工作簿
            const workbook = new ExcelJS.Workbook();
            // 添加工作表,名為sheet1
            const sheet1 = workbook.addWorksheet("sheet1");
            // 導(dǎo)出數(shù)據(jù)列表
            const data = [
              {"姓名": "張三", "年齡": 18, "身高": 1.75, "體重": 74},
              {"姓名": "李四", "年齡": 22, "身高": 1.77, "體重": 84},
              {"姓名": "王五", "年齡": 53, "身高": 1.55, "體重": 64}
            ]
            // 獲取表頭所有鍵
            const headers = Object.keys(data[0])
            // 將標(biāo)題寫入第一行
            sheet1.addRow(headers);
            // 將數(shù)據(jù)寫入工作表
            data.forEach((row) => {
              const values = Object.values(row)
              sheet1.addRow(values);
            });
            // 年齡大于18歲紅色標(biāo)注
            sheet1.addConditionalFormatting({
              ref: "B2:B4",
              rules: [
                {
                  type: "cellIs",
                  operator: "greaterThan",
                  priority: 1,
                  formulae: [18],
                  style: {
                    fill: {
                      type: "pattern",
                      pattern: "solid",
                      bgColor: { argb: "FFFFC0CB" },
                    },
                  },
                },
              ],
            });
            // 導(dǎo)出表格文件
            workbook.xlsx.writeBuffer().then((buffer) => {
              let file = new Blob([buffer], {type: "application/octet-stream"});
              FileSaver.saveAs(file, "ExcelJS.xlsx");
            }).catch(error => console.log('Error writing excel export', error))
          }
          
          </script>
          
          <style scoped lang="scss">
          
          </style>

          導(dǎo)出后的文件效果如下:

          封裝exceljs

          封裝導(dǎo)入導(dǎo)出函數(shù)

          為了提高項(xiàng)目代碼的復(fù)用性,通常會(huì)將excel導(dǎo)入導(dǎo)出功能封裝到單獨(dú)的函數(shù)中方便調(diào)用,封裝后的函數(shù)如下:

          import ExcelJS from "exceljs";
          import FileSaver from "file-saver";
          import {timeFile} from "@/utils/timeFormat";
          // 導(dǎo)出excel文件
          export function exportFile(export_data, filename) {
              // 創(chuàng)建工作簿
              const workbook = new ExcelJS.Workbook();
              // 添加工作表,名為sheet1
              const sheet1 = workbook.addWorksheet("sheet1");
              // 獲取表頭所有鍵
              const headers = Object.keys(export_data[0])
              // 將標(biāo)題寫入第一行
              sheet1.addRow(headers);
              // 將數(shù)據(jù)寫入工作表
              export_data.forEach((row) => {
                  const values = Object.values(row)
                  sheet1.addRow(values);
              });
              // 設(shè)置默認(rèn)寬高屬性
              sheet1.properties.defaultColWidth = 20
              sheet1.properties.defaultRowHeight = 20
              // 修改所有單元格樣式
              // 遍歷每一行
              sheet1.eachRow((row, rowNumber) => {
                  // 遍歷每個(gè)單元格
                  row.eachCell((cell) => {
                      // 設(shè)置邊框樣式
                      cell.border = {
                          top: {style: 'thin'},
                          left: {style: 'thin'},
                          bottom: {style: 'thin'},
                          right: {style: 'thin'}
                      };
                      // 設(shè)置居中對(duì)齊
                      cell.alignment = {
                          vertical: 'middle',
                          horizontal: 'center'
                      };
                  });
              });
              // 獲取標(biāo)題行數(shù)據(jù)
              const titleCell = sheet1.getRow(1);
              // 設(shè)置標(biāo)題行單元格樣式
              titleCell.eachCell((cell) => {
                  // 設(shè)置標(biāo)題行背景顏色
                  cell.fill = {
                      type: 'pattern',
                      pattern: 'solid',
                      fgColor: {argb: '3498db'}
                  };
                  // 設(shè)置標(biāo)題行字體
                  cell.font = {
                      bold: true,// 字體粗體
                  };
              })
              // 導(dǎo)出表格文件
              workbook.xlsx.writeBuffer().then((buffer) => {
                  let file = new Blob([buffer], {type: "application/octet-stream"});
                  FileSaver.saveAs(file, filename + timeFile() + ".xlsx");
              }).catch(error => console.log('Error writing excel export', error))
          }
          
          // 導(dǎo)入excel文件
          export function importFile(content) {
              return new Promise((resolve, reject) => {
                  // 創(chuàng)建一個(gè)空的JavaScript對(duì)象數(shù)組,用于存儲(chǔ)解析后的數(shù)據(jù)
                  const data = [];
                  //創(chuàng)建Workbook實(shí)例
                  const workbook = new ExcelJS.Workbook();
                  workbook.xlsx.load(content).then(workbook => {
                      // 獲取第一個(gè)worksheet內(nèi)容
                      const worksheet = workbook.getWorksheet(1);
                      // 獲取第一行的標(biāo)題
                      const headers = [];
                      worksheet.getRow(1).eachCell((cell) => {
                          headers.push(cell.value);
                      });
                      // console.log("headers", headers)
                      // 遍歷工作表的每一行(從第二行開始,因?yàn)榈谝恍型ǔJ菢?biāo)題行)
                      for (let rowNumber = 2; rowNumber <= worksheet.rowCount; rowNumber++) {
                          const rowData = {};
                          const row = worksheet.getRow(rowNumber);
                          // 遍歷當(dāng)前行的每個(gè)單元格
                          row.eachCell((cell, colNumber) => {
                              // 獲取標(biāo)題對(duì)應(yīng)的鍵,并將當(dāng)前單元格的值存儲(chǔ)到相應(yīng)的屬性名中
                              rowData[headers[colNumber - 1]] = cell.value;
                          });
                          // 將當(dāng)前行的數(shù)據(jù)對(duì)象添加到數(shù)組中
                          data.push(rowData);
                      }
                      // console.log("data", data)
                      resolve(data);
                  }).catch(error => {
                      reject(error);
                  });
              })
          }

          vue組件調(diào)用

          以element plus為例,調(diào)用函數(shù)完成Excel文件導(dǎo)入與導(dǎo)出,代碼如下:

          <template>
            <el-button type="primary" @click="exportExcel">導(dǎo)出excel</el-button>
            <el-button type="success" @click="importExcel">導(dǎo)入excel</el-button>
            <p>導(dǎo)入數(shù)據(jù)預(yù)覽</p>
            {{ uploadData}}
            <el-dialog
                v-model="uploadDialogVisible"
                title="批量添加數(shù)據(jù)"
                width="40%"
            >
              <el-form label-width="120px">
                <el-form-item label="模板下載:">
                  <el-button type="info" @click="downloadTemplate">
                    <el-icon>
                      <Download/>
                    </el-icon>
                    點(diǎn)擊下載
                  </el-button>
                </el-form-item>
                <el-form-item label="文件上傳:">
                  <el-upload drag accept=".xls,.xlsx" :auto-upload="false" :on-change="handleChange">
                    <el-icon class="el-icon--upload">
                      <upload-filled/>
                    </el-icon>
                    <div class="el-upload__text">
                      將文件拖到此處,或<em>點(diǎn)擊上傳</em>
                    </div>
                    <template #tip>
                      <div class="el-upload__tip">
                        請(qǐng)上傳.xls,.xlsx格式文件,文件最大為500kb
                      </div>
                    </template>
                  </el-upload>
                </el-form-item>
              </el-form>
              <template #footer>
                <span class="dialog-footer">
                  <el-button @click="uploadDialogVisible = false">取消</el-button>
                  <el-button type="primary" @click="submitUpload">
                    導(dǎo)入
                  </el-button>
                </span>
              </template>
            </el-dialog>
          </template>
          
          <script setup>
          import {ref} from "vue";
          import {ElMessage} from "element-plus";
          import {Download, UploadFilled} from "@element-plus/icons-vue"
          import {getDemo} from "@/api/home";
          import {timeFormatConversion} from "@/utils/timeFormat";
          import {exportFile, importFile} from "@/utils/excel";
          // 表格字段配置
          const fieldConfig = ref([
            {
              'label': 'ID', // 標(biāo)簽
              'model': 'id',// 字段名
              'is_export': true,// 是否導(dǎo)出該字段
            },
            {
              'label': '用戶名', // 標(biāo)簽
              'model': 'username',// 字段名
              'is_export': true, // 是否導(dǎo)出該字段
            },
            {
              'label': '省份', // 標(biāo)簽
              'model': 'province',// 字段名
              'is_export': true // 是否導(dǎo)出該字段
            },
            {
              'label': '性別', // 標(biāo)簽
              'model': 'sex_name',// 字段名
              'is_export': true // 是否導(dǎo)出該字段
            },
            {
              'label': '生日', // 標(biāo)簽
              'model': 'birthday',// 字段名
              'is_export': true, // 是否導(dǎo)出該字段
            },
            {
              'label': '身高(cm)', // 標(biāo)簽
              'model': 'height',// 字段名
              'is_export': true, // 是否導(dǎo)出該字段
            },
            {
              'label': '體重(kg)', // 標(biāo)簽
              'model': 'weight',// 字段名
              'is_export': true,// 是否導(dǎo)出該字段
            },
            {
              'label': '注冊(cè)時(shí)間', // 標(biāo)簽
              'model': 'created_time',// 字段名
              'is_export': true, // 是否導(dǎo)出該字段
            },
            {
              'label': '個(gè)人介紹', // 標(biāo)簽
              'model': 'introduction',// 字段名
              'is_export': true,// 是否導(dǎo)出該字段
            }
          ])
          // 導(dǎo)出Excel事件
          const exportExcel = () => {
            ElMessage({
              message: '開始導(dǎo)出數(shù)據(jù),請(qǐng)稍候!',
              type: 'success',
            })
            // 導(dǎo)出數(shù)據(jù)查詢參數(shù)
            const printParams = {
              'size': 1000,
              'page': 1,
            }
            // 獲取需要導(dǎo)出的字段配置
            const export_fields = fieldConfig.value
                .filter(obj => obj['is_export'])
                .map(({label, model}) => ({[model]: label}))
            // 處理數(shù)據(jù)結(jié)構(gòu)
            getDemo(printParams).then((response) => {
              // console.log(response.results)
              const export_data = response.results.map(obj => {
                const newObj = {};
                export_fields.forEach(field => {
                  const [key, value] = Object.entries(field)[0];
                  if (key === 'created_time') {
                    newObj[value] = timeFormatConversion((obj[key]), 'YYYY-MM-DD HH:mm:ss');
                  } else {
                    newObj[value] = obj[key];
                  }
                });
                return newObj;
              });
              let filename = '示例用戶'
              exportFile(export_data, filename);
            }).catch(response => {
              //發(fā)生錯(cuò)誤時(shí)執(zhí)行的代碼
              console.log(response)
              ElMessage.error('獲取列表數(shù)據(jù)失敗!')
            });
          }
          // 導(dǎo)入excel彈窗是否顯示
          const uploadDialogVisible = ref(false)
          // 點(diǎn)擊導(dǎo)入excel按鈕事件
          const importExcel = () => {
            uploadDialogVisible.value = true
          }
          // 下載模板文件
          const downloadTemplate = () => {
            window.open('https://api.cuiliangblog.cn/static/demo-template.xlsx')
          }
          // 文件數(shù)據(jù)
          const uploadData=ref([])
          // 文件上傳事件
          const handleChange = (file) => {
            const reader = new FileReader();
            reader.onload = () => {
              const content = reader.result;
              importFile(content).then((data) => {
                console.log(data)
                uploadData.value = data
              }).catch(response => {
                //發(fā)生錯(cuò)誤時(shí)執(zhí)行的代碼
                console.log(response)
                ElMessage.error('獲取列表數(shù)據(jù)失敗!')
              });
            };
            reader.readAsBinaryString(file.raw);
          };
          // 點(diǎn)擊導(dǎo)入excel提交數(shù)據(jù)事件
          const submitUpload = () => {
            uploadDialogVisible.value =false
          }
          </script>
          
          <style scoped lang="scss">
          
          </style>

          頁(yè)面效果

          封裝后的頁(yè)面效果如下,至此,一個(gè)簡(jiǎn)單的vue前端實(shí)現(xiàn)Excel文件導(dǎo)入導(dǎo)出功能便開發(fā)完成了。

          完整代碼

          gitee:https://gitee.com/cuiliang0302/vue3_vite_element-plus

          github:https://github.com/cuiliang0302/vue3-vite-template

          查看更多

          微信公眾號(hào)

          微信公眾號(hào)同步更新,歡迎關(guān)注微信公眾號(hào)《崔亮的博客》第一時(shí)間獲取最近文章。

          博客網(wǎng)站

          崔亮的博客-專注devops自動(dòng)化運(yùn)維,傳播優(yōu)秀it運(yùn)維技術(shù)文章。更多原創(chuàng)運(yùn)維開發(fā)相關(guān)文章,歡迎訪問(wèn)https://www.cuiliangblog.cn


          主站蜘蛛池模板: 香蕉久久ac一区二区三区| 任你躁国产自任一区二区三区| 夜夜爽一区二区三区精品| 亚洲日韩精品一区二区三区 | 日本一区精品久久久久影院| 呦系列视频一区二区三区| 国产精品亚洲综合一区| 人妻精品无码一区二区三区| 国产一区二区三区91| 人妻无码一区二区视频| 中文字幕精品一区二区| 亚洲AV日韩AV天堂一区二区三区| 精品理论片一区二区三区| 精品亚洲AV无码一区二区三区 | 日韩视频一区二区| 激情内射亚洲一区二区三区 | 狠狠爱无码一区二区三区| 亚洲综合av一区二区三区不卡| 果冻传媒董小宛一区二区| 日韩视频在线观看一区二区| 亚洲AV无码一区二区乱子仑| 亚洲一区二区三区四区在线观看| 大屁股熟女一区二区三区| 国产一区二区三区在线观看影院| 在线精品动漫一区二区无广告| 国产av夜夜欢一区二区三区| 国产一区二区好的精华液| 国产精品高清一区二区人妖| 无码精品国产一区二区三区免费| 制服丝袜一区二区三区| 亚洲视频在线一区二区| 日本一区二区高清不卡| 日本强伦姧人妻一区二区| 国产丝袜无码一区二区视频| 国产在线第一区二区三区| 福利一区二区在线| 人成精品视频三区二区一区| 亚洲国产成人久久综合一区77| 美女视频免费看一区二区| 国产一区二区三区国产精品| 一区二区三区视频在线播放|