精华内容
下载资源
问答
  • Excel导入功能 前端 JQ JS xlsx.core.min.js
  • 最近做了好几个和excel相关的项目,大部分是用phpexcel处理的,因为首先想到的也是用后端语言处理这些肯定更给力点。但是后端导出excel的时候,数据量大起来...papaparse 和 jsxlsx但是前后端分离开发一个项目的时候...

    最近做了好几个和excel相关的项目,大部分是用phpexcel处理的,因为首先想到的也是用后端语言处理这些肯定更给力点。但是后端导出excel的时候,数据量大起来会很慢。我测试了下我们那个表,用phpexcel导出,12000条的时候需要花掉40秒左右,然而php.ini默认都是最长30s就要中断了。还得改配置,还得等很长时间。

    papaparse 和 jsxlsx

    但是前后端分离开发一个项目的时候,由于前端需要excel的导入导出,接触了两个插件,一个是papaparse,相关介绍见papaparse.

    另一个是jsxlsx。因为papaparse虽然体积小,但是只能搞csv格式。jsxlsx却没有这个限制。但是core版都要500k,体积确实大了点,但比其他的性能,还是值得拥有的撒。我用这个插件测试,20000条只用了3.5s。其实想想也好理解,这样不用跟后端频繁交互,消耗的是浏览器本身的性能,当然会快不少。

    上代码:

    $(function () {

    var oCk = true;

    $('#upload').click(function()

    {

    if(oCk){

    oCk = false;

    if (!$('#aaaa')[0].files.length) {

    commonFn.layerMsg('请选择数据文件');

    oCk = true;

    } else {

    var wb;//读取完成的数据

    var rABS = false; //是否将文件读取为二进制字符串

    var fileObj = document.getElementById('company-login-zhizhao');

    var resJson ;

    importf(fileObj);

    function importf(obj) {//导入

    if(!obj.files) {

    return;

    }

    var f = obj.files[0];

    var reader = new FileReader();

    reader.onload = function(e) {

    var data = e.target.result;

    if(rABS) {

    wb = XLSX.read(btoa(fixdata(data)), {//手动转化

    type: 'base64'

    });

    } else {

    wb = XLSX.read(data, {

    type: 'binary'

    });

    }

    resJson= XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]) ;

    resJsonLen = resJson.length;

    var finalArr = [];

    for(var i=0;i

    var objs = {

    partner_id:1,

    external_orderid:resJson[i]['aaa'],

    };

    finalArr.push(objs)

    }

    $.ajax({

    'url':'0000000000', //验证登录信息

    data:{param:finalArr},

    type:'post',

    dataType:"json",

    success: function(data){

    console.log(data)

    setTimeout(function () {

    oCk = true;

    },500)

    },

    error:function (err) {

    commonFn.layerMsg('请求失败');

    setTimeout(function () {

    oCk = true;

    },500)

    return false;

    }

    })

    };

    if(rABS) {

    reader.readAsArrayBuffer(f);

    } else {

    reader.readAsBinaryString(f);

    }

    }

    function fixdata(data) { //文件流转BinaryString

    var o = "",

    l = 0,

    w = 10240;

    for(; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)));

    o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));

    return o;

    }

    }

    }

    })

    })

    展开全文
  • js xlsx 的导出

    2020-01-10 11:00:12
    1.安装依赖 npm install -S file-saver xlsx ...2.项目中src下新建一个js文件夹放入两个文件Blob.js和 Export2Excel.js 3.使用 onExport:function(){ // console.log('导出EXCEL'); const list = t...

    1.安装依赖

    npm install -S file-saver xlsx
    npm install -D script-loader

     

    2.项目中src下新建一个js文件夹放入两个文件  Blob.js和 Export2Excel.js

     

    3.使用

    onExport:function(){
      // console.log('导出EXCEL');
      const list = this.$refs.workpage.tableData;
      require.ensure([], () => {
        const {export_json_to_excel} = require('../../../js/Export2Excel.js');
        const tHeader = ['手机号', '微信昵称'];   //自己定义输出的数据 这是表格头部
        const filterVal = ['mobile', 'nickname'];  //对应数据中的字段名称
        const data = this.formatJson(filterVal, list);
        export_json_to_excel(tHeader, data, '导出' + new Date().getDates());
      });
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => v[j]))
    },

    4.附上 Blob.js和 Export2Excel.js 两个文件

    Blob.js

    /* eslint-disable */
    /* Blob.js
     * A Blob implementation.
     * 2014-05-27
     *
     * By Eli Grey, http://eligrey.com
     * By Devin Samarin, https://github.com/eboyjr
     * License: X11/MIT
     *   See LICENSE.md
     */
    
    /*global self, unescape */
    /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
     plusplus: true */
    
    /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
    /*excel导入导出*/
    
    (function (view) {
        "use strict";
    
        view.URL = view.URL || view.webkitURL;
    
        if (view.Blob && view.URL) {
            try {
                new Blob;
                return;
            } catch (e) {}
        }
    
        // Internally we use a BlobBuilder implementation to base Blob off of
        // in order to support older browsers that only have BlobBuilder
        var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
                var
                    get_class = function(object) {
                        return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
                    }
                    , FakeBlobBuilder = function BlobBuilder() {
                        this.data = [];
                    }
                    , FakeBlob = function Blob(data, type, encoding) {
                        this.data = data;
                        this.size = data.length;
                        this.type = type;
                        this.encoding = encoding;
                    }
                    , FBB_proto = FakeBlobBuilder.prototype
                    , FB_proto = FakeBlob.prototype
                    , FileReaderSync = view.FileReaderSync
                    , FileException = function(type) {
                        this.code = this[this.name = type];
                    }
                    , file_ex_codes = (
                        "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
                        + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
                    ).split(" ")
                    , file_ex_code = file_ex_codes.length
                    , real_URL = view.URL || view.webkitURL || view
                    , real_create_object_URL = real_URL.createObjectURL
                    , real_revoke_object_URL = real_URL.revokeObjectURL
                    , URL = real_URL
                    , btoa = view.btoa
                    , atob = view.atob
    
                    , ArrayBuffer = view.ArrayBuffer
                    , Uint8Array = view.Uint8Array
                    ;
                FakeBlob.fake = FB_proto.fake = true;
                while (file_ex_code--) {
                    FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
                }
                if (!real_URL.createObjectURL) {
                    URL = view.URL = {};
                }
                URL.createObjectURL = function(blob) {
                    var
                        type = blob.type
                        , data_URI_header
                        ;
                    if (type === null) {
                        type = "application/octet-stream";
                    }
                    if (blob instanceof FakeBlob) {
                        data_URI_header = "data:" + type;
                        if (blob.encoding === "base64") {
                            return data_URI_header + ";base64," + blob.data;
                        } else if (blob.encoding === "URI") {
                            return data_URI_header + "," + decodeURIComponent(blob.data);
                        } if (btoa) {
                            return data_URI_header + ";base64," + btoa(blob.data);
                        } else {
                            return data_URI_header + "," + encodeURIComponent(blob.data);
                        }
                    } else if (real_create_object_URL) {
                        return real_create_object_URL.call(real_URL, blob);
                    }
                };
                URL.revokeObjectURL = function(object_URL) {
                    if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
                        real_revoke_object_URL.call(real_URL, object_URL);
                    }
                };
                FBB_proto.append = function(data/*, endings*/) {
                    var bb = this.data;
                    // decode data to a binary string
                    if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
                        var
                            str = ""
                            , buf = new Uint8Array(data)
                            , i = 0
                            , buf_len = buf.length
                            ;
                        for (; i < buf_len; i++) {
                            str += String.fromCharCode(buf[i]);
                        }
                        bb.push(str);
                    } else if (get_class(data) === "Blob" || get_class(data) === "File") {
                        if (FileReaderSync) {
                            var fr = new FileReaderSync;
                            bb.push(fr.readAsBinaryString(data));
                        } else {
                            // async FileReader won't work as BlobBuilder is sync
                            throw new FileException("NOT_READABLE_ERR");
                        }
                    } else if (data instanceof FakeBlob) {
                        if (data.encoding === "base64" && atob) {
                            bb.push(atob(data.data));
                        } else if (data.encoding === "URI") {
                            bb.push(decodeURIComponent(data.data));
                        } else if (data.encoding === "raw") {
                            bb.push(data.data);
                        }
                    } else {
                        if (typeof data !== "string") {
                            data += ""; // convert unsupported types to strings
                        }
                        // decode UTF-16 to binary string
                        bb.push(unescape(encodeURIComponent(data)));
                    }
                };
                FBB_proto.getBlob = function(type) {
                    if (!arguments.length) {
                        type = null;
                    }
                    return new FakeBlob(this.data.join(""), type, "raw");
                };
                FBB_proto.toString = function() {
                    return "[object BlobBuilder]";
                };
                FB_proto.slice = function(start, end, type) {
                    var args = arguments.length;
                    if (args < 3) {
                        type = null;
                    }
                    return new FakeBlob(
                        this.data.slice(start, args > 1 ? end : this.data.length)
                        , type
                        , this.encoding
                    );
                };
                FB_proto.toString = function() {
                    return "[object Blob]";
                };
                FB_proto.close = function() {
                    this.size = this.data.length = 0;
                };
                return FakeBlobBuilder;
            }(view));
    
        view.Blob = function Blob(blobParts, options) {
            var type = options ? (options.type || "") : "";
            var builder = new BlobBuilder();
            if (blobParts) {
                for (var i = 0, len = blobParts.length; i < len; i++) {
                    builder.append(blobParts[i]);
                }
            }
            return builder.getBlob(type);
        };
    }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
    

    Export2Excel.js

    /* eslint-disable */
    /*excel导入导出*/
    require('script-loader!file-saver');
    require('./Blob');
    require('script-loader!xlsx/dist/xlsx.core.min');
    function generateArray(table) {
        var out = [];
        var rows = table.querySelectorAll('tr');
        var ranges = [];
        for (var R = 0; R < rows.length; ++R) {
            var outRow = [];
            var row = rows[R];
            var columns = row.querySelectorAll('td');
            for (var C = 0; C < columns.length; ++C) {
                var cell = columns[C];
                var colspan = cell.getAttribute('colspan');
                var rowspan = cell.getAttribute('rowspan');
                var cellValue = cell.innerText;
                if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
    
                //Skip ranges
                ranges.forEach(function (range) {
                    if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
                        for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
                    }
                });
    
                //Handle Row Span
                if (rowspan || colspan) {
                    rowspan = rowspan || 1;
                    colspan = colspan || 1;
                    ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
                }
                ;
    
                //Handle Value
                outRow.push(cellValue !== "" ? cellValue : null);
    
                //Handle Colspan
                if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
            }
            out.push(outRow);
        }
        return [out, ranges];
    };
    
    function datenum(v, date1904) {
        if (date1904) v += 1462;
        var epoch = Date.parse(v);
        return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
    }
    
    function sheet_from_array_of_arrays(data, opts) {
        var ws = {};
        var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
        for (var R = 0; R != data.length; ++R) {
            for (var C = 0; C != data[R].length; ++C) {
                if (range.s.r > R) range.s.r = R;
                if (range.s.c > C) range.s.c = C;
                if (range.e.r < R) range.e.r = R;
                if (range.e.c < C) range.e.c = C;
                var cell = {v: data[R][C]};
                if (cell.v == null) continue;
                var cell_ref = XLSX.utils.encode_cell({c: C, r: R});
    
                if (typeof cell.v === 'number') cell.t = 'n';
                else if (typeof cell.v === 'boolean') cell.t = 'b';
                else if (cell.v instanceof Date) {
                    cell.t = 'n';
                    cell.z = XLSX.SSF._table[14];
                    cell.v = datenum(cell.v);
                }
                else cell.t = 's';
    
                ws[cell_ref] = cell;
            }
        }
        if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
        return ws;
    }
    
    function Workbook() {
        if (!(this instanceof Workbook)) return new Workbook();
        this.SheetNames = [];
        this.Sheets = {};
    }
    
    function s2ab(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;
    }
    
    export function export_table_to_excel(id) {
        var theTable = document.getElementById(id);
        console.log('a')
        var oo = generateArray(theTable);
        var ranges = oo[1];
    
        /* original data */
        var data = oo[0];
        var ws_name = "SheetJS";
        console.log(data);
    
        var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
    
        /* add ranges to worksheet */
        // ws['!cols'] = ['apple', 'banan'];
        ws['!merges'] = ranges;
    
        /* add worksheet to workbook */
        wb.SheetNames.push(ws_name);
        wb.Sheets[ws_name] = ws;
    
        var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
    
        saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
    }
    
    function formatJson(jsonData) {
        console.log(jsonData)
    }
    export function export_json_to_excel(th, jsonData, defaultTitle) {
    
        /* original data */
    
        var data = jsonData;
        data.unshift(th);
        var ws_name = "SheetJS";
    
        var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
    
    
        /* add worksheet to workbook */
        wb.SheetNames.push(ws_name);
        wb.Sheets[ws_name] = ws;
    
        var wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
        var title = defaultTitle || '列表'
        saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
    }
    

     

    展开全文
  • js xlsx自定义样式导出

    千次阅读 2019-10-18 20:13:01
    xlsx-style 为xlsx库添加样式,比如字体颜色,大小,行宽等。但是只支持xlsx、xlsm、xlsb格式 FileSaver.js 负责下载保存文件。对各种兼容性比较好,对跨域文件也有处理 lodash js常用工具库 需要注意的地方 一、...

    使用的技术

    1. xlsx 用于解析和编写各种电子表格。比如excel、csv、html文件
    2. xlsx-style 为xlsx库添加样式,比如字体颜色,大小,行宽等。但是只支持xlsx、xlsm、xlsb格式
    3. FileSaver.js 负责下载保存文件。对各种兼容性比较好,对跨域文件也有处理
    4. lodash js常用工具库

    需要注意的地方

    一、引入xlsx-style报错

    This relative module was not found:
    ./cptable in ./node_modules/xlsx-style@0.8.13@xlsx-style/dist/cpexcel.js

    亲测两种解决方案:

    1. 在\node_modules\xlsx-style\dist\cpexcel.js 807行 的 var cpt = require(’./cpt’ + ‘able’); 把这一行改成 var cpt = cptable;
    2. 把xlsx的cpexcel.js文件复制到xlsx-style的dist文件夹,覆盖cpexcel.js。

    二、颜色添加不上

    1. xlsx-style 只 支持16进制的ARGB颜色,比如:{ rgb: "FFFFAA00" }。注意这里是没有#号的。
    2. 添加背景色是使用fill的fgColor,而不是bgColor。这里需要驼峰编写。

    实现步骤

    一、需求描述

    将列表数据导出成Excel。所有的导出表格都固定表头样式,但是内容不固定,特殊列需要高亮(添加背景色),其他的数据列按需求设置宽度,可以添加换行等。(比如身份证号固定字符长度,地址列固定宽度、自动换行)

    二、实现导出核心代码

    使用xlsx的json_to_sheet工具方法,把数组的数据格式转换成xlsx需要worksheet。然后再添加xlsx-style支持的样式代码,使用xlsx-style编写成数据流,最后再使用FileSaver.js把数据流保存成文件

    创建工作簿

    let wb = XLSX.utils.book_new()
    

    创建显示表头

    const ws = XLSX.utils.json_to_sheet([
      colNames
    ], { header: keys, skipHeader: true })
    

    追加数据到excel中,从第二行开始

      XLSX.utils.sheet_add_json(ws, data, { header: keys, skipHeader: true, origin: 'A2' })
    

    添加表头样式,设置背景色、字体大小、下边框线

    for (const key in ws) {
      // 第一行
      if(key.replace(/[^0-9]/ig, '') === '1') {
        ws[key].s = {
          fill: {
            fgColor: { rgb: 'FFA3F4B1' } // 添加背景色
          },
          font: {
            name: '宋体', // 字体
            sz: 12, // 字体大小
            bold: true // 加粗
          },
          border: {
          	// 下划线
            bottom: {
              style: 'thin',
              color: 'FF000000'
            }
          }
        }
      }
    }
    

    生成xlsx导出类。这里必须使用xlsx-style才能生成指定样式

    wbOut = XLSXStyle.write(wb, { bookType: bookType, bookSST: false, type: 'binary' })
    

    生成并下载文件

    saveAs(new Blob([s2ab(wbOut)], { type: '' }), filename)
    

    完整的代码

    import XLSX from 'xlsx'
    import XLSXStyle from 'xlsx-style'
    import { saveAs } from 'file-saver'
    import path from 'path'
    import _ from 'lodash'
    
    const FILE_NAME = '云途教育表格.xlsx'
    const COL_PARAMS = ['hidden', 'wpx', 'width', 'wch', 'MDW']
    const STYLE_PARAMS = ['fill', 'font', 'alignment', 'border']
    
    /**
     * 数字转换成excel表头。 (递归处理)
     * @param {Number} num 需要转换的数字
     */
    // eslint-disable-next-line no-unused-vars
    function numToString(num) {
      let strArray = []
      let numToStringAction = function(o) {
        let temp = o - 1
        let a = parseInt(temp / 26)
        let b = temp % 26
        strArray.push(String.fromCharCode(64 + parseInt(b + 1)))
        if (a > 0) {
          numToStringAction(a)
        }
      }
      numToStringAction(num)
      return strArray.reverse().join('')
    }
    
    /**
     * 表头字母转换成数字。(进制转换)
     * @param {string} str 需要装换的字母
     */
    function stringToNum(str) {
      let temp = str.toLowerCase().split('')
      let len = temp.length
      let getCharNumber = function(charx) {
        return charx.charCodeAt() - 96
      }
      let numout = 0
      let charnum = 0
      for (let i = 0; i < len; i++) {
        charnum = getCharNumber(temp[i])
        numout += charnum * Math.pow(26, len - i - 1)
      }
      return numout
    }
    
    /**
     * worksheet转成ArrayBuffer
     * @param {worksheet} s xlsx库中的worksheet
     */
    function s2ab(s) {
      if (typeof ArrayBuffer !== 'undefined') {
        const buf = new ArrayBuffer(s.length)
        const view = new Uint8Array(buf)
        for (let i = 0; i !== s.length; ++i) {
          view[i] = s.charCodeAt(i) & 0xFF
        }
        return buf
      } else {
        const buf = new Array(s.length)
        for (let i = 0; i !== s.length; ++i) {
          buf[i] = s.charCodeAt(i) & 0xFF
        }
        return buf
      }
    }
    
    /**
     * 导出成Excel
     * @param {Array} data 数据
     * @param {Object} columns 每列参数说明。可直接写对应的中文名称,也可以写这一列的样式。比如列宽,背景色
     * @param {String} filename 文件名。可根据文件名后缀动态判断文件格式。支持xlsx, xlsm, xlsb(这三个支持自定义样式), html, csv等
     * @param {Object} styleConf 其他xlsx-style的参数
     *
     * columns数据格式:{
     *         name: '姓名',
     *         sex: '性别',
     *         birthday: {
     *           name: '出生日期',
     *           wch: 14
     *         },
     *         address: {
     *           name: '地址',
     *           wpx: 160,
     *           alignment: { wrapText: true }
     *         }
     *       }
     *
     * styleConf数据格式: {
     *          'E4': {
     *             font: {
     *               bold: true,
     *               color: { rgb 'FFFF0000' }
     *             }
     *          },
     *          '!merges': [ // 合并第一行
     *             {
     *               s: { c: 0, r: 0 },
     *               e: { c: 7, r: 0 }
     *             }
     *          ]
     *        }
     */
    export function exportExcel(data, columns, filename = FILE_NAME, styleConf) {
      let keys = _.keys(columns)
      let colNames = _.mapValues(columns, o => {
        if (_.isPlainObject(o)) {
          return o.name
        } else {
          return o
        }
      })
    
      // 创建工作簿
      let wb = XLSX.utils.book_new()
    
      // 显示表头
      const ws = XLSX.utils.json_to_sheet([
        colNames
      ], { header: keys, skipHeader: true })
      // 过滤数据,只显示表头包含的数据
      for (let i = 0; i < data.length; i++) {
        data[i] = _.pick(data[i], keys)
      }
      // 追加数据到excel中,从第二行开始
      XLSX.utils.sheet_add_json(ws, data, { header: keys, skipHeader: true, origin: 'A2' })
    
      wb.SheetNames.push('sheet1')
      wb.Sheets['sheet1'] = ws
    
      // 根据不同的扩展名,导出不同格式的文件
      let bookType = null
      let ext = path.extname(filename)
      if (ext == null) {
        filename += '.xlsx'
        bookType = 'xlsx'
      } else {
        bookType = ext.substr(1).toLowerCase()
      }
    
      let wbOut
      // 如果是支持样式的格式
      if (['xlsx', 'xlsm', 'xlsb'].includes(bookType)) {
        // ws['!merges'] = [{// 合并第一行数据[B1,C1,D1,E1]
        //   s: {// s为开始
        //     c: 0, // 开始列
        //     r: 0// 开始取值范围
        //   },
        //   e: {// e结束
        //     c: 7, // 结束列
        //     r: 0// 结束范围
        //   }
        // }]
    
        for (const key in ws) {
          // 第一行,表头
          if (key.replace(/[^0-9]/ig, '') === '1') {
            ws[key].s = {
              fill: {
                fgColor: { rgb: 'FFA3F4B1' }
              },
              font: {
                name: '宋体',
                sz: 12,
                bold: true
              },
              border: {
                bottom: {
                  style: 'thin',
                  color: 'FF000000'
                }
              }
            }
          } else {
            let str = key.replace(/[^A-Za-z]+$/ig, '')
            let colIndex = stringToNum(str) - 1
            if (keys[colIndex] && _.isPlainObject(columns[keys[colIndex]])) {
              const a = _.pick(columns[keys[colIndex]], STYLE_PARAMS)
              ws[key].s = _.assign(ws[key].s, a)
            }
          }
        }
        // 设置列宽
        const colsP = []
        _.mapValues(columns, o => {
          colsP.push(_.pick(o, COL_PARAMS))
        })
        ws['!cols'] = colsP
    
        // 合并其他样式参数
        if (styleConf) {
          for (const key in styleConf) {
            if (ws.hasOwnProperty(key)) {
              ws[key].s = styleConf[key]
            }
          }
        }
        wbOut = XLSXStyle.write(wb, { bookType: bookType, bookSST: false, type: 'binary' })
      } else {
        wbOut = XLSX.write(wb, { bookType: bookType, bookSST: false, type: 'binary' })
      }
    
      saveAs(new Blob([s2ab(wbOut)], { type: '' }), filename)
    }
    

    调用实例

    import { exportExcel } from '../../utils/xlsxUtils.js'
    
    async exportStudent() {
          const params = {
            pageNum: this.pageNum,
            pageSize: this.pageSize
          }
          params[this.queryForm.searchType] = this.queryForm.searchInput
          this.exportLoading = true
          try {
            const res = await this.$http.get('/v1/ExportOrImport/exportStudentInfo', params)
            res.data.forEach(item => {
              item.courseStr = item.courses.map(o => o.name).join(',')
              item.classStr = item.classes.map(o => o.name).join(',')
            })
            await exportExcel(res.data, {
              name: '姓名',
              sex: '性别',
              idCard: {
                name: '身份证号',
                wch: 18
              },
              birthday: {
                name: '出生日期',
                wch: 14
              },
              primaryContactPhone: {
                name: '联系人号码',
                wch: 11
              },
              primaryContactName: '联系人姓名',
              relation: '联系人关系',
              nickName: '昵称',
              school: '就读学校',
              grade: '年级',
              address: {
                name: '地址',
                wpx: 160,
                alignment: { wrapText: true }
              },
              remark: {
                name: '备注',
                wpx: 240,
                alignment: { wrapText: true }
              },
              courseStr: {
                name: '报读课程',
                wpx: 120,
                font: { color: { rgb: 'ffff0000' } },
                alignment: { wrapText: true }
              },
              classStr: {
                name: '班级',
                wpx: 120,
                font: { color: { rgb: 'ffff0000' } },
                alignment: { wrapText: true }
              }
            }, '学员信息表.xlsx', {
              'E4': {
                fill: { fgColor: { rgb: 'FFFF0000' } }
              }
            })
          } catch (error) {
    
          }
          this.exportLoading = false
        }
    

    最后导出的样式:
    导出示例

    展开全文
  • 安装js-xlsx cnpm install js-xlsx 复制代码安装成功 JS: import XLSX from 'xlsx' const EXCEL = class { construct () {} /** * [exportsEXCL 导出数据到excel] * @param {Array} [_headers=[]] [表头] * @...

    安装js-xlsx

    cnpm install js-xlsx
    复制代码

    安装成功

    JS:

    import XLSX from 'xlsx'
    const EXCEL = class {
      construct () {}
      /**
       * [exportsEXCL 导出数据到excel]
       * @param  {Array}  [_headers=[]]   [表头]
       * @param  {Array}  [_body=[]]      [内容]
       * @param  {String} [name='excel'}] [文件名]
       * @return {[type]}                 [无]
       */
      exportsEXCL ({_headers = [], _body = [], name = 'excel'}) {
        /**
         *
         * workbook 对象,指的是整份 Excel 文档。我们在使用 js-xlsx 读取 Excel 文档之后就会获得 workbook 对象。
         * worksheet 对象,指的是 Excel 文档中的表。我们知道一份 Excel 文档中可以包含很多张表,而每张表对应的就是 worksheet 对象。
         * cell 对象,指的就是 worksheet 中的单元格,一个单元格就是一个 cell 对象。
         */
        // const workbook = {
        //   SheetNames: ['sheet1'],
        //   Sheets: {
        //     'sheet1': {
        //       '!ref': 'A1:E4', // 必须要有这个范围才能输出,否则导出的 excel 会是一个空表
        //       A1: {v: 'id'}
        //     }
        //   }
        // }
        // const _headers = ['id', 'name', 'age', 'country', 'remark']
        // const _data = [
        //   {
        //     id: 1,
        //     name: 'test1',
        //     age: 30,
        //     country: 'China',
        //     remark: 'hello'
        //   },
        //   {
        //     id: 2,
        //     name: 'test2',
        //     age: 40,
        //     country: 'UN',
        //     remark: '??'
        //   }
        // ]
        // 获取表头
        const headers = _headers
          // 为 _headers 添加对应的单元格位置
          // [
          //   {
          //     v: 'id', position: 'A1'
          //   },
          //   {
          //     v: 'name', position: 'B1'
          //   },
          //   ......
          // ]
          // Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
          .map((v, i) => Object.assign({}, {v, position: String.fromCharCode(65 + i) + 1}))
          // 转换成 worksheet 需要的结构
          // {
          //   A1: {v: 'id'},
          //   B1: {v: 'name'},
          //   ....
          // }
          .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {})
    
        const body = _body
          // 匹配 headers 的位置,生成对应的单元格数据
          // [
          //   [
          //     {
          //       v: 1,
          //       position: 'A2'
          //     },
          //     {
          //       v: 'test1',
          //       position: 'B2'
          //     },
          //     {
          //       v: 30,
          //       position: 'C2'
          //     },
          //     {
          //       v: 'China',
          //       position: 'D2'
          //     },
          //     {
          //       v: 'hello',
          //       position: 'E2'
          //     }
          //   ],
          //   [
          //     {
          //       v: 2,
          //       position: 'A3'
          //     },
          //     {
          //       v: 'test2',
          //       position: 'B3'
          //     },
          //     {
          //       v: 40,
          //       position: 'C3'
          //     },
          //     {
          //       v: 'UN',
          //       position: 'D3'
          //     },
          //     {
          //       v: '??',
          //       position: 'E3'
          //     }
          //   ]
          // ]
          .map((v, i) => _headers.map((k, j) => Object.assign({}, { v: v[k], position: String.fromCharCode(65 + j) + (i + 2) })))
          // 对刚才的结果进行降维处理(二维数组变成一维数组)
          // [
          //   {
          //     v: 1,
          //     position: 'A2'
          //   },
          //   {
          //     v: 'test1',
          //     position: 'B2'
          //   },
          //   {
          //     v: 30,
          //     position: 'C2'
          //   },
          //   {
          //     v: 'China',
          //     position: 'D2'
          //   },
          //   {
          //     v: 'hello',
          //     position: 'E2'
          //   },
          //   {
          //     v: 2,
          //     position: 'A3'
          //   },
          //   {
          //     v: 'test2',
          //     position: 'B3'
          //   },
          //   {
          //     v: 40,
          //     position: 'C3'
          //   },
          //   {
          //     v: 'UN',
          //     position: 'D3'
          //   },
          //   {
          //     v: '??',
          //     position: 'E3'
          //   }
          // ]
          .reduce((prev, next) => prev.concat(next))
          // 转换成 worksheet 需要的结构
          // {
          //   A2: {v: 1},
          //   B2: {v: 'test1'},
          //   .....,
          //   A3: {v: 2},
          //   B3: {v: 'test2'}
          // }
          .reduce((prev, next) => Object.assign({}, prev, {[next.position]: {v: next.v}}), {})
        // 合并headers和data
        const output = Object.assign({}, headers, body)
        // 获取所有单元格位置
        const outputPos = Object.keys(output)
        // ====设置xlsx单元格样式
        // headers['B1'].s = { font: { sz: 14, bold: true, color: { rgb: 'FFAA00' } }, fill: { bgColor: { indexed: 64 }, fgColor: { rgb: 'FFFF00' } } }
        // 计算出范围
        const ref = outputPos[0] + ':' + outputPos[outputPos.length - 1]
    
        // 构建 workbook 对象
        const wb = {
          SheetNames: ['mySheet'],
          Sheets: {
            'mySheet': Object.assign({}, output, { '!ref': ref })
          }
        }
        // 导出 Excel
        // XLSX.writeFile(wb, `${name}.xlsx`)
        XLSX.writeFile(wb, `${name}.xlsx`, { bookType: 'xlsx', bookSST: false, type: 'binary', cellStyles: true })
      }
    }
    exports.defalut = new EXCEL()
    
    复制代码
    展开全文
  • vue js xlsx 读取 本地 excel

    千次阅读 2019-07-22 13:57:28
    最近在写一个人力资源...1、安装npm包xlsx yarn add xlsx 2、结合上传组件和自己写的读取方法readXLSX,可以进行本地excel读取。 我使用的语言是vue,代码如下: <template> <div> <Upload acti...
  • 最近要实现一个功能,大概就是前端读取excel 文件,excel内容展示在页面上,用户确认无误后再上传至后端,使用的XLSX来解析excel,读取日期的时候是数字,解决这个问题花了蛮久时间,记录一下 xlsx 官方github 1....
  • 然后找到xlsx.full.min.js这个js文件直接引用就行,简单使用代码如下 //代码1 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content=...
  • workbook: 可以理解为XLSX对excel文件描述的一个对象,可通过 XLSX.utils.book_new()来创建,该方法返回workbook对象 worksheet:可以理解为XLSX对 excel 中sheet的描述的一个对象,可通过 XLSX.utils.aoa_to_sheet...
  • 第一步 npm i xlsx 第二步 在vue中引入xlsx 第三部 编码 导入excel (博主在这里是通过点击button按钮触发input来达到上传的效果) 在这里我使用的是vue,如果没有使用vue,则直接绑定(this)即可 //html部分 &lt;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,339
精华内容 935
关键字:

jsxlsx