jExcel 創(chuàng)建基于 Web 的電子表格應用

jExcel 創(chuàng)建基于 Web 的電子表格應用

jExcel 是一個輕量級的vanilla javascript插件凳厢,用于創(chuàng)建與Excel或任何其他電子表格軟件兼容的基于Web的交互式表格和電子表格碘裕,可以創(chuàng)建可以交互的表格,兼容Excel埃篓,可以從 Js ArrayJSON袱蜡、CSV叙淌、XSLX文件創(chuàng)建表格『翰伲可以從Excel中直接復制再来,然后粘貼在jExcel表格中。而且可以定制化磷瘤,還可以結合第三方的庫使用芒篷,支持 ReactVue采缚、JQuery等针炉。

jexcel.gif

原文鏈接

安裝

  • 通過 npm安裝
npm install jexcel
  • 瀏覽器直接引用
 <script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
 <script src="https://bossanova.uk/jsuites/v2/jsuites.js"></script>
 <link rel="stylesheet"  type="text/css" />
 <link rel="stylesheet"  type="text/css" />

基本使用

需要先創(chuàng)建一個div的容器,來顯示表格

<div id="spreadsheet"></div>

需要在 script中初始化表格扳抽,這樣表格就會顯示出來了

var data = [
    ['Jazz', 'Honda', '2019-02-12', '', true, '$ 2.000,00', '#777700'],
    ['Civic', 'Honda', '2018-07-11', '', true, '$ 4.000,01', '#007777'],
];

jexcel(document.getElementById('spreadsheet'), {
    data:data,
    columns: [
        { type: 'text', title:'Car', width:120 },
        { type: 'dropdown', title:'Make', width:200, source:[ "Alfa Romeo", "Audi", "Bmw" ] },
        { type: 'calendar', title:'Available', width:200 },
        { type: 'image', title:'Photo', width:120 },
        { type: 'checkbox', title:'Stock', width:80 },
        { type: 'numeric', title:'Price', width:100, mask:'$ #.##,00', decimal:',' },
        { type: 'color', width:100, render:'square', }
     ]
});
微信截圖_20200907214625.png

React中使用

class Jexcel extends React.Component {
    constructor(props) {
        super(props);
        this.options = props.options;
        this.wrapper = React.createRef();
    }

    componentDidMount = function() {
        this.el = jexcel(this.wrapper.current, this.options);
    }

    addRow = function() {
        this.el.insertRow();
    }

    render() {
        return (
            <div>
                <div></div><br/><br/>
                <input type='button' value='Add new row' onClick={() => this.addRow()}></input>
            </div>
        );
    }
}

var options = {
    data:[[]],
    minDimensions:[10,10],
};

ReactDOM.render(<Jexcel options={options} />, document.getElementById('spreadsheet'))

Vue中使用

import jexcel from 'jexcel'
import 'jexcel/dist/jexcel.css'
var data = [
  ['Jazz', 'Honda', '2019-02-12', '', true, '$ 2.000,00', '#777700'],
  ['Civic', 'Honda', '2018-07-11', '', true, '$ 4.000,01', '#007777']
]
var options = {
  data: data,
  allowToolbar:true,
  columns: [
    { type: 'text', title: 'Car', width: '120px' },
    { type: 'dropdown', title: 'Make', width: '250px', source: [ 'Alfa Romeo', 'Audi', 'Bmw' ] },
    { type: 'calendar', title: 'Available', width: '250px' },
    { type: 'image', title: 'Photo', width: '120px' },
    { type: 'checkbox', title: 'Stock', width: '80px' },
    { type: 'numeric', title: 'Price', width: '100px', mask: '$ #.##,00', decimal: ',' },
    { type: 'color', width: '100px', render: 'square' }
  ]
}
export default {
  name: 'App',
  mounted: function () {
    let spreadsheet = jexcel(this.$el, options)
    Object.assign(this, { spreadsheet })
  }
}

加載數(shù)據(jù)

加載 javascript數(shù)組

<div id='my-spreadsheet'></div>

<script>
data = [
    ['Mazda', 2001, 2000],
    ['Pegeout', 2010, 5000],
    ['Honda Fit', 2009, 3000],
    ['Honda CRV', 2010, 6000],
];

