前端完成对excel的批量导入导出

783 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

前言

最近在研究如何通过 js 来处理 excel,发现存在一个 jS 的 第三方库,可以比较简单的对 excel 进行处理,excel 的数据放到前端不过就是一个对象罢了,今天就来学习一下,如何进行最简单的导入导出。

完整的代码可以移步文章的最下方。

xlsx npm

上文提到的第三方库就是 xlsx 这个库

xlsx npm

<script type="text/javascript" src="./asecct/xlsx.core.min.js"></script>

通过引入这个库,就可以使用它提供的,对xlsx处理的功能,需要 script 压缩包的可以到这个地址去获取:

mr-yel.github.io/my-project/…

导入功能

文件导入

通过 input标签 以及 type=file 我们能够轻松的通过这个元素的 change 事件获取到输入的文件以及具体的文件信息,

<label id="realBtn" class="lqwvje-btn">
        <input type="file" id="testFile" hidden="hidden" multiple />
        上传文件
</label>
...
const loadFileBottom = document.querySelector("#testFile");
loadFileBottom.addEventListener("change", importExcel);
...
function importExcel() {
    const files = document.querySelector("#testFile").files;
}

然后通过 FileReader 的 readAsBinaryString 方法, readAsBinaryString 方法会读取指定的 Blob 或 File 对象,当读取完成的时候,readyState 会变成DONE(已完成),并触发 loadend (en-US) 事件,同时 result 属性将包含所读取文件原始二进制格式。

FileReader.readAsBinaryString()

const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = function (e) {
...
}

XSLX 读取文件

在上一步获取到文件原始的二进制格式数据后,我们就可以通过 XSLX 提供的一个 read 方法,来讲这些数据转为一个对象。

const data = e.target.result;
console.log('data', data);
const excel = window.XLSX.read(data, {
        type: "binary",
});
console.log("excel", excel);

image.png

在这个对象的 sheetNames 和 Sheets 中,我们成功的发现了这个 excel 表中包含的数据。

image.png

最后还有一个也是 XSLX 提供的 sheet_to_json 方法,让我们能够把上面的那个 sheet 表转为一个 数组对象

const newData = window.XLSX.utils.sheet_to_json(
	excel.Sheets[excel.SheetNames[i]]
);
console.log('newData', newData);

image.png

根据这个对象做出处理,我们就能够得到这张excel表中保存的数据了。

表格渲染

在一开始获取到 file 的时候,我们能够获取到文件的文件名,在之后通过 sheet_to_json 方法,我们能够获取表中的数据详情,那么,通过循环这些数据,我们就能够在前端生成一个表格。

image.png

导出

在前面的导入处理中,我们成功的获取到了excel表的各种数据,关于导出方法也不过是在这份数据的基础上做出拼接操作,最后调用 XSLX 提供的文件写入方法,就能够调用浏览器的下载下载一份新的 excel 表格。


function json2Excel(
        data,
        sheetName = "sheetName",
        fileName = "fileName"
) {
        let type = fileName.split(".");

        if (
                type[type.length - 1] !== "xlsx" &&
                type[type.length - 1] !== "xls"
        ) {
                fileName = fileName + ".xlsx";
        }
        const jsonWorkSheet = XLSX.utils.json_to_sheet(data);

        const workBook = {
                SheetNames: [sheetName], // 指定有序 sheet 的 name
                Sheets: {
                        [sheetName]: jsonWorkSheet, // 表格数据内容
                },
        };

        return XLSX.writeFile(workBook, fileName); // 向文件系统写出文件
}

这个方法比较关键的点就在于,我们需要把保存的数据,调用 json_to_sheet 方法,重新转为 sheet 表,然后构造好需要保存的 workBook,其中就包含 excel 的子表的名字以及这个名字对应的数据是什么,最后才是像浏览器写出这份数据。

导出想比较与导入要来的简单一点,这里就不做过多的讲解,感兴趣的可以直接去看代码。

批量导入导出

对于批量这个操作,我们需要开启 input 元素上的 multiple 属性,这样就可以在选择的时候通过 shift 或者ctrl 选中多个文件,并且在导入之后的 files 获取到的也会是一个数组,这里其实跟单个文件的处理是完全相同的,我们可以定义一个数据模型,用来保存所有的输入文件,最后在导出的时候也去获取这个文件并且做出导出,想要修改相关的数据就可以直接对这个对象进行操作。

<input type="file" id="testFile" hidden="hidden" multiple />

像我就定义了一个 excelDataArr 的数组,这个数组保存着 excelData 对象,对象存在四个属性,分别为 id 唯一的key,name 文件名称,titleList 表格标题,data 表格数据。

这样在导入的时候组装好数据对象push进这个数组,导出的时候再从这个数组中去获取数据,就能够比较方便的实现导入导出功能,并且像想要修改表格的名称,也可以通过去修改这个对象的name属性来实现。

image.png

项目源码

excel批量导入导出

总结

本文简单的实现了 excel 的导入和导出,总的来说只是通过操作数据来简单的实现,还无法解决复杂的 excel 数据处理,之后要更进一步应该需要对 数据模型 做出改造,现有的明显无法解决复杂 excel 表的数据。把比方说表中存在多个子表,表中存在多个合并的单元格,甚至图片之类的,这些都会在以后做出更多的扩展。