Excel表格插件:js-xlsx.js 的使用

1、描述需求

前两天,有一个需求,excel的某一列中含有不同字符,改为统一字符。如A列(某列)的单元格含有“数字”、“字母”、“商品”、“数字”、“货品”,需求:把“数字”、“字母”改为“ABC123”。

Excel表格插件:js-xlsx.js 的使用_第1张图片

2、寻找插件

从网上搜索到一个插件名为:js-xlsx。其GitHub地址为:https://github.com/SheetJS/js-xlsx。

该插件支持IE8及以上版本浏览器,当然还支持safri、firefox、chrome这类优秀浏览器。它提供了脚本js引入、npm及bower等模块引入。

3、使用过程

先叙述下我使用它解决那个需求的过程,更多的内容下次分解。

html页面显示如图:

Excel表格插件:js-xlsx.js 的使用_第2张图片

3.1读取表格文件:

js:

var reader = new FileReader();
var fileExcel={
	"oldFile":"",
};
function addLis() { //监听输入框,引入文件
    var xlf = document.getElementById('xlf');
    if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
}

addLis();

// 变量fileExcel赋值,获取文件
function handleFile(e) {
    var files = e.target.files;
    fileExcel.oldFile = files[0];
    readFile(fileExcel.oldFile);
}

function readFile(file) {
    var name = file.name;
    reader.onload = function (e) {
        fileExcel.oldFile = e.target.result;
        var wb = XLSX.read(fileExcel.oldFile, { type: "binary" });
        console.log(wb);
        var wb_sheetname=wb.SheetNames[0];
        console.log(wb.Sheets[wb_sheetname]);
    };
    reader.readAsBinaryString(file);
}

这样,就有了一个全局变量fileExcel,用于存储相关参数,如同vuejs的vuex功能。

3.2 读取第一个工作表

    // 读取文件
    var wb = XLSX.read(fileExcel.oldFile, { type: "binary" });
    // console.log(wb);
    var wb_sheetname=wb.SheetNames[0]; //获取第一张表的名字
    var wb_sheet=wb.Sheets[wb_sheetname]; //通过表名获取第一张表
    // 加入变量
    fileExcel.wb=wb;
    fileExcel.wb_sheetname=wb_sheetname;
    fileExcel.wb_sheet=wb_sheet;
该插件注册了一个全局变量XLSX,提供各种操作。如读取文件接口:
XLSX.read(File, options)

options是解析文件时参数对象,here:

这里使用 type:"binary",表示:以字符编码的方式解析。我们可以看到控制台的结果是:

Excel表格插件:js-xlsx.js 的使用_第3张图片

这里可以看到工作簿的详细信息。其中:

SheetNames:由工作簿中工作表的名字组成的数组。

Sheets:包含各工作表的详细内容:

Excel表格插件:js-xlsx.js 的使用_第4张图片

我上传的表格文件中含有3张表,名称分别为:Sheet1、Sheet2、Sheet3。其中!ref表示表格的数据分布范围,是一个字符串类型的数据。有了这个我们在对表格进行各中操作时就有了一个参考。

3.3获取工作表中数据范围

可以通过正则表达式把!ref信息转化为可使用的数据:

    // 开始查询
    var columnNum=$("#queryColumn").val(); //指定查询哪一列
    var columnMax=wb_sheet["!ref"];
    //console.log(columnMax)
    // 匹配数字
    var column_arr=/([A-Z]+)([0-9]+):([A-Z]+)([0-9]+)/i.exec(columnMax)
    console.log(column_arr)

这样,就可以通过数组来操作数据范围了。得到以下结果:


可以看到第一个工作表Sheet1的数据范围是:A列到AD列,1行到12行。得到这个数据可以让我们在进行表格操作时有一个明确的范围,比如查找A列的数据时,只要遍历A1到A12就可以了。

3.4查询数据

在“修改的列名”输入框中键入A,点击查询按钮,得到以下结果:

Excel表格插件:js-xlsx.js 的使用_第5张图片