jexcel(document.getElementById('my-spreadsheet'), {
    data:data,
    columns:[
        { title:'Model', width:300 },
        { title:'Price', width:80 },
        { title:'Model', width:100 }
    ]
});
</script>

加載 JSON文件

<div id='my-spreadsheet'></div>

<script>
jexcel(document.getElementById('my-spreadsheet'), {
    url:'data.json',
    columns:[
        { title:'Model', width:300 },
        { title:'Price', width:80 },
        { title:'Model', width:100 }
    ]
});
</script>

加載 CSV文件

<div id='my-spreadsheet'></div>

<script>
jexcel(document.getElementById('my-spreadsheet'), {
    csv:'demo.csv',
    csvHeaders:true,
    columns:[
        { width:300 },
        { width:80 },
        { width:100 }
    ]
});
</script>

銷毀表

<script>
var table = jexcel(document.getElementById('my-spreadsheet'), {
    csv:'demo.csv',
    csvHeaders:true,
    columns:[
        { width:300 },
        { width:80 },
        { width:100 }
    ]
});

// If second argument is true will destroy all handlers and you can't create any other instance.
jexcel.destroy(document.getElementById('my-spreadsheet'), true);
</script>

原文鏈接

支持的數(shù)據(jù)類型

原生支持以下數(shù)據(jù)類型

text
numeric
hidden
dropdown
autocomplete
checkbox
radio
calendar
image
color
html

<html>
<script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v3/jsuites.js"></script>
<link rel="stylesheet"  type="text/css" />
<link rel="stylesheet"  type="text/css" />

<div id="spreadsheet"></div>

<script>
var data = [
    ['Jazz', 'Honda', '2019-02-12', '', true, '$ 2.000,00', '#777700'],
    ['Civic', 'Honda', '2018-07-11', '', true, '$ 4.000,01', '#007777'],
];

jexcel(document.getElementById('spreadsheet'), {
    data:data,
    columns: [
        { type: 'text', title:'Car', width:120 },
        { type: 'dropdown', title:'Make', width:200, source:[ "Alfa Romeo", "Audi", "Bmw" ] },
        { type: 'calendar', title:'Available', width:200 },
        { type: 'image', title:'Photo', width:120 },
        { type: 'checkbox', title:'Stock', width:80 },
        { type: 'numeric', title:'Price', width:100, mask:'$ #.##,00', decimal:',' },
        { type: 'color', width:100, render:'square', }
     ]
});
</script>
</html>
image

可以定制其他的類型

如顯示時間的控件


微信截圖_20200907220335.png
<html>
<script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v3/jsuites.js"></script>
<link rel="stylesheet"  type="text/css" />
<link rel="stylesheet"  type="text/css" />

<link rel="stylesheet" type="text/css"  />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="http://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.js"></script>

<div id="custom"></div>

<script>
var data2 = [
    ['PHP', '14:00'],
    ['Javascript', '16:30'],
];

var customColumn = {
    // Methods
    closeEditor : function(cell, save) {
        var value = cell.children[0].value;
        cell.innerHTML = value;
        return value;
    },
    openEditor : function(cell) {
        // Create input
        var element = document.createElement('input');
        element.value = cell.innerHTML;
        // Update cell
        cell.classList.add('editor');
        cell.innerHTML = '';
        cell.appendChild(element);
        $(element).clockpicker({
            afterHide:function() {
                setTimeout(function() {
                    // To avoid double call
                    if (cell.children[0]) {
                        myTable.closeEditor(cell, true);
                    }
                });
            }
        });
        // Focus on the element
        element.focus();
    },
    getValue : function(cell) {
        return cell.innerHTML;
    },
    setValue : function(cell, value) {
        cell.innerHTML = value;
    }
}

myTable = jexcel(document.getElementById('custom'), {
    data:data2,
    columns: [
        { type: 'text', title:'Course Title', width:300 },
        { type: 'text', title:'Time', width:100, editor:customColumn },
     ]
});
</script>
</html>
  • 定制時的重點
 { type: 'text', title:'Time', width:100, editor:customColumn },
openEditor: function(cell) {
// 通過原生方法創(chuàng)建新的控件
}篡帕,
closeEditor : function(cell, save) {
// 關閉時,獲取對應的值信息
},

支持搜索和分頁

