【JavaScript】浏览器中导入导出excel

2018-11-13  本文已影响0人  burningalive

导入excel

确保导入了xlsx模块,将文件选择器的change事件添加handleFilePickerChange方法即可.

// 先 npm install xlsx 或
// <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
function handleFilePickerChange(e) {
    let files = e.target.files;
    let fileReader = new FileReader();
    fileReader.readAsBinaryString(files[0]);
    e.target.value = '';
    fileReader.onload = (readerEv) => {
        let workbook;
        let datas = []; // 存取要读取的值
        try {
            let data = readerEv.target.result;
            workbook = XLSX.read(data, { type: 'binary' }); // 二进制流方式读取
        } catch (err) {
            message( '文件类型不正确');
            return;
        }
        // 遍历每张表读取
        for (let sheet in workbook.Sheets) {
            if (sheet in workbook.Sheets) {
                let fromTo = workbook.Sheets[sheet]['!ref'];
                datas = datas.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
                break; // 如果只取第一张表
            }
        }
        let updateDatas = [];
        for (let row of datas) {
            if ('课程' in row && '班级编号' in row && '用户姓名' in row && '用户手机号' in row) {
                if (rowdataPassValidate()) {
                    updateDatas.push({
                        ClassNum: row.班级编号,
                        TestType: row.课程 === '四级' ? 0 : 1,
                        UserName: row.用户姓名,
                        CellPhone: row.用户手机号.toString(),
                        OperatorUID: ''
                    });
                } else {
                    message( '请确保要上传的数据');
                }
            } else {
                message( '请检查excel的表头是否正确');
                return;
            }
        }
        fetch( requestUrl, {
            method: 'POST',
            body: JSON.stringify(updateDatas),
            headers: new Headers({
                'Content-Type': 'application/json'
            })
        }).then(response => response.json())
        .then(result => {
            if (Array.isArray(result) && result.length) {
                this.uploadFailDialogVisible = true;
                this.uploadFailInfo = result;
            } else {
                message('上传成功');
            }
        }).catch(err => console.log(err));
    };
}

导出excel

先导入xlsxfilesaver, 再引入下方函数, 调用exportToExcel并传入要导出的数组, 下载生成的excel文件。
如有避免全局function污染变量的需要, 可自行将下方函数封装成一个class.
导出的数组格式:

[
    {
        '图片url': 'http://*****/**.jpg',
        '标题': 'qwertyuiop',
        '评论数': 54
    }, {
        '图片url': 'http://*****/*****.png',
        '标题': 'asdfghjkl',
        '评论数': 86
    }
]
// npm install xlsx file-saver 或
// <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
// <script src="https://unpkg.com/file-saver@2.0.0-rc.3/dist/FileSaver.min.js"></script>
function exportToExcel(arrayOfExportToExcel) {
    if (Array.isArray(arrayOfExportToExcel) && arrayOfExportToExcel.length) {
        downloadExl(arrayOfExportToExcel);
    }
}
function downloadExl(data, type) {
    var keys = Object.keys(data[0]);
    var firstRow = {};
    keys.forEach(function (item) {
        firstRow[item] = item;
    });
    data.unshift(firstRow);

    var content = {};

    // 把json格式的数据转为excel的行列形式
    var sheetsData = data.map(function (item, rowIndex) {
        return keys.map(function (key, columnIndex) {
            return Object.assign({}, {
                value: item[key],
                position: (columnIndex > 25 ? getCharCol(columnIndex) : String.fromCharCode(65 + columnIndex)) + (rowIndex + 1),
            });
        });
    }).reduce(function (prev, next) {
        return prev.concat(next);
    });

    sheetsData.forEach(function (item, index) {
        content[item.position] = { v: item.value };
    });

    //设置区域,比如表格从A1到D10,SheetNames:标题,
    var coordinate = Object.keys(content);
    var workBook = {
        SheetNames: ["Sheet"],
        Sheets: {
            "Sheet": Object.assign({}, content, { "!ref": coordinate[0] + ":" + coordinate[coordinate.length - 1] }),
        }
    };
    //这里的数据是用来定义导出的格式类型
    var excelData = XLSX.write(workBook, { bookType: "xlsx", bookSST: false, type: "binary" });
    var blob = new Blob([string2ArrayBuffer(excelData)], { type: "" });
    saveAs(blob, "导出的excel文件.xlsx");
}
//字符串转字符流
function string2ArrayBuffer(s) {
    var buf = new ArrayBuffer(s.length);
    var view = new Uint8Array(buf);
    for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
    return buf;
}
// 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
function getCharCol(n) {
    let temCol = "",
        s = "",
        m = 0
    while (n > 0) {
        m = n % 26 + 1
        s = String.fromCharCode(m + 64) + s
        n = (n - m) / 26
    }
    return s
}
上一篇下一篇

猜你喜欢

热点阅读