应用Electron 架构技术操作Excel 文件
2019-12-28邓杰海
邓杰海
(江西中医药高等专科学校教育技术中心,抚州344000)
0 引言
在计算机课程的实践教学中,上机实践操作课占的比重较大。在上机过程中,教师有时需要在机房的教师电脑端给学生演示软件的操作,需要将教师端的电脑屏幕实现发送给学生电脑端;或者在学生上机过程中,也需要实时监控学生的桌面,关注学生在上机过程中的一举一动,防备学生上机课开小差,操作一些与上课无关的软件应用,如打游戏、看电影或看小说。为了实现以上两个目的,使用一套计算机机房教学辅助软件还是很有必要的。在日常教学中教学辅助软件也应用了几个,或多或少都存在一些问题,不能完全满足要求,因此需要自主开发一套机房辅助软件。
开发机房辅助软件的功能模块中,有一个模块实现的功能是将上课班级学生的名单导入,并在Electron渲染进程中将班级名单显示出来,在软件界面中要响应鼠标事件,将鼠标停留的学生信息能突出的显示来,从而可以快速地定位到需要关注的学生的电脑上。本文的范围为将Electron 怎么导入Excel 表格,JavaScript编程语言怎么实现这些功能并操作DOM。以下就各部分的功能及实现的源代码进行说明。
1 导入Excel文件的实现
在编写本部分的软件实现过程中,导入文件使用到的是input type=file 元素来实现本地文件的导入。通过input type=file 元素,可以得到本地文件的file 对象。如果直接使用input type=file 元素,由Chromium开源引擎渲染之后界面不大美观。为了解决这个问题,需要引用CSS 技术,对input type=file 元素进行处理。文章的篇幅有限,此处就不将Html 语言和CSS 文本样式计算机语言写上。
如图1 所示,在没有经过CSS 语言处理,input type=file 的外观确实不美观。在经过CSS 语言处理和HTML 语言定义之后,就可以得到如图2 所示的外观界面。
图1 未经处理的界面
图2 经过处理的选择班级的界面
2 使用JS-XLSX工具库将Excel文件导入渲染进程的界面中
将要导入的Excel 表头如图3 所示。
图3 导入的Excel文件表头结构
利用JS-XLSX 工具库将Excel 文件导入渲染进程的程序清单如下:
var XLSX=require('xlsx');
var Electron=require('Electron').remote;
var stuinfo=require('./stuinfo');
var userinterface=require('./userInterface');
var process_wb=(function(){
return function process_wb(wb){
wb.SheetNames.forEach(function(sheetName){
var worksheet=wb.Sheets[sheetName];//获得工作表对象
var colNumArr=['A','B','C','D','E','F','G','H','I','J','K','L','M','N'];
//用于Excel 表格每行的编号
var i=2;
var j=0;
//var cell_address='A2';
var rowVal=[];
//获得单元格地址
var cell_address=colNumArr[0]+i;
//获得单元格地址相对应的单元格对象
var cell_obj=worksheet[cell_address];
//获得对应单元格地址的源数据,如果不是undefined 则表示单元格有数据,进入循环进行处理
var cell_val=(cell_obj?cell_obj.v:undefined);
//如果单元格的源数据不为undefined,则进入循环进行处理
while(cell_val){
if(cell_val){
//用于存放获得的单元格数据的数组的下标
j=0;
//对Excel 表格A~N 列的数据进行处理
colNumArr.forEach(function(colNum){
//取到第i 行每一列的单元格地址
cell_address=colNum+i;
//获得对应单元格地址的单元格对象
cell_obj=worksheet[cell_address];
//获得相应单元格的源数据
rowVal[j++]=cell_obj.v;
});
//console.log(rowVal);
//获得的一行的单元格数据push 入存放学生信息的stuinfo 数组,并同时在渲染进程显示
stuinfo.appendStu(rowVal);
//调用渲染进程函数,将学生的姓名与学号信息在渲染进程的界面中显示出来
userInterface.initSrc(rowVal[0],rowVal[1]);
//将存放每行单元格数据的临时数组清空,准备存放下一个学生信息
rowVal.length=0;
}
//调到Excel 表格的下一行
i++;
cell_address=colNumArr[0]+i;
cell_obj=worksheet[cell_address];
cell_val=(cell_obj?cell_obj.v:undefined);
}
});
};
})();
var do_file=(function(){
return function do_file(files){
var f=files[0];
var reader=new FileReader();
reader.onload=function(e){
var data=e.target.result;
//获得Excel 表格的无符号单字节的数组
data=new Uint8Array(data);
//调用JS-XLSX 工具库函数process_wb 对数组进行处理
process_wb(XLSX.read(data,{type:'array'}));
};
reader.readAsArrayBuffer(f);
};
})();
(function(){
var xlf=document.getElementById('selectFile');
function handleFile(e){
if(e.target.files.length===0){
return;
}
let filePath=$(this).val();
let urlArr=filePath.split("\");
let fileName=urlArr[urlArr.length-1];
$(".fileName").val(fileName);
userinterface.clearScrn();
do_file(e.target.files);
}
//调用input type=file 元素的change 事件获得打开的Excel文件的File 对象
xlf.addEventListener('change',handleFile,false);})();
以上程序清单中的函数来自GitHub 地址:https://github.com/SheetJS/js-xlsx,对相关的函数作了一些修改,在相关的Demo 程序中,没有将Excel 的每个单元格进行处理,而是使用XLSX.utils.sheet_to_html 函数将Excel 表格中的数据直接显示在div 元素中。如此处理显然不能满足要求,根据图3 所示的Excel 表头,修改了一下GitHub 地址所提供的程序源代码,如上面的process_wb(wb)函数,对上课班级中的每个学生信息进行处理。
3 在渲染进程的界面中显示学生信息
在将Excel 本地文件中的数据导入内存数组中同时,也将学生的学号和姓名信息在渲染进程的界面中显示出来,如图4 所示是在导入学生信息之前的界面,图5 是导入学生信息之后的界面。
图4 导入Excel文件之前渲染进程的界面
图5 导入Excel学生信息之后的渲染进程界面
以上就是导入班级信息之后再调用渲染进程的initSrc 函数,将学生的姓名和学号在渲染进程的主界面中显示出来,源代码如下,文章篇幅有限,就没有将渲染进程界面中的CSS 文本样式计算机语言写上:
//初始化屏幕界面
function initSrc(stuXh,stuXm){
if(!document)document=window.document;
const mainArea=document.getElementById('main-areaDJH');
const template=document.querySelector('#scr-maintemp');
let clone=document.importNode(template.content,true);
clone.querySelector('img').src='./public/nologin.svg';
clone.querySelector('img').setAttribute('id',stuXh);
clone.querySelector('.stuXhmain').innerText=stuXh;
clone.querySelector('.stuXmmain').innerText=stuXm;
mainArea.appendChild(clone);
const scrleft=document.getElementById('page-wrapperDJH');
const lefttemp=document.querySelector('#scr-lefttemp');
let clone2=document.importNode(lefttemp.content,true);
clone2.querySelector('.leftXh').innerText=stuXh;
clone2.querySelector('.leftXm').innerText=stuXm;
scrleft.appendChild(clone2);
}
渲染进程对应的index.html 文件如下:
4 结语
在实现本文论述的功能过程中,在网上找了好多的资料,也学到了很多的东西。但网上的资料都不是太齐全,很多程序源代码还要靠自己写出来。通过使用Electron 结构技术开发桌面程序之后,发现使用JavaScript 语言开发桌面程序有天然的优势,特别应用CSS 文本样式计算机语言设计渲染进程的界面非常方便,网上资料也非常多,感觉比传统的桌面开发工具C#、Delphi 和VC 做界面还方便。