<html>
<script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v3/jsuites.js"></script>
<link rel="stylesheet"  type="text/css" />
<link rel="stylesheet"  type="text/css" />

<link rel="stylesheet"  type="text/css" />

<div id="spreadsheet"></div>

<script>
jexcel(document.getElementById('spreadsheet'), {
    csv:'https://bossanova.uk/jexcel/v4/demo.csv',
    csvHeaders:true,
    search:true,
    pagination:10,
    columns: [
        { type:'text', width:300 },
        { type:'text', width:200 },
        { type:'text', width:100 },
        { type:'text', width:100 },
        { type:'text', width:100 },
     ]
});
<script>

</script>
</html>
image

通過程序動態(tài)設置表格內容

增加贸呢、刪除行和列

<html>
<script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v3/jsuites.js"></script>
<link rel="stylesheet"  type="text/css" />
<link rel="stylesheet"  type="text/css" />

<div id="spreadsheet1"></div>

<script>
var data1 = [
    [ 'Cheese', 10, 1.10, '=B1*C1'],
    [ 'Apples', 30, 0.40, '=B2*C2'],
    [ 'Carrots', 15, 0.45, '=B3*C3'],
    [ 'Oranges', 20, 0.49, '=B4*C4'],
];

var table1 = jexcel(document.getElementById('spreadsheet1'), {
    data:data1,
    columns: [
        {
            title: 'Product',
            type: 'autocomplete',
            source:[ 'Apples','Bananas','Carrots','Oranges','Cheese','Pears' ],
            width:'300px',
        },
        {
            title: 'Quantity',
            type: 'number',
            width:'100px',
        },
        {
            title: 'Price',
            type: 'number',
            width:'100px',
        },
        {
            title: 'Total',
            type: 'number',
            width:'100px',
        },
    ],
    rowResize: true,
    columnDrag: true,
});
</script>

<br>

<ol class='example'>
    <li><a onclick="table1.insertColumn()">在表格末尾增加新的一列</a></li>
    <li><a onclick="table1.insertColumn(5, 0, 1, null);">在表格開頭增加5列空白表格</a></li>
    <li><a onclick="table1.insertColumn([ '0.99', '1.22', '3.11', '2.21' ]);">在表格末尾增加帶數(shù)據(jù)的列</a></li>
    <li><a onclick="table1.insertRow()">在末尾增加新的一行</a></li>
    <li><a onclick="table1.insertRow([ 'Pears', 10, 0.59, '=B2*C2' ], 1);">在第二行后增加新的帶數(shù)據(jù)的一行</a></li>
    <li><a onclick="table1.insertRow(10);">創(chuàng)建10行在表格末尾</a></li>
    <li><a onclick="table1.deleteRow(0, 1);">刪除第一行</a></li>
    <li><a onclick="table1.deleteColumn();">刪除最后一列</a></li>
    <li><a onclick="table1.moveRow(3, 0);">移動地四行到一行</a></li>
    <li><a onclick="table1.moveColumn(0, 2);">移動第一列到第三列的位置</a></li>
</ol>

</html>

支持的事件

<html>
<script src="https://bossanova.uk/jexcel/v4/jexcel.js"></script>
<script src="https://bossanova.uk/jsuites/v3/jsuites.js"></script>
<link rel="stylesheet"  type="text/css" />
<link rel="stylesheet"  type="text/css" />

<div id="spreadsheet"></div>