这里我加入了一段去除重复的代码:

    var arr_sheet_name=[]; //存储列名
    var arr_sheet_value=[]; //存储单元格的内容,不重复
    for(var i=column_arr[2]; i<=column_arr[4]; i++){
    	var column_query_num=columnNum.toString()+i;
    	console.log(wb_sheet[column_query_num])
    	var flag=true; //标记是否可以存储单元格内容,
    	if(wb_sheet[column_query_num]){
    		for(var j=0; j

把两个数组显示到页面的第一个大框框中,以备用户选择:

    for (var i = 0; i<=arr_sheet_value.length - 1;  i++) {
    	var stringTag='
'+arr_sheet_value[i]+'
'; $("#leftSelect").append(stringTag) } divfununbind(); divfunbind();

3.5选择数据进行修改

在左框中点击要修改的内容:

Excel表格插件:js-xlsx.js 的使用_第6张图片

点击 >> 按钮,输入要修改的期望文字:

Excel表格插件:js-xlsx.js 的使用_第7张图片

点击OK按钮,

Excel表格插件:js-xlsx.js 的使用_第8张图片

	// 更改内容
	var change_arr=$("#rightSelect div").map(function() {
		return $(this).attr("data-inde");
	}).get().join("_").split("_"); //获取需要修改的单元格地址
	for(var i=0; i";
		fileExcel.wb_sheet[change_arr[i]].v=changeColumn_word;
		//fileExcel.wb_sheet[change_arr[i]].w=changeColumn_word;
		console.log(change_arr[i])
		console.log(fileExcel.wb_sheet[change_arr[i]])
	}
	// 全局声明更改表格
	fileExcel.wb.Sheets[fileExcel.wb_sheetname]=fileExcel.wb_sheet;
	console.log(fileExcel.wb_sheet)

更改单元格内容时的操作对象是Sheet[cell]的属性.v,不是Sheet[cell]本身(它的类型是[Object]),

只需更改 .v 的值,因为它指向单元格的值(我猜测此处是引用类型的传值),其他的 .h .r .w 等等都是由它转换而来的。here

Excel表格插件:js-xlsx.js 的使用_第9张图片

我这里把要操作的工作表单独保存为全局变量fileExcel的属性fileExcel.wb_sheet,所以修改数据之后,需要重新给fileExcel.wb.Sheets[fileExcel.wb_sheetname]赋值。

3.6保存工作簿

点击保存按钮,弹出浏览器自带的下载框:

Excel表格插件:js-xlsx.js 的使用_第10张图片

其中的网址是该插件默认的,可以自行修改:

	// /* bookType can be any supported output type */
	// var wopts = { bookType:'xlsx', bookSST:false, type:'array' };
	// var wbout = XLSX.write(fileExcel.wb, wopts);
	// /* the saveAs call downloads a file on the local machine */
	// XLSX.writeFile.saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx");

我这里,使用的是:

XLSX.writeFile(fileExcel.wb, 'out.xlsx');

writeFile()接口将自动调用saveAs()。保存文件时,一定要保存工作簿wb,保存工作表wb_sheet是错误的。

Excel表格插件:js-xlsx.js 的使用_第11张图片

4、注意:

该程序有两个bug,因为制作时的目标是:是否有能力实现需求,并没有要求功能十分完整,程序尽可能完美。

第一个bug是:上传文件的input标签,有一个accept属性,给属性只有一个声明功能,并不进行验证。W3C建议进行后台验证。此处如果上传的文件不是Excel是可以上传的。

第二个bug是:输入列名的输入框应该输入规范的列名,如A、AB,如果输入a、Ab、aB或数字或字母与数字的组合是没有结果的。此处应该进行判断和输入有误的提示型告知。

5、关于bug的想法:

软件本没有bug,用的人多了就有了bug。解决bug的第一条思路,鄙人认为是:数据验证、数据约束。

如果不是输入类型的bug,我想也可以从数据约束的思路找到一点点启发。

你可能感兴趣的:(Excel表格插件:js-xlsx.js 的使用)