[Electron]仿寫一個課堂隨機點名小專案

hzr發表於2018-04-26

自從前幾個月下了抖音,無聊閒暇時就打會開啟抖音,因為開啟它有種莫名其妙開啟了全世界的感覺...

無意中看到這個小視訊:隨機點名

於是仿寫了一個課堂點名小專案,算是對Electron的一個簡單的認識,有時間再深入。

專案地址

github.com/alex1504/el…

專案截圖

preview
preview
preview
preview

Electron介紹

引用官網的一句話: Build cross platform desktop apps with JavaScript, HTML, and CSS(通過HTML+CSS+JS技術做跨平臺的桌面應用)

需求分析:

  1. 無網路環境使用:大學大部分科室可能無網路,本專案所有資源使用本地資源,資料檔案存放在本地。
  2. Excel錄入:一般每個班級都有一份名單,excel匯入節省時間。
  3. 多班級列表管理:一個老師可能同時排多個班級學生的課程。
  4. 資料統計:統計學生回答情況,方便期末考評。

功能點介紹

  • [x] Excel匯入學生名冊
  • [x] 手動錄入名冊
  • [x] 名冊列表管理
  • [ ] 資料統計

開發前瞭解

  • 為快速開發,使用UI庫photonkit
  • 使用vue作為lib進行前端邏輯的編寫
  • Excel資料錄入基於xlsx
  • 時間生成使用moment

初始化

本專案基於官方electron-quick-start 腳手架,建立並初始化專案。

# Clone this repository
git clone https://github.com/electron/electron-quick-start
# Go into the repository
cd electron-quick-start
# Install dependencies
npm install
# Run the app
npm start
複製程式碼

專案核心結構

為使程式碼可讀性更強,重新使用es6語法對腳手架進行結構修改

.
|-- src                              // 原始碼目錄
|   |-- assets					     // 資原始檔
|   |-- config					     // 專案配置
|   |-- data					     // 名冊json資料
|   |-- vendors						 // 第三方指令碼
|   |-- window					     // 視窗目錄
|       |-- controllers  			 // 視窗生成
|       |-- views   				 // 頁面
|   |-- main.js                      // 程式入口檔案
|-- .gitignore                       // Git提交忽略檔案規則
|-- LICENSE                          // 授權協議
|-- README.md                        // 專案說明
|-- package.json                     // 配置專案相關資訊
.
複製程式碼

主程式:

const electron = require('electron');
const app = electron.app;
const IndexWindow = require('./windows/controllers/index');

class RollTool {
    constructor() {
        this.indexWindow = null;
    }

    init() {
        this.initApp()
    }

    initApp() {
        app.on('ready', () => {
            this.indexWindow = new IndexWindow();
        });
        app.on('activate', () => { 
            if (this.indexWindow === null) {
                this.indexWindow = new IndexWindow();
            }
        });
        app.on('window-all-closed', function () {
            if (process.platform !== 'darwin') {
                app.quit()
            }
        })
    }
}
new RollTool().init();
複製程式碼

介面的切換隱藏

通過一個step欄位,將主導航介面定義為狀態'1',將點名介面定義為狀態'2',其他的功能介面定義為大寫字母。

<div id="app">
    <div class="window">
        <div class="window-content">
            <div class="pane-group">
                <!-- START Maincontent -->
                <div class="pane">
                    <!-- 初始導航 -->
                    <section class="guide-box" v-if="step==='1'">
                    </section>
                    <!-- 名冊列表 -->
                    <section class="select-box" v-if="step==='A'">
                    </section>
                    <!-- excel錄入 命名名冊 -->
                    <section class="guide-box" v-if="step==='B'">
                    </section>
                    <!-- 修改頭像 -->
                    <section class="guide-box" v-if="step==='E'">
                    </section>
                    <!--手動錄入 -->
                    <section class="manual-box" v-if="step==='C'">
                    </section>
                    <!-- 手動錄入 命名名冊 -->
                    <section class="guide-box" v-if="step==='C1'">
                    </section>
                    <!-- 隨機抽取 -->
                    <section class="roll-box" v-if="step==='2'">
                    </section>
                </div>
                <!--END Maincontent-->
                <!-- START Sidebar-->
                <div class="pane-sm sidebar">
                </div>
                <!-- END Sidebar -->
            </div>
        </div>
    </div>
</div>
複製程式碼

js-xlxs使用

基於該庫,可以將excel資料轉化為json資料,然後自己再進行格式化。

一些概念:

  • workbook 物件,指的是整份 Excel 文件。我們在使用 js-xlsx 讀取 Excel 文件之後就會獲得 workbook 物件。
  • worksheet 物件,指的是 Excel 文件中的表。我們知道一份 Excel 文件中可以包含很多張表,而每張表對應的就是 worksheet 物件。
  • cell 物件,指的就是 worksheet 中的單元格,一個單元格就是一個 cell 物件。

關係:

// workbook
{
    SheetNames: ['sheet1', 'sheet2'],
    Sheets: {
        // worksheet
        'sheet1': {
            // cell
            'A1': { ... },
            // cell
            'A2': { ... },
            ...
        },
        // worksheet
        'sheet2': {
            // cell
            'A1': { ... },
            // cell
            'A2': { ... },
            ...
        }
    }
}
複製程式碼

基本用法

  • 用 XLSX.readFile 開啟 Excel 檔案,返回 workbook
  • 用 workbook.SheetNames 獲取表名
  • 用 workbook.Sheets[xxx] 通過表名獲取表格
  • 按自己的需求去處理表格
  • 生成新的 Excel 檔案

本專案中,通過input獲得file物件,然後通過xlsxjs讀取workbook物件,其中worksheet的!margins和!ref屬於我們不關心的屬性,排除。然後通過迴圈獲取從第二行開始的資料,設定預設頭像,拼接成我們的json資料,再下一步通過Node檔案系統API寫入data資料夾下。

readXlsxFile(file) {
    const filePath = file.path;
    const workbook = XLSX.readFile(filePath);
    const sheetNames = workbook.SheetNames;
    const worksheet = workbook.Sheets[sheetNames[0]];
    const fileDir = Date.now().toString();
    const time = moment().format('LLL');
    let jsonData = {};
    let details = [];
    let length = (Object.keys(worksheet).length - 2) / 2;
    try{
        for (let i = 2; i <= length; i++) {
            const name = worksheet[`A${i}`].h;
            const id = worksheet[`B${i}`].h;
            let student = {
                name,
                id,
                isExcluded: false,
                avatar: `../../../assets/imgs/default_avatar.jpg`
            };
            details.push(student)
        }
        jsonData.fileDir = fileDir;
        jsonData.createdAt = time;
        jsonData.updatedAt = time;
        jsonData.details = details;

        this.jsonData = jsonData;
    }catch (e) {
        console.log(e)
        alert('匯入失敗,請檢測excel格式是否正確')
    }
}
複製程式碼

喜歡本專案可以star或fork,感謝你的支援。

相關文章