xlsx.js 是一个开源且应用广泛的前端类库。读取导入工作簿的办法大致分为三步:
0、泛微E8表单页面中引入 xlsx.core.js 。
1、在泛微E8的表单页面设计器中,增加一个文件上传字段并设置 id(实际是一个 input 元素)。
2、用 js 或库(如 jQuery)监听该文件上传字段的 change 事件,将回调对象 e 的 e.target.files 的值读取为上传的全部文件名(数组)。
3、实例化 xlsx.core.js 中的 FileReader() 对象,并调用 FileReader 对象的 read(单个文件名) 方法进行读取和获取各行的值,将工作簿各行中单元格的值、赋给泛微E8表单页面的对应(明细表)的单元格。
注意:泛微E8的明细表单元格中,如两个明细表中有同名的字段,则前端脚本是无法进行区分的。首先获取目标明细表的最大行数,如需要导入的工作簿超过当前的最大行数,则先(循环)往目标明细表插入一行,再(循环)导入工作簿的对应一行。
另外,导入的单元格如未填入值,读取的内容中将没有这个单元格的属性,直接读取会抛出异常、需要进行捕捉处理。
可以看到 L2 单元格如果没有值,连 L2 这个属性都不会产生。
导入一个含有表头(第0行)的模板的代码大致如下:
/* 1、创建接收导入 excel 文件的元素 */
function createInputFirst(){
//在表单的对应 id 的单元格中,插入接收导入模板的 input 元素
//不能直接在表单设计器中新建 附件上传 字段来替代此功能,否则会报错
jQuery(".drsj").append("<input type='file' class='excel-file'>");
}
/* 2、监听接收导入 excel 文件的元素,并写入对应明细行的单元格 */
function loadExcelThen(){
//貌似只能读取xls,读取xlsx的数据读取不了
//明细1增加行之前,先清空明细表1的行
jQuery('.excel-file').change(function(e) {
var files = e.target.files;
WfForm.delDetailRow("detail_1", "all");
var filename = files[0].name;
if (filename.substring(filename.length - 3, filename.length) != 'xls') {
alert("只支持xls的文件,不支持xlsx文件,请将xlsx另存为xls文件再上传");
return;
}
var fileReader = new FileReader();
// 以二进制方式打开文件
fileReader.readAsBinaryString(files[0]);
fileReader.onload = function (ev) {
try {
var data = ev.target.result,
workbook = XLSX.read(data, {
type: 'binary'
}) // 以二进制流方式读取得到整份excel表格对象
} catch (e) {
alert('文件类型不正确');
return;
}
var cell = '';
var flag = "";
var mxb = 0;
var add = 0;
var oTable0index = 0;
var add1 = 0;
var oTable1index = 0;
var lshs1 = new Array();
var lshylds1 = new Array();
for (var sheet in workbook.Sheets) {//遍历sheet
if (workbook.Sheets.hasOwnProperty(sheet)) {
lastRow = workbook.Sheets[sheet]['!ref']; // A1:AC2
var xx = lastRow.indexOf(":"); //2
lastRow = lastRow.substring(lastRow.indexOf(":") + 3, lastRow.length);//找到最后一行,避免遍历过多的空行
// lastROw 应为 1,2,3 ...
cell = workbook.Sheets[sheet];
for (var x = 1; x <= lastRow; x++) {//遍历行数
var AfirstSheet;
if(flag == ""){
try {
AfirstSheet = cell['A' + x].v;//每一行的首列
} catch (e) {
AfirstSheet = "";
}
if (AfirstSheet == "标准板类型") {//开始遍历
flag = 'mx0';
continue;
}
}
if (AfirstSheet == "") {//为防止用户表格有几万条空行,首列为空时,退出循环
break;
}
//add 2022-02-22
var currentCellVal = "";
//end add
if (flag == 'mx0' && AfirstSheet != "") {
DPTools.DPAddDetailRow(1);//明细表1增加一行
oTable0index = getMaxRowIndex(0);
try {
//add 2022-02-22
currentCellVal = cell['A' + x].v;
//end add
DPSetValue(fieldMap.MX1_BZBLX + oTable0index, cell['A' + x].v);//标准版类型
} catch (e) {
console.log("导入单元格 A 错误:目标值"+currentCellVal+";异常原因:"+e);
}
try {
//add 2022-02-22
currentCellVal = cell['B' + x].v;
//end add
DPSetValue(fieldMap.MX1_BZBBH + oTable0index, cell['B' + x].v);//标准版编号
} catch (e) {
console.log("导入单元格 B 错误:目标值"+currentCellVal+";异常原因:"+e);
}
/* 中间省略 */
try {
//add 2022-02-22
currentCellVal = cell['AC' + x].v;
//end add
DPSetValue(fieldMap.MX1_GDCPJF + oTable0index, cell['AC' + x].v);//高端产品积分(%):(非经销商为0)
} catch (e) {
console.log("导入单元格 AC 错误:目标值"+currentCellVal+";异常原因:"+e);
}
add++;
}
}
break;
}
}
}
});
}
xlsx.js 的文档可以参考这个:js-xlsx: Documentation | Openbasejs-xlsx docs, getting started, code examples, API reference and morehttps://openbase.com/js/js-xlsx/documentation
后续有其他的再补充。
(完)