[Electron]仿写一个课堂随机点名小项目

3,218 阅读4分钟

自从前几个月下了抖音,无聊闲暇时就打会打开抖音,因为打开它有种莫名其妙打开了全世界的感觉...

无意中看到这个小视频:随机点名

于是仿写了一个课堂点名小项目,算是对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,感谢你的支持。