<script>
var changed = function(instance, cell, x, y, value) {
    var cellName = jexcel.getColumnNameFromId([x,y]);
    $('#log').append('New change on cell ' + cellName + ' to: ' + value + '
');
}

var beforeChange = function(instance, cell, x, y, value) {
    var cellName = jexcel.getColumnNameFromId([x,y]);
    $('#log').append('The cell ' + cellName + ' will be changed
');
}

var insertedRow = function(instance) {
    $('#log').append('Row added
');
}

var insertedColumn = function(instance) {
    $('#log').append('Column added
');
}

var deletedRow = function(instance) {
    $('#log').append('Row deleted
');
}

var deletedColumn = function(instance) {
    $('#log').append('Column deleted
');
}

var sort = function(instance, cellNum, order) {
    var order = (order) ? 'desc' : 'asc';
    $('#log').append('The column  ' + cellNum + ' sorted by ' + order + '
');
}

var resizeColumn = function(instance, cell, width) {
    $('#log').append('The column  ' + cell + ' resized to width ' + width + ' px
');
}

var resizeRow = function(instance, cell, height) {
    $('#log').append('The row  ' + cell + ' resized to height ' + height + ' px
');
}

var selectionActive = function(instance, x1, y1, x2, y2, origin) {
    var cellName1 = jexcel.getColumnNameFromId([x1, y1]);
    var cellName2 = jexcel.getColumnNameFromId([x2, y2]);
    $('#log').append('The selection from ' + cellName1 + ' to ' + cellName2 + '
');
}

var loaded = function(instance) {
    $('#log').append('New data is loaded
');
}

var moveRow = function(instance, from, to) {
    $('#log').append('The row ' + from + ' was move to the position of ' + to + ' 
');
}

var moveColumn = function(instance, from, to) {
    $('#log').append('The col ' + from + ' was move to the position of ' + to + ' 
');
}

var blur = function(instance) {
    $('#log').append('The table ' + $(instance).prop('id') + ' is blur
');
}

var focus = function(instance) {
    $('#log').append('The table ' + $(instance).prop('id') + ' is focus
');
}

var paste = function(data) {
    $('#log').append('Paste on the table ' + $(instance).prop('id') + '
');
}

var data = [
    ['Mazda', 2001, 2000, '2006-01-01'],
    ['Pegeout', 2010, 5000, '2005-01-01'],
    ['Honda Fit', 2009, 3000, '2004-01-01'],
    ['Honda CRV', 2010, 6000, '2003-01-01'],
];

jexcel(document.getElementById('spreadsheet'), {
    data:data,
    rowResize:true,
    columnDrag:true,
    columns: [
        { type: 'text', width:'200' },
        { type: 'text', width:'100' },
        { type: 'text', width:'100' },
        { type: 'calendar', width:'100' },
    ],
    onchange: changed,
    onbeforechange: beforeChange,
    oninsertrow: insertedRow,
    oninsertcolumn: insertedColumn,
    ondeleterow: deletedRow,
    ondeletecolumn: deletedColumn,
    onselection: selectionActive,
    onsort: sort,
    onresizerow: resizeRow,
    onresizecolumn: resizeColumn,
    onmoverow: moveRow,
    onmovecolumn: moveColumn,
    onload: loaded,
    onblur: blur,
    onfocus: focus,
    onpaste: paste,
});
</script>
</html>

完整的事件列表
原文鏈接

支持右鍵

支持嵌套表頭

支持懶加載

支持凍結列

支持列排序

支持列過濾

支持定制化的工具欄

支持定制化樣式

支持定制化公式

支持拖拽

...
更多新特性值得你繼續(xù)探索

原文鏈接

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末镰烧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贮尉,更是在濱河造成了極大的恐慌拌滋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猜谚,死亡現(xiàn)場離奇詭異败砂,居然都是意外死亡赌渣,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門昌犹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坚芜,“玉大人,你說我怎么就攤上這事斜姥『枋” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵铸敏,是天一觀的道長缚忧。 經常有香客問我,道長杈笔,這世上最難降的妖魔是什么闪水? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蒙具,結果婚禮上球榆,老公的妹妹穿的比我還像新娘。我一直安慰自己禁筏,他們只是感情好持钉,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著篱昔,像睡著了一般每强。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旱爆,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天舀射,我揣著相機與錄音,去河邊找鬼怀伦。 笑死脆烟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的房待。 我是一名探鬼主播邢羔,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼桑孩!你這毒婦竟也來了拜鹤?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤流椒,失蹤者是張志新(化名)和其女友劉穎敏簿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡惯裕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年温数,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜻势。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡撑刺,死狀恐怖,靈堂內的尸體忽然破棺而出握玛,到底是詐尸還是另有隱情够傍,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布挠铲,位于F島的核電站冕屯,受9級特大地震影響,放射性物質發(fā)生泄漏市殷。R本人自食惡果不足惜愕撰,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望醋寝。 院中可真熱鬧,春花似錦带迟、人聲如沸音羞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗅绰。三九已至,卻和暖如春搀继,著一層夾襖步出監(jiān)牢的瞬間窘面,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工叽躯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留财边,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓点骑,卻偏偏與公主長得像酣难,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子黑滴,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345