@ -0,0 +1,5 @@ |
|||
.DS_Store |
|||
node_modules |
|||
package-lock.json |
|||
dist |
|||
docs/.vuepress/dist |
|||
@ -0,0 +1,103 @@ |
|||
# Luckysheet |
|||
|
|||
## Introduction - 介绍 |
|||
Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 |
|||
|
|||
## Features - 特性 |
|||
1. Luckysheet支持表格设置包括冻结行列、合并单元格、筛选、排序、查询、条件格式、批注 |
|||
2. 支持数据分析功能包括透视表、图表、分列、矩阵操作、内置385个计算函数 |
|||
3. 支持一键截图、复制为json数据、共享编辑、excel与Luckysheet之间数据的复制粘贴 |
|||
4. 支持移动端查看 |
|||
5. 支持sparkLine |
|||
 |
|||
|
|||
## Plan - 计划 |
|||
- 模块化(进行中) |
|||
- excel导入/导出 |
|||
- 表单 |
|||
- 插入图片 |
|||
- 更多... |
|||
|
|||
## Documentation - 文档 |
|||
[在线demo](https://mengshukeji.github.io/LuckysheetDemo/) |
|||
|
|||
[在线文档](https://mengshukeji.github.io/LuckysheetDocs/) |
|||
|
|||
## Requirements - 环境 |
|||
[Node.js](https://nodejs.org/en/) Version >= 6 |
|||
|
|||
## Installation - 安装 |
|||
``` |
|||
npm install |
|||
npm install gulp -g |
|||
``` |
|||
|
|||
## Development - 开发 |
|||
开发 |
|||
``` |
|||
npm run dev |
|||
``` |
|||
打包 |
|||
``` |
|||
npm run build |
|||
``` |
|||
阅读 |
|||
|
|||
Luckysheet的核心代码为luckysheet-core.js和luckysheet-function.js,开发者看源码只需要看这两个文件即可,接下来会讨论进行模块化方案,完善这个插件. |
|||
|
|||
## Usage - 用法 |
|||
|
|||
#### 第一步 |
|||
npm run build后dist文件夹下的所有文件复制到项目目录 |
|||
|
|||
#### 第二步 |
|||
引入依赖 |
|||
``` |
|||
<link rel="stylesheet" href="plugins/css/pluginsCss.min.css"> |
|||
<link rel="stylesheet" href="plugins/plugins.min.css"> |
|||
<link rel="stylesheet" href="css/main.min.css"> |
|||
<script src="plugins/js/plugin.min.js"></script> |
|||
<script src="main.min.js"></script> |
|||
``` |
|||
#### 第三步 |
|||
指定一个表格容器 |
|||
``` |
|||
<div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;height:100%;left: 0px;top: 0px;"></div> |
|||
``` |
|||
#### 第四步 |
|||
创建一个表格 |
|||
``` |
|||
<script> |
|||
$(function () { |
|||
//配置项 |
|||
var options = { |
|||
container: 'luckysheet' //luckysheet为容器id |
|||
} |
|||
luckysheet.create(options) |
|||
}) |
|||
</script> |
|||
``` |
|||
|
|||
## Contact - 联系 |
|||
mengshu@office2.cn |
|||
|
|||
## communication - 交流 |
|||
|
|||
- 添加小编微信,拉你进Luckysheet开发者交流微信群,备注:加群 |
|||
|
|||
<img src="https://minio.cnbabylon.com/public/luckysheet/%E5%BE%AE%E4%BF%A1%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg" width = "200" alt="微信群" align="center" /> |
|||
|
|||
或者 |
|||
|
|||
- 加入Luckysheet开发者交流QQ群 |
|||
|
|||
<img src="https://minio.cnbabylon.com/public/luckysheet/QQ%E7%BE%A4%E4%BA%8C%E7%BB%B4%E7%A0%81.jpg" width = "200" alt="微信群" align="center" /> |
|||
|
|||
## Authors and acknowledgment - 贡献者和感谢 |
|||
- Bug Pan ([@wpxp123456](https://github.com/wpxp123456)) |
|||
- Dushusir ([@Dushusir](https://github.com/Dushusir)) |
|||
|
|||
## License - 版权信息 |
|||
[MIT](http://opensource.org/licenses/MIT) |
|||
|
|||
Copyright (c) 2020-present, mengshukeji |
|||
@ -0,0 +1,34 @@ |
|||
module.exports = { |
|||
title: 'Luckysheet文档', |
|||
description: 'Luckysheet 配置文档/API/教程', |
|||
base: '/LuckysheetDocs/', |
|||
themeConfig: { |
|||
logo: '/img/logo.png', |
|||
// 页面滚动
|
|||
smoothScroll: true, |
|||
// 导航栏
|
|||
nav: [ |
|||
{ text: '首页', link: '/' }, |
|||
{ text: '指南', link: '/guide/' }, |
|||
{ text: '演示', link: 'https://mengshukeji.github.io/LuckysheetDemo/' }, |
|||
{ text: 'Github', link: 'https://github.com/mengshukeji/Luckysheet' }, |
|||
], |
|||
// 侧边栏
|
|||
sidebar: { |
|||
'/guide/': [ |
|||
'', |
|||
'config', |
|||
'feature', |
|||
'data', |
|||
'operate', |
|||
'format' |
|||
], |
|||
}, |
|||
// 仓库地址
|
|||
repo: 'mengshukeji/Luckysheet', |
|||
// 仓库链接文字
|
|||
repoLabel: '在 GitHub 上编辑此页', |
|||
// 仓库的文档目录
|
|||
docsDir: 'docs', |
|||
}, |
|||
} |
|||
|
After Width: | Height: | Size: 6.2 KiB |
@ -0,0 +1,15 @@ |
|||
--- |
|||
home: true |
|||
heroText: Luckysheet |
|||
tagline: Luckysheet 配置文档/API/教程 |
|||
actionText: 快速上手 → |
|||
actionLink: /guide/ |
|||
features: |
|||
- title: 功能强大 |
|||
details: 包含大量常用电子表格功能,替代你的excel |
|||
- title: 配置简单 |
|||
details: 最少的配置就能开始上手使用 |
|||
- title: 完全开源 |
|||
details: 社区驱动,共同来完善你的想法 |
|||
footer: MIT Licensed | Copyright © 2020-present Mengshukeji |
|||
--- |
|||
@ -0,0 +1,123 @@ |
|||
# 快速上手 |
|||
|
|||
## 基本介绍 |
|||
Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 |
|||
|
|||
### 特性 |
|||
1. Luckysheet支持表格设置包括冻结行列、合并单元格、筛选、排序、查询、条件格式、批注 |
|||
2. 支持数据分析功能包括透视表、分列、矩阵操作、内置385个计算函数 |
|||
3. 支持一键截图、复制为json数据、共享编辑、excel与Luckysheet之间数据的复制粘贴 |
|||
4. 支持移动端查看 |
|||
|
|||
 |
|||
|
|||
|
|||
### Demo |
|||
[在线demo](https://mengshukeji.github.io/LuckysheetDemo/) |
|||
|
|||
## 开发模式 |
|||
|
|||
### 环境 |
|||
[Node.js](https://nodejs.org/en/) Version >= 6 |
|||
|
|||
### 安装 |
|||
```shell |
|||
npm install |
|||
npm install gulp -g |
|||
``` |
|||
|
|||
### 开发 |
|||
```shell |
|||
npm run dev |
|||
``` |
|||
|
|||
### 打包 |
|||
```shell |
|||
npm run build |
|||
``` |
|||
|
|||
## 使用步骤 |
|||
|
|||
### 第一步 |
|||
npm run build后dist文件夹下的所有文件复制到项目目录 |
|||
|
|||
### 第二步 |
|||
引入依赖 |
|||
```html |
|||
<link rel="stylesheet" href="plugins/css/pluginsCss.min.css"> |
|||
<link rel="stylesheet" href="plugins/plugins.min.css"> |
|||
<link rel="stylesheet" href="css/main.min.css"> |
|||
<script src="plugins/js/plugin.min.js"></script> |
|||
<script src="main.min.js"></script> |
|||
``` |
|||
### 第三步 |
|||
指定一个表格容器 |
|||
```html |
|||
<div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;height:100%;left: 0px;top: 0px;"></div> |
|||
``` |
|||
### 第四步 |
|||
创建一个表格 |
|||
```javascript |
|||
<script> |
|||
$(function () { |
|||
//配置项 |
|||
var options = { |
|||
container: 'luckysheet' //luckysheet为容器id |
|||
} |
|||
luckysheet.create(options) |
|||
}) |
|||
</script> |
|||
``` |
|||
|
|||
## 整体结构 |
|||
|
|||
### 格式 |
|||
|
|||
一个完整的Luckysheet表格文件的数据格式为:luckysheetfile,一个表格表格文件包含若干个sheet文件,对应excel的sheet0、sheet1等。 |
|||
|
|||
一个Luckysheet文件的示例如下,该表格包含3个sheet:` |
|||
luckysheetfile = [ {sheet1设置}, {sheet2设置}, {sheet3设置} ]` |
|||
相当于excel的3个sheet |
|||
|
|||
 |
|||
|
|||
文件中的一个sheet的示例如下: |
|||
```javascript |
|||
luckysheetfile[0] = |
|||
{ |
|||
"name": "超市销售额", |
|||
"color": "", |
|||
"chart": [], |
|||
"status": 0, |
|||
"order": 0, |
|||
"celldata": [], |
|||
"row":90, |
|||
"column":100, |
|||
"index": 0, |
|||
"visibledatarow": [], |
|||
"visibledatacolumn": [], |
|||
"rowsplit": [], |
|||
"ch_width": 4629, |
|||
"rh_height": 1681, |
|||
"luckysheet_select_save": {}, |
|||
"luckysheet_selection_range": {}, |
|||
"scrollLeft": 0, |
|||
"scrollTop": 0, |
|||
"load": "1", |
|||
"config": { |
|||
"columlen": {}, |
|||
"rowhidden": {} |
|||
} |
|||
, |
|||
"pivotTable": {}, |
|||
"isPivotTable": true, |
|||
"calcChain": [], |
|||
"filter":{key1:value1, key2:value2}, |
|||
"filter_select": {} |
|||
} |
|||
``` |
|||
### 查看方式 |
|||
在chrome的console中查看 |
|||
`luckysheet.getluckysheetfile()` |
|||
可以看到完整设置 |
|||
[{shee1}, {sheet2}, {sheet3}] |
|||
@ -0,0 +1,232 @@ |
|||
# 基本配置 |
|||
|
|||
## container |
|||
- 类型:String |
|||
- 默认值:"luckysheet" |
|||
- 作用:容器的ID |
|||
|
|||
------------ |
|||
## title |
|||
- 类型:String |
|||
- 默认值:"Luckysheet Demo" |
|||
- 作用:表格的名称 |
|||
|
|||
------------ |
|||
## column |
|||
- 类型:Number |
|||
- 默认值:60 |
|||
- 作用:空表格默认的列数量 |
|||
|
|||
------------ |
|||
## row |
|||
- 类型:Number |
|||
- 默认值:84 |
|||
- 作用:空表格默认的行数据量 |
|||
|
|||
------------ |
|||
## data |
|||
- 类型:Array |
|||
- 默认值:[{ "name": "Sheet1", color: "", "status": "1", "order": "0", "data": [], "config": {}, "index":0 }, { "name": "Sheet2", color: "", "status": "0", "order": "1", "data": [], "config": {}, "index":1 }, { "name": "Sheet3", color: "", "status": "0", "order": "2", "data": [], "config": {}, "index":2 }] |
|||
- 作用:客户端sheet数据[shee1, sheet2, sheet3] |
|||
|
|||
------------ |
|||
|
|||
## fullscreenmode |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否全屏模式,非全屏模式下,标记框不会强制选中。 |
|||
|
|||
------------ |
|||
## autoFormatw |
|||
- 类型:Boolean |
|||
- 默认值:false |
|||
- 作用:自动格式化超过4位数的数字为 亿万格式 例:true or "true" or "TRUE" |
|||
|
|||
------------ |
|||
## accuracy |
|||
- 类型:Number |
|||
- 默认值:undefined |
|||
- 作用:设置传输来的数值的精确位数,小数点后n位 传参数为数字或数字字符串,例: "0" 或 0 |
|||
|
|||
------------ |
|||
## allowCopy |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否允许拷贝 |
|||
|
|||
------------ |
|||
## showtoolbar |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否第二列显示工具栏 |
|||
|
|||
------------ |
|||
## showinfobar |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否显示顶部名称栏 |
|||
|
|||
------------ |
|||
## showsheetbar |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否显示底部表格名称区域 |
|||
|
|||
------------ |
|||
|
|||
## showstatisticBar |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否显示底部计数栏 |
|||
|
|||
------------ |
|||
## editMode |
|||
- 类型:Boolean |
|||
- 默认值:false |
|||
- 作用:是否为编辑模式 |
|||
|
|||
------------ |
|||
## allowEdit |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:是否允许前台编辑 |
|||
|
|||
------------ |
|||
## enableAddRow |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:允许增加行 |
|||
|
|||
------------ |
|||
## enableAddCol |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:允许增加列 |
|||
|
|||
------------ |
|||
## pointEdit |
|||
- 类型:Boolean |
|||
- 默认值:false |
|||
- 作用:是否是编辑器插入表格模式 |
|||
|
|||
------------ |
|||
## pointEditUpdate |
|||
- 类型:Function |
|||
- 默认值:null |
|||
- 作用:编辑器表格更新函数 |
|||
|
|||
------------ |
|||
## pointEditZoom |
|||
- 类型:Number |
|||
- 默认值:1 |
|||
- 作用:编辑器表格编辑时缩放比例 |
|||
|
|||
------------ |
|||
## pointEditZoom |
|||
- 类型:Number |
|||
- 默认值:1 |
|||
- 作用:编辑器表格编辑时缩放比例 |
|||
|
|||
------------ |
|||
## userInfo |
|||
- 类型:String |
|||
- 默认值:`'<i style="font-size:16px;color:#ff6a00;" class="fa fa-taxi" aria-hidden="true"></i> rabbit'` |
|||
- 作用:右上角的用户信息展示样式 |
|||
|
|||
------------ |
|||
## userMenuItem |
|||
- 类型:Array |
|||
- 默认值:`[{url:"www.baidu.com", "icon":'<i class="fa fa-folder" aria-hidden="true"></i>', "name":"我的表格"}, {url:"www.baidu.com", "icon":'<i class="fa fa-sign-out" aria-hidden="true"></i>', "name":"退出登陆"}]` |
|||
- 作用:点击右上角的用户信息弹出的菜单 |
|||
|
|||
------------ |
|||
## myFolderUrl |
|||
- 类型:String |
|||
- 默认值:"www.baidu.com" |
|||
- 作用:左上角<返回按钮的链接 |
|||
|
|||
------------ |
|||
## config |
|||
- 类型:Object |
|||
- 默认值:{} |
|||
- 作用:表格行高、列宽、合并单元格、公式等设置 |
|||
|
|||
------------ |
|||
## devicePixelRatio |
|||
- 类型:Number |
|||
- 默认值:window.devicePixelRatio |
|||
- 作用:设备比例,比例越大表格分标率越高 |
|||
|
|||
------------ |
|||
## gridKey |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:表格唯一标识符 |
|||
|
|||
------------ |
|||
## loadUrl |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:配置loadUrl的地址,luckysheet会通过ajax请求表格数据,默认载入status为1的sheet数据中的所有data,其余的sheet载入除data字段外的所有字段 |
|||
|
|||
------------ |
|||
## loadSheetUrl |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:配置loadSheetUrl的地址,参数为gridKey(表格主键) 和 index(sheet主键合集,格式为[1,2,3]),返回的数据为sheet的data字段数据集合 |
|||
|
|||
------------ |
|||
## updateUrl |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:表格数据的更新地址 |
|||
|
|||
------------ |
|||
## updateImageUrl |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:缩略图的更新地址 |
|||
|
|||
------------ |
|||
## allowUpdate |
|||
- 类型:Boolean |
|||
- 默认值:false |
|||
- 作用:是否允许编辑后的后台更新 |
|||
|
|||
------------ |
|||
## functionButton |
|||
- 类型:String |
|||
- 默认值:"" |
|||
- 作用:右上角功能按钮,例如`'<button id="" class="btn btn-primary" style="padding:3px 6px;font-size: 12px;margin-right: 10px;">下载</button> <button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 10px;">分享</button> <button id="luckysheet-share-btn-title" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 10px;">秀数据</button>'` |
|||
|
|||
------------ |
|||
## showConfigWindowResize |
|||
- 类型:Boolean |
|||
- 默认值:true |
|||
- 作用:图表和数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进 |
|||
|
|||
------------ |
|||
## enablePage |
|||
- 类型:Boolean |
|||
- 默认值:false |
|||
- 作用:允许加载下一页 |
|||
|
|||
------------ |
|||
## chartConfigChange |
|||
- 类型:Function |
|||
- 默认值:null |
|||
- 作用:图表插件中图表更新触发的自定义方法 |
|||
|
|||
------------ |
|||
## beforeCreateDom |
|||
- 类型:Function |
|||
- 默认值:null |
|||
- 作用:表格创建之前自定义方法 |
|||
|
|||
------------ |
|||
## fireMousedown |
|||
- 类型:Function |
|||
- 默认值:null |
|||
- 作用:单元格数据下钻自定义方法 |
|||
|
|||
------------ |
|||
@ -0,0 +1,92 @@ |
|||
# 表格数据 |
|||
|
|||
## 获取表格数据 |
|||
|
|||
- **配置**: |
|||
|
|||
配置 `updateUrl` 的地址,Luckysheet会通过ajax请求表格数据,默认载入status为1的sheet数据中的所有data,其余的sheet载入除data字段外的所有字段。 |
|||
|
|||
- **格式**: |
|||
|
|||
luckysheetfile示例如下: |
|||
```json |
|||
[ |
|||
{ |
|||
"name": "Sheet1", |
|||
"color": "", |
|||
"status": "1", |
|||
"order": "0", |
|||
"celldata": [], |
|||
"config": {}, |
|||
"index": 0 |
|||
}, |
|||
{ |
|||
"name": "Sheet2", |
|||
"color": "", |
|||
"status": "0", |
|||
"order": "1", |
|||
"data": [], |
|||
"config": {}, |
|||
"index": 1 |
|||
}, |
|||
{ |
|||
"name": "Sheet3", |
|||
"color": "", |
|||
"status": "0", |
|||
"order": "2", |
|||
"data": [], |
|||
"config": {}, |
|||
"index": 2 |
|||
} |
|||
] |
|||
``` |
|||
|
|||
## 获取sheet数据 |
|||
|
|||
- **配置**: |
|||
|
|||
配置 `loadSheetUrl` 的地址,参数为gridKey(表格主键) 和 index(sheet主键合集,格式为[1,2,3]),返回的数据为sheet的data字段数据集合 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"1": [{r:0, c:1, v:"值1"},{r:10, c:11, v:"值2"}], |
|||
"2": [data], |
|||
"3": [data], |
|||
} |
|||
``` |
|||
- **说明**: |
|||
|
|||
r代表行,c代表列,v代表该单元格的值,值可以是字符、数字或者json串。 |
|||
数据只会载入一次,一般来说都只有一个主键,但是考虑到一些公式、图表及数据透视表会引用其他sheet的数据,所以前台会加一个判断,如果该当前sheet引用了其他sheet的数据则把引用到的sheet的数据一并补全。 |
|||
|
|||
## 获取range范围数据 |
|||
|
|||
- **配置**: |
|||
|
|||
配置 `loadCellUrl` 的地址,参数为gridKey(表格主键) 、 index(sheet主键)、开始行、结束行、开始列、结束列。后台根据范围获取指定的celldata数据并返回。 |
|||
|
|||
## 更新数据 |
|||
|
|||
- **配置**: |
|||
|
|||
配置 `updateUrl` 的地址,发送到后台的参数为json的字符串。 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
compress: false, |
|||
gridKey:10004, |
|||
data: [更新数据] |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
| 参数 | 说明 | 举例 | |
|||
| ------------ | ------------ | ------------ | |
|||
| compress | Luckysheet采用客户端pako进行zlib参数压缩,如果浏览器支持压缩则为true,否则为false。后台可以根据此参数决定是否解压data中的内容 | 服务端获取参数过程:1. 序列化json字符串 2判断compress字段如果为TRUE则解压data字段 3. 解码data字符串URLDecoder.decode(utf-8) | |
|||
| gridKey | Luckysheet文件的标识符 | 无 | |
|||
| data | 一个包含更新数据的数组,数组中的参数格式请看下面的介绍。实例中:t表示更新类型、i为sheet的索引、c为行号、r为列号,v为值 | data: [{ t : 'cell', i:0, c : 0, r : 0 , v: 2 }] | |
|||
@ -0,0 +1,124 @@ |
|||
# 高级功能 |
|||
|
|||
## luckysheet.getcellvalue(r, c, data, type) |
|||
- **参数**: |
|||
- r:单元格所在行数;可选值;从0开始的整数,0表示第一行。 |
|||
- c:单元格所在列数;可选值;从0开始的整数,0表示第一列。 |
|||
- data:表数据;二维数组;默认值为当前表格数据。 |
|||
- type:单元格属性值;可选值;默认值为'v',表示获取单元格的值。 |
|||
- **用法**: |
|||
|
|||
此方法为获取单元格的值。r, c都没有值时,返回data;r, c只有一个有值时,返回整行或整列数据; |
|||
|
|||
------------ |
|||
## luckysheet.getluckysheetfile() |
|||
- **用法**: |
|||
|
|||
返回所有表格数据结构。 |
|||
|
|||
------------ |
|||
## luckysheet.sheetmanage.getSheetByIndex(index) |
|||
- **参数**: |
|||
- index:表格下标;从0开始的整数,0表示第一个表格;默认为当前表格下标。 |
|||
- **用法**: |
|||
|
|||
返回某个表格数据结构。 |
|||
|
|||
------------ |
|||
## luckysheet.getconfig() |
|||
- **用法**: |
|||
|
|||
返回当前表格config配置。 |
|||
|
|||
------------ |
|||
## luckysheet.getSheetConfig(sheetIndex) |
|||
- **参数**: |
|||
- sheetIndex:表格下标;从0开始的整数,0表示第一个表格;默认为当前表格下标。 |
|||
- **用法**: |
|||
|
|||
返回某个表格config配置。 |
|||
|
|||
------------ |
|||
## luckysheet.getvisibledatarow() |
|||
- **用法**: |
|||
|
|||
返回当前表格行高。 |
|||
|
|||
------------ |
|||
## luckysheet.getvisibledatacolumn() |
|||
- **用法**: |
|||
|
|||
返回当前表格列宽。 |
|||
|
|||
------------ |
|||
## luckysheet.getluckysheet_select_save() |
|||
- **用法**: |
|||
|
|||
返回当前选区。 |
|||
|
|||
------------ |
|||
## luckysheet.getdatabyselection(range, sheetIndex) |
|||
- **参数**: |
|||
- range:选区对象;object: { row: [r1, r2], column: [c1, c2] };默认为当前选区。 |
|||
- sheetIndex:表格下标;从0开始的整数,0表示第一个表格;默认为当前表格下标。 |
|||
- **用法**: |
|||
|
|||
返回某个表格某个区域单元格数据。 |
|||
|
|||
------------ |
|||
## luckysheet.luckysheetrefreshgrid(scrollWidth, scrollHeight) |
|||
- **参数**: |
|||
- scrollWidth:横向滚动值。默认为当前横向滚动位置。 |
|||
- scrollHeight:纵向滚动值。默认为当前纵向滚动位置。 |
|||
- **用法**: |
|||
|
|||
按照scrollWidth, scrollHeight刷新canvas展示数据。 |
|||
|
|||
------------ |
|||
## luckysheet.setcellvalue(r, c, d, v) |
|||
- **参数**: |
|||
- r:单元格所在行数;从0开始的整数,0表示第一行。 |
|||
- c:单元格所在列数;从0开始的整数,0表示第一列。 |
|||
- d:表数据;二维数组。 |
|||
- v:要设置的值;可为对象,对象是是要符合单元格对象格式。 |
|||
- **用法**: |
|||
|
|||
设置某个单元格的值。可配合luckysheet.luckysheetrefreshgrid()刷新查看单元格值改变。 |
|||
```js |
|||
luckysheet.setcellvalue(0, 0, luckysheet.flowdata, 'abc'); |
|||
luckysheet.luckysheetrefreshgrid(); |
|||
``` |
|||
|
|||
------------ |
|||
## luckysheet.setluckysheet_select_save(v) |
|||
- **参数**: |
|||
- v:要设置的选区值(数组)。符合选区格式规则,如[{ row: [r1, r2], column: [c1, c2] }]。 |
|||
- **用法**: |
|||
|
|||
设置当前表格选区的值。配合luckysheet.selectHightlightShow()可在界面查看选区改变。 |
|||
```js |
|||
luckysheet.setluckysheet_select_save([{ row: [0, 1], column: [0, 1] }]); |
|||
luckysheet.selectHightlightShow(); |
|||
``` |
|||
|
|||
------------ |
|||
## luckysheet.sheetmanage.setSheetHide(index) |
|||
- **参数**: |
|||
- index:表格下标;从0开始的整数,0表示第一个表格;默认为当前表格下标。 |
|||
- **用法**: |
|||
|
|||
隐藏某个表格。 |
|||
|
|||
------------ |
|||
## luckysheet.sheetmanage.setSheetShow(index) |
|||
- **参数**: |
|||
- index:表格下标;从0开始的整数,0表示第一个表格;默认为当前表格下标。 |
|||
- **用法**: |
|||
|
|||
显示某个表格。 |
|||
|
|||
------------ |
|||
## luckysheet.method.destroy() |
|||
- **用法**: |
|||
|
|||
释放表格 |
|||
@ -0,0 +1,316 @@ |
|||
# 格式属性 |
|||
|
|||
## 单元格属性表 |
|||
|
|||
<table> |
|||
<tr> |
|||
<td>属性值</td> |
|||
<td>全称</td> |
|||
<td><div style="width:100px">说明</div></td> |
|||
<td>值示例</td> |
|||
<td>Aspose方法或者属性</td> |
|||
</tr> |
|||
<tr> |
|||
<td>ct</td> |
|||
<td>celltype</td> |
|||
<td>单元格值格式:文本、时间等</td> |
|||
<td><a href="#cellStyle">单元格格式</a></td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bg</td> |
|||
<td>background</td> |
|||
<td>背景颜色</td> |
|||
<td>#fff000</td> |
|||
<td>setBackgroundColor</td> |
|||
</tr> |
|||
<tr> |
|||
<td>ff</td> |
|||
<td>fontfamily</td> |
|||
<td>字体</td> |
|||
<td>0 微软雅黑、1 宋体(Song)、2 黑体(ST Heiti)、3 楷体(ST Kaiti)、 4仿宋(ST FangSong)、 5 新宋体(ST Song)、 6 华文新魏、 7华文行楷、 8 华文隶书、 9 Arial、 10 Times New Roman 、11 Tahoma 、12 Verdana</td> |
|||
<td>Style.Font object's Name property.</td> |
|||
</tr> |
|||
<tr> |
|||
<td>fc</td> |
|||
<td>fontcolor</td> |
|||
<td>字体颜色</td> |
|||
<td>#fff000</td> |
|||
<td>Style.Font object's Color property</td> |
|||
</tr> |
|||
<tr> |
|||
<td>bl</td> |
|||
<td>bold</td> |
|||
<td>粗体</td> |
|||
<td>0 常规 、 1加粗</td> |
|||
<td>Style.Font object's IsBold property to true.</td> |
|||
</tr> |
|||
<tr> |
|||
<td>it</td> |
|||
<td>italic</td> |
|||
<td>斜体</td> |
|||
<td>0 常规 、 1 斜体</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>fs</td> |
|||
<td>fontsize</td> |
|||
<td>字体大小</td> |
|||
<td>14</td> |
|||
<td>Style.Font object's Size property.</td> |
|||
</tr> |
|||
<tr> |
|||
<td>cl</td> |
|||
<td>cancelline</td> |
|||
<td>删除线</td> |
|||
<td>0 常规 、 1 删除线</td> |
|||
<td rowspan="2">Style.Font object's Underline property</td> |
|||
</tr> |
|||
<tr> |
|||
<td>ul</td> |
|||
<td>underline</td> |
|||
<td>下划线</td> |
|||
<td>0 常规 、 1 下划线</td> |
|||
</tr> |
|||
<tr> |
|||
<td rowspan="14">bs</td> |
|||
<td rowspan="14">borderstyle</td> |
|||
<td rowspan="14">边框样式</td> |
|||
<td>0 none</td> |
|||
<td rowspan="14">LineStyle</td> |
|||
</tr> |
|||
<tr> |
|||
<td>1 Thin</td> |
|||
</tr> |
|||
<tr> |
|||
<td>2 Hair</td> |
|||
</tr> |
|||
<tr> |
|||
<td>3 Dotted</td> |
|||
</tr> |
|||
<tr> |
|||
<td>4 Dashed</td> |
|||
</tr> |
|||
<tr> |
|||
<td>5 DashDot</td> |
|||
</tr> |
|||
<tr> |
|||
<td>6 DashDotDot</td> |
|||
</tr> |
|||
<tr> |
|||
<td>7 Double</td> |
|||
</tr> |
|||
<tr> |
|||
<td>8 Medium</td> |
|||
</tr> |
|||
<tr> |
|||
<td>9 MediumDashed</td> |
|||
</tr> |
|||
<tr> |
|||
<td>10 MediumDashDot</td> |
|||
</tr> |
|||
<tr> |
|||
<td>11 MediumDashDotDot</td> |
|||
</tr> |
|||
<tr> |
|||
<td>12 SlantedDashDot</td> |
|||
</tr> |
|||
<tr> |
|||
<td>13 Thick</td> |
|||
</tr> |
|||
<tr> |
|||
<td>bc</td> |
|||
<td>bordercolor</td> |
|||
<td>边框颜色</td> |
|||
<td>#fff000</td> |
|||
<td>setBorderColor</td> |
|||
</tr> |
|||
<tr> |
|||
<td>bs_t</td> |
|||
<td>borderstyleTop</td> |
|||
<td>上边框样式</td> |
|||
<td rowspan="8">同上</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bc_t</td> |
|||
<td>bordercolorTop</td> |
|||
<td>上边框颜色</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bs_b</td> |
|||
<td>borderstyleBottom</td> |
|||
<td>下边框样式</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bc_b</td> |
|||
<td>bordercolorBottom</td> |
|||
<td>下边框颜色</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bs_l</td> |
|||
<td>borderstyleLeft</td> |
|||
<td>左边框样式</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bc_l</td> |
|||
<td>bordercolorLeft</td> |
|||
<td>左边框颜色</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bs_r</td> |
|||
<td>borderstyleRight</td> |
|||
<td>右边框样式</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>bc_r</td> |
|||
<td>bordercolorRight</td> |
|||
<td>右边框颜色</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>vt</td> |
|||
<td>verticaltype</td> |
|||
<td>垂直对齐</td> |
|||
<td>0 中间、1 上、2下</td> |
|||
<td>setVerticalAlignment</td> |
|||
</tr> |
|||
<tr> |
|||
<td>ht</td> |
|||
<td>horizontaltype</td> |
|||
<td>水平对齐</td> |
|||
<td>0 居中、1 左、2右</td> |
|||
<td>setHorizontalAlignment</td> |
|||
</tr> |
|||
<tr> |
|||
<td>mc</td> |
|||
<td>mergecell</td> |
|||
<td>合并单元格</td> |
|||
<td>{ rs: 10, cs:5 } 表示从此cell开始到10行5列的cell进行合并。</td> |
|||
<td>Merge</td> |
|||
</tr> |
|||
<tr> |
|||
<td>tr</td> |
|||
<td>textrotate</td> |
|||
<td>文字旋转</td> |
|||
<td>0: 0、1: 45 、2:-45、3 竖排文字、4: 90 、5:-90</td> |
|||
<td>setRotationAngle</td> |
|||
</tr> |
|||
<tr> |
|||
<td>fl</td> |
|||
<td>floatlenght</td> |
|||
<td>小数位数</td> |
|||
<td>3</td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>tb</td> |
|||
<td>textbeak</td> |
|||
<td>文本换行</td> |
|||
<td>0 截断、1溢出、2 自动换行</td> |
|||
<td>2:setTextWrapped <br> 0和1:IsTextWrapped = true</td> |
|||
</tr> |
|||
<tr> |
|||
<td>ov</td> |
|||
<td>originvalue</td> |
|||
<td>原始值</td> |
|||
<td></td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>v</td> |
|||
<td>value</td> |
|||
<td>显示值</td> |
|||
<td></td> |
|||
<td></td> |
|||
</tr> |
|||
<tr> |
|||
<td>f</td> |
|||
<td>function</td> |
|||
<td>公式</td> |
|||
<td></td> |
|||
<td>setFormula <br> setArrayFormula <br> workbook.calculateFormula();</td> |
|||
</tr> |
|||
</table> |
|||
|
|||
|
|||
以下为3个单元格存储: |
|||
```json |
|||
[ |
|||
{r:0, c:1, v: { v:"显示", f:"=SUM(A2)", bg:"#fff000", bs:"1",bc:"#000"}}, |
|||
{r:10, c:11, v:"值2"}, |
|||
{r:10, c:11, v:{f:"=sum", v:"100"}} |
|||
] |
|||
``` |
|||
|
|||
## <div id='cellStyle'>单元格格式</div> |
|||
|
|||
参考[Aspose.Cells](https://docs.aspose.com/display/cellsnet/List+of+Supported+Number+Formats#ListofSupportedNumberFormats-Aspose.Cells) |
|||
|
|||
格式设置为: |
|||
|
|||
```json |
|||
{ |
|||
"v": "", |
|||
"f": "", |
|||
"ct": { |
|||
"v": 1, |
|||
"f": "#,##0.00", |
|||
"t": " Decimal" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
|参数|说明|使用| |
|||
| ------------ | ------------ | ------------ | |
|||
|v|value,Aspose中的快捷设置值|`var currencyStyle = book.CreateStyle();`<br>`currencyStyle.Number = 8;`| |
|||
|f|Format:格式的定义串 `$#,##0;$-#,##0`|`var currencyStyle = book.CreateStyle();`<br>`currencyStyle.Custom = "#,##0 SEK";`| |
|||
|t|Type类型:<br>0:General<br>1:Decimal<br>2:Currency<br>3:Percentage<br>4:Scientific<br>5:Fraction<br>6:Date<br>7:Time<br>8:Accounting<br>9:Text<br>10:DateTime|类型是前端区分的格式,excel导入时根据导入format字符的关键字来区分是哪种类型:<br>1.含YYYY、MM、DD的是6| |
|||
|
|||
Aspose设置如下: |
|||
| Value | Type | Format String | |
|||
|-------|------------|---------------------------------------------| |
|||
| 0 | General | General | |
|||
| 1 | Decimal | 0 | |
|||
| 2 | Decimal | 0\.00 | |
|||
| 3 | Decimal | \#,\#\#0 | |
|||
| 4 | Decimal | \#,\#\#0\.00 | |
|||
| 5 | Currency | $\#,\#\#0;$\-\#,\#\#0 | |
|||
| 6 | Currency | $\#,\#\#0;$\-\#,\#\#0 | |
|||
| 7 | Currency | $\#,\#\#0\.00;$\-\#,\#\#0\.00 | |
|||
| 8 | Currency | $\#,\#\#0\.00;$\-\#,\#\#0\.00 | |
|||
| 9 | Percentage | 0% | |
|||
| 10 | Percentage | 0\.00% | |
|||
| 11 | Scientific | 0\.00E\+00 | |
|||
| 12 | Fraction | \# ?/? | |
|||
| 13 | Fraction | \# / | |
|||
| 14 | Date | m/d/yy | |
|||
| 15 | Date | d\-mmm\-yy | |
|||
| 16 | Date | d\-mmm | |
|||
| 17 | Date | mmm\-yy | |
|||
| 18 | Time | h:mm AM/PM | |
|||
| 19 | Time | h:mm:ss AM/PM | |
|||
| 20 | Time | h:mm | |
|||
| 21 | Time | h:mm:ss | |
|||
| 22 | Time | m/d/yy h:mm | |
|||
| 37 | Currency | \#,\#\#0;\-\#,\#\#0 | |
|||
| 38 | Currency | \#,\#\#0;\-\#,\#\#0 | |
|||
| 39 | Currency | \#,\#\#0\.00;\-\#,\#\#0\.00 | |
|||
| 40 | Currency | \#,\#\#0\.00;\-\#,\#\#0\.00 | |
|||
| 41 | Accounting | \_ \* \#,\#\#0\_ ;\_ \* "\_ ;\_ @\_ | |
|||
| 42 | Accounting | \_ $\* \#,\#\#0\_ ;\_ $\* "\_ ;\_ @\_ | |
|||
| 43 | Accounting | \_ \* \#,\#\#0\.00\_ ;\_ \* "??\_ ;\_ @\_ | |
|||
| 44 | Accounting | \_ $\* \#,\#\#0\.00\_ ;\_ $\* "??\_ ;\_ @\_ | |
|||
| 45 | Time | mm:ss | |
|||
| 46 | Time | h :mm:ss | |
|||
| 47 | Time | mm:ss\.0 | |
|||
| 48 | Scientific | \#\#0\.0E\+00 | |
|||
| 49 | Text | @ | |
|||
|
|||
导入/导出只用考虑用户看到的数据样式,例如excel中处理日期格式的方式为把日期统一转换为数字:42736 代表 2017-1-1, |
|||
@ -0,0 +1,619 @@ |
|||
# 表格操作 |
|||
|
|||
## 单元格刷新 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "v", |
|||
"i": 3, |
|||
"v": "asdf", |
|||
"r": 5, |
|||
"c": 7 |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|v|单元格的值| |
|||
|r|单元格的行号| |
|||
|c|单元格的列号| |
|||
|
|||
- **后台更新**: |
|||
|
|||
单元格更新主要是更新 `luckysheetfile[i].celldata` 参数,该参数是一个数组: |
|||
```json |
|||
[ |
|||
{r:0, c:1, v: "值1"}, |
|||
{r:10, c:11, v:"值2"}, |
|||
{r:10, c:11, v:{f:"=sum", v:"100"}} |
|||
] |
|||
``` |
|||
存储了sheet中所有单元格中的值,Luckysheet在建立的时候会根据 `luckysheetfile[i].row` 和 `luckysheetfile[i].column` 的行列数量大小新建一个表格data,然后再使用 `data[r][c]=v` 的方式填充表格数据,空数据单元格以null表示。 |
|||
|
|||
后台在保存前台推送的数据时,首先需要把参数转换为 `{r:0, c:1:v:100}` 的格式,然后更新 `luckysheetfile[i].celldata` 字段,如果存在该单元格则更新,如果没有则添加,如果存在该单元格但是v为null则删除该单元格。 |
|||
|
|||
- **前台查看**: |
|||
|
|||
可以修改任意单元格的数值,然后到chrome控制台中查看"t"=="v"的操作。 |
|||
|
|||
## config操作 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "cg", |
|||
"i": 3, |
|||
"v": { |
|||
"7": 192 |
|||
}, |
|||
"k": "rowlen" |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|v|需要更新的内部key-value| |
|||
|k|操作的key名称| |
|||
|
|||
- **后台更新**: |
|||
|
|||
更新 `luckysheetfile[i].config.[k][v.key] = v.value` ,如果config中不存k,则新建一个k属性并设置为空,如果k中不存在v.key中,则新建一个v.key再更新v.value。 |
|||
|
|||
1. 修改行高度举例: |
|||
- 输入:`{"t":"cg","i":3,"v":{"3":10, "5":70, "10":100},"k":" rowlen"}` |
|||
- 更新:`luckysheetfile[3].config.["rowlen"]["3"] = 10` |
|||
|
|||
2. 修改列宽度举例: |
|||
- 输入:`{"t":"cg","i":1,"v":{"20":74, "15":170, "6":40},"k":" columlen"}` |
|||
- 更新:`luckysheetfile[1].config.["columlen"]["20"] = 74` |
|||
|
|||
3. 合并单元格举例: |
|||
- 输入:`{"t":"cg","i":1,"v":{"5_10":{row:[1,3], column:[3,5]},"k":" merge "}` |
|||
- 更新:`luckysheetfile[1].config.["merge"]["5_10"] = {row:[1,3], column:[3,5]}` |
|||
|
|||
## 通用保存 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "all", |
|||
"i": 3, |
|||
"v": { |
|||
"v": 1, |
|||
"m":1, |
|||
}, |
|||
"k": "freezen", |
|||
"s": false |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|v|需要更新的内部key-value| |
|||
|k|需要保存的key-value中的value| |
|||
|s|如果是true则v保存为字符串,否则按照对象进行保存| |
|||
|
|||
- **后台更新**: |
|||
|
|||
`luckysheetfile[3].[k]= v` |
|||
如果s为true,则为 `luckysheetfile[3].[k]= JSON.stringify(v)` |
|||
|
|||
1. 数据透视表: |
|||
- 输入:`{"t":"all","i":1,"v":{………},"k":"pivotTable", "s": false}` |
|||
- 更新:`luckysheetfile[1].["pivotTable"] = {………}` |
|||
|
|||
2. 冻结行列: |
|||
- 输入:`{"t":"all","i":3,"v":{………},"k":"freezen", "s": false}` |
|||
- 更新:`luckysheetfile[3].["freezen"] = {………}` |
|||
|
|||
3. 筛选范围: |
|||
- 输入:`{"t":"all","i":3,"v":{………},"k":"filter_select", "s": true }` |
|||
- 更新:`luckysheetfile[3].["filter_select"] = JSON.stringify ({………})` |
|||
|
|||
4. Sheet名称: |
|||
- 输入:`{"t":"all","i":1,"v":"文档","k":"name", "s": false}` |
|||
- 更新:`luckysheetfile[1].["name"] = "文档"` |
|||
|
|||
5. Sheet颜色: |
|||
- 输入: `{"t":"all","i":2,"v":"#FFF000","k":"color", "s": false}` |
|||
- 更新:`luckysheetfile[2].["color"] = "#FFF000"` |
|||
|
|||
## 函数链操作 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "fc", |
|||
"i": 0, |
|||
"v": { |
|||
"r": 3, |
|||
"c": 7, |
|||
"index": 0, |
|||
"func": [ |
|||
true, |
|||
187282, |
|||
"=SUM(E4:G4)" |
|||
] |
|||
}, |
|||
"op": "add", |
|||
"pos": 0 |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|v|对象值,这里对象的内部字段不需要单独更新,所以存为文本即可| |
|||
|op|操作类型,add为新增,update为更新,del为删除| |
|||
|pos|更新或者删除的函数位置| |
|||
|
|||
- **后台更新**: |
|||
|
|||
calcChain为一个数组 |
|||
- 如果op的值add则添加到末尾 `luckysheetfile[i].calcChain.push (v)`, |
|||
- 如果op的值update则更新 `luckysheetfile[i].calcChain[pos]= v`, |
|||
- 如果op的值del则删除 `luckysheetfile[i].calcChain.splice(pos, 1)`。 |
|||
|
|||
- **前台查看**: |
|||
|
|||
可以修改任意单元格的数值,然后到chrome控制台中查看"t"=="v"的操作。 |
|||
|
|||
## 行列操作 |
|||
|
|||
### 删除行或列 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "drc", |
|||
"i": 3, |
|||
"v": { |
|||
"index": 6, |
|||
"len": 2 |
|||
}, |
|||
"rc": "r" |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
<table> |
|||
<tr> |
|||
<td colspan="2">参数</td> |
|||
<td>说明</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">t</td> |
|||
<td>操作类型表示符号</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">i</td> |
|||
<td>当前sheet的index值</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">rc</td> |
|||
<td>行操作还是列操作,值r代表行,c代表列</td> |
|||
</tr> |
|||
<tr> |
|||
<td rowspan="2">v</td> |
|||
<td>index</td> |
|||
<td>从第几行或者列开始删除</td> |
|||
</tr> |
|||
<tr> |
|||
<td>len</td> |
|||
<td>删除多少行或者列</td> |
|||
</tr> |
|||
|
|||
</table> |
|||
|
|||
- **后台更新**: |
|||
|
|||
如果rc的值是r删除行, 如果rc的值为c则删除列, 例如rc=r,index=4,len=5,则代表从第4行开始删除之后的5行(4、5、6、7、8)。 |
|||
|
|||
主要是对 `luckysheetfile[i].celldata` 中的单元格进行操作,删除参数中所描述符合条件的单元格并且更新其他单元格的行列值,以上述为例,首先查找单元格中r值在4到8的所有单元格并删除,然后把本来行号9以后的单元格的r值减去5,最后把 `luckysheetfile[i].row` 减去5。 |
|||
如果v值为 `"#__qkdelete#"`(不含引号),则此处为需要删除的单元格。 |
|||
|
|||
- **前台查看**: |
|||
|
|||
可以删除行或者列,然后到chrome控制台中查看"t"=="drc"的操作。 |
|||
|
|||
### 增加行或列 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "arc", |
|||
"i": 0, |
|||
"v": { |
|||
"index": 5, |
|||
"len": 10, |
|||
"data": [] |
|||
}, |
|||
"rc": "c" |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
<table> |
|||
<tr> |
|||
<td colspan="2">参数</td> |
|||
<td>说明</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">t</td> |
|||
<td>操作类型表示符号</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">i</td> |
|||
<td>当前sheet的index值</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">rc</td> |
|||
<td>行操作还是列操作,值r代表行,c代表列</td> |
|||
</tr> |
|||
<tr> |
|||
<td rowspan="3">v</td> |
|||
<td>index</td> |
|||
<td>从第几行或者列开始新增</td> |
|||
</tr> |
|||
<tr> |
|||
<td>len</td> |
|||
<td>增加多少行或者列</td> |
|||
</tr> |
|||
<tr> |
|||
<td>data</td> |
|||
<td>新增行或者列的内容</td> |
|||
</tr> |
|||
|
|||
</table> |
|||
|
|||
- **后台更新**: |
|||
|
|||
如果rc的值是r新增行, 如果rc的值为c则新增列, 例如rc=r,index=4,len=5,则代表从第4行开始增加5行,如果data为空则增加空行,如果data不为空则用data中的数组添加新增的行中。 |
|||
主要是对 `luckysheetfile[i].celldata` 中的单元格进行操作,以上述为例,首先 `luckysheetfile[i].row` 加5,然后把r大于4的单元格的整体的r值+5,如果data为空则增加空行则结束,如果data不为空则把二维数组data转换为 `{r:0,c:0,v:100}` 的格式并添加到celldata中,转换的伪代码如下: |
|||
```javascript |
|||
var ret = []; |
|||
for(var r=0;r<data.length;r++){ |
|||
for(var c=0;c<data[0].length;c++){ |
|||
if(d[r][c]==null){ |
|||
continue; |
|||
} |
|||
ret.push({r:r+5, c:c, v: data[r][c]}); |
|||
} |
|||
} |
|||
return ret; |
|||
``` |
|||
|
|||
- **前台查看**: |
|||
可以新增行或者列,然后到chrome控制台中查看"t"=="arc"的操作。如果想查看具有data值的操作,则先删除某几行或几列,然后再撤销删除(Ctrl+Z),就能看到。 |
|||
|
|||
## 筛选操作 |
|||
|
|||
### 选择筛选条件 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "f", |
|||
"i": 0, |
|||
"v": "{\"caljs\":{},\"selected\":{\"青岛\":\"1\",\"广西\":\"1\",\"重庆\":\"1\"},\"rowhidden\":{\"1\":0,\"2\":0,\"3\":0,\"4\":0,\"6\":0,\"7\":0,\"8\":0,\"9\":0,\"10\":0,\"11\":0,\"12\":0,\"13\":0,\"14\":0,\"15\":0,\"16\":0,\"17\":0,\"18\":0,\"19\":0,\"21\":0,\"22\":0,\"24\":0,\"25\":0,\"26\":0,\"27\":0,\"28\":0,\"29\":0,\"30\":0,\"31\":0,\"32\":0,\"33\":0,\"34\":0,\"35\":0}}", |
|||
"op": "upOrAdd", |
|||
"pos": 1 |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|v|对象值,这里对象的内部字段不需要单独更新,所以存为文本即可| |
|||
|op|操作类型upOrAdd为更新,如果不存在则增加,del为删除| |
|||
|pos|更新或者删除的option位置| |
|||
|
|||
- **后台更新**: |
|||
|
|||
更新 `luckysheetfile[i].filter = { pos : v }`, v值为一个JSON格式的字符串。filter为一个键值对,key表示选项位置的索引值(以字符表示),v表示一个json字符串参数。filter代表一个筛选条件的集合。 |
|||
|
|||
### 清除筛选 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "fsc", |
|||
"i": 0, |
|||
"v": null |
|||
} |
|||
``` |
|||
|
|||
- **后台更新**: |
|||
|
|||
清除 `luckysheetfile[i]. filter = null` , `luckysheetfile[i]. filter_select = null`。 |
|||
|
|||
### 恢复筛选 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "fsr", |
|||
"i": 0, |
|||
"v": { |
|||
"filter": [], |
|||
"filter_select": {} |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- **后台更新**: |
|||
|
|||
清除 `luckysheetfile[i]. filter = v.filter`, `luckysheetfile[i]. filter_select = v. filter_select`。 |
|||
|
|||
## sheet操作 |
|||
|
|||
### 新建sheet |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "sha", |
|||
"i": null, |
|||
"v": { |
|||
"name": "Sheet4", |
|||
"color": "", |
|||
"status": "0", |
|||
"order": 3, |
|||
"index": 3, |
|||
"data": [], |
|||
"config": {}, |
|||
"pivotTable": null, |
|||
"isPivotTable": false |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
<table> |
|||
<tr> |
|||
<td colspan="2">参数</td> |
|||
<td>说明</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">t</td> |
|||
<td>操作类型表示符号</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">i</td> |
|||
<td>当前sheet的index值</td> |
|||
</tr> |
|||
<tr> |
|||
<td rowspan="9">v</td> |
|||
<td>name</td> |
|||
<td>隐藏后跳转的sheet的index值</td> |
|||
</tr> |
|||
<tr> |
|||
<td>color</td> |
|||
<td>Sheet颜色</td> |
|||
</tr> |
|||
<tr> |
|||
<td>status</td> |
|||
<td>激活状态</td> |
|||
</tr> |
|||
<tr> |
|||
<td>order</td> |
|||
<td>Sheet摆放顺序</td> |
|||
</tr> |
|||
<tr> |
|||
<td>index</td> |
|||
<td>Index索引</td> |
|||
</tr> |
|||
<tr> |
|||
<td>celldata</td> |
|||
<td>单元格数据集</td> |
|||
</tr> |
|||
<tr> |
|||
<td>config</td> |
|||
<td>设置</td> |
|||
</tr> |
|||
<tr> |
|||
<td>pivotTable</td> |
|||
<td>数据透视表设置</td> |
|||
</tr> |
|||
<tr> |
|||
<td>isPivotTable</td> |
|||
<td>是否数据透视表</td> |
|||
</tr> |
|||
|
|||
</table> |
|||
|
|||
- **后台更新**: |
|||
|
|||
添加一行(一个文档)到数据库中。 |
|||
|
|||
### 复制sheet |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "shc", |
|||
"i": "新建sheet的位置", |
|||
"v": { |
|||
"copyindex": "copyindex" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- **后台更新**: |
|||
|
|||
复制表格中的sheet索引值为copyindex并添加到数据库中,添加的设置该新文档的index为i对应的值。 |
|||
|
|||
### 删除sheet |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "shd", |
|||
"i": null, |
|||
"v": { |
|||
"deleIndex": 0 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
<table> |
|||
<tr> |
|||
<td colspan="2">参数</td> |
|||
<td>说明</td> |
|||
</tr> |
|||
<tr> |
|||
<td colspan="2">t</td> |
|||
<td>操作类型表示符号</td> |
|||
</tr> |
|||
<tr> |
|||
<td rowspan="2">v</td> |
|||
<td>deleIndex</td> |
|||
<td>需要删除的sheet索引</td> |
|||
</tr> |
|||
|
|||
</table> |
|||
|
|||
- **后台更新**: |
|||
|
|||
删除索引为deleIndex对应值得sheet。 |
|||
|
|||
### 位置 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "shr", |
|||
"v": { |
|||
"index": "positon" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|v|设置Sheet的排序,为一个键值对,key代表sheet的index,value代表order值。格式为:`{"1": 3, "2":1, "0": 2, "3":0}| |
|||
|
|||
- **后台更新**: |
|||
|
|||
对sheet的index等于key的页设置其order属性为value值。示例: |
|||
|
|||
`luckysheetfile[key1].order = value1` |
|||
`luckysheetfile[key2].order = value2` |
|||
`luckysheetfile[key3].order = value3` |
|||
|
|||
## sheet属性(隐藏或显示) |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "sh", |
|||
"i": 0, |
|||
"v": 1, |
|||
"op": " hide", |
|||
"cur": 2 |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|i|当前sheet的index值| |
|||
|op|操作选项,有hide、show。| |
|||
|v|如果hide为1则隐藏,为0或者空则为显示| |
|||
|cur|隐藏后设置索引对应cur的sheet为激活状态。| |
|||
|
|||
- **后台更新**: |
|||
|
|||
更新"i"对应sheet的根路径hide字段为v,当隐藏时status值为0,当显示时为1, 如果为隐藏则更新index对应cur的sheet的status状态为1。 |
|||
|
|||
## 表格信息更改 |
|||
|
|||
### 表格名称 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "na", |
|||
"i": null, |
|||
"v": "数据" |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|v|表格的名称| |
|||
|
|||
- **后台更新**: |
|||
|
|||
根据gridkey更新数据库中的表格名称。 |
|||
|
|||
### 缩略图 |
|||
|
|||
- **格式**: |
|||
|
|||
```json |
|||
{ |
|||
"t": "thumb", |
|||
"img": "base64", |
|||
"curindex": "curindx" |
|||
} |
|||
``` |
|||
|
|||
- **说明**: |
|||
|
|||
|参数|说明| |
|||
| ------------ | ------------ | |
|||
|t|操作类型表示符号| |
|||
|img|当前表格的缩略图,为base64字符串| |
|||
|curindex|当前表格默认打开的sheet| |
|||
|
|||
- **后台更新**: |
|||
|
|||
根据gridkey更新mysql中表格的缩略图字段为img值,同时更新index为curindex值的sheet的status字段为1,设置其他sheet的status值为0。 |
|||
@ -0,0 +1,142 @@ |
|||
const gulp = require('gulp'); |
|||
// gulp 核心方法
|
|||
const { src, dest, series, parallel, watch } = require('gulp'); |
|||
// gulp压缩js
|
|||
const uglify = require('gulp-uglify'); |
|||
// gulp判断
|
|||
const gulpif = require('gulp-if'); |
|||
// gulp压缩css
|
|||
const cleanCSS = require('gulp-clean-css'); |
|||
// 删除文件
|
|||
const del = require('delete'); |
|||
// 实时刷新浏览器
|
|||
const browserSync = require('browser-sync').create(); |
|||
const reload = browserSync.reload; |
|||
// 文件合并
|
|||
const useref = require('gulp-useref'); |
|||
|
|||
// rollup打包,处理es6模块
|
|||
const { rollup } = require('rollup'); |
|||
// rollup寻找node_modules模块
|
|||
const { nodeResolve } = require('@rollup/plugin-node-resolve'); |
|||
// rollup把commonjs模块转化为es6模块
|
|||
const commonjs = require('@rollup/plugin-commonjs'); |
|||
// rollup代码压缩
|
|||
const terser = require('rollup-plugin-terser').terser; |
|||
// rollup babel plugin, support the latest ES grammar
|
|||
const babel = require('@rollup/plugin-babel').default; |
|||
// 区分开发与生产环境
|
|||
const production = !process.env.ROLLUP_WATCH; |
|||
|
|||
// uglify js压缩配置 https://github.com/mishoo/UglifyJS#minify-options
|
|||
const uglifyOptions = { |
|||
compress: { |
|||
drop_console: true |
|||
} |
|||
} |
|||
|
|||
const babelConfig = { |
|||
babelHelpers: 'bundled', |
|||
exclude: 'node_modules/**', // 只编译我们的源代码
|
|||
plugins: [ |
|||
], |
|||
presets: [ |
|||
'@babel/preset-env' |
|||
] |
|||
}; |
|||
|
|||
|
|||
// 清除dist目录
|
|||
function clean() { |
|||
return del(['dist']); |
|||
} |
|||
//监听文件+重载
|
|||
function watchReload() { |
|||
serve(); |
|||
core(); |
|||
const watcher = watch(['src/**']); |
|||
|
|||
// 多次刷新节流
|
|||
let reloadTimer = null; |
|||
watcher.on('change', function (path, stats) { |
|||
console.info('change------',path) |
|||
|
|||
|
|||
if (reloadTimer !== null) { |
|||
return; |
|||
} |
|||
reloadTimer = setTimeout(() => { |
|||
reload(); |
|||
// core();
|
|||
reloadTimer = null; |
|||
}, 500); |
|||
|
|||
}); |
|||
} |
|||
|
|||
//打包核心代码
|
|||
async function core() { |
|||
const bundle = await rollup({ |
|||
input: 'src/index.js', |
|||
plugins: [ |
|||
nodeResolve(), // tells Rollup how to find date-fns in node_modules
|
|||
commonjs(), // converts date-fns to ES modules
|
|||
// postcss({
|
|||
// plugins: [],
|
|||
// extract: true,
|
|||
// // minimize: isProductionEnv,
|
|||
// }),
|
|||
// production && terser(), // minify, but only in production
|
|||
babel(babelConfig) |
|||
], |
|||
}); |
|||
|
|||
return bundle.write({ |
|||
file: 'src/luckysheet.js', |
|||
format: 'umd', |
|||
name: 'luckysheet', |
|||
sourcemap: true |
|||
}); |
|||
} |
|||
|
|||
// 打包js
|
|||
function js() { |
|||
return src(['src/**/*.html', '!src/luckysheet-core.js','!src/luckysheet-function.js','!src/luckysheet-chart.js']) |
|||
.pipe(useref(), function () { |
|||
return vinylPaths(del) |
|||
}) |
|||
.pipe(gulpif(isJavaScript, uglify(uglifyOptions))) |
|||
.pipe(gulpif(isCss, cleanCSS())) |
|||
.pipe(dest('dist/')) |
|||
} |
|||
// 打包其他文件
|
|||
function otherFile() { |
|||
return src(['src/**', '!src/**/*.html', '!src/**/*.js', '!src/**/*.css', '!src/luckysheet-core.js','!src/luckysheet-function.js','!src/luckysheet-chart.js']) |
|||
.pipe(dest('dist/')) |
|||
} |
|||
|
|||
// 静态服务器
|
|||
function serve() { |
|||
browserSync.init({ |
|||
server: { |
|||
baseDir: "src" |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// 判断文件的扩展名是否是 '.js' , 且需要为未压缩过的js
|
|||
function isJavaScript(file) { |
|||
return file.extname === '.js'; |
|||
} |
|||
|
|||
// 判断文件的扩展名是否是 '.css' , 且需要为未压缩过的css
|
|||
function isCss(file) { |
|||
return file.extname === '.css'; |
|||
} |
|||
|
|||
const build = series(clean, parallel(js, otherFile, core)); |
|||
const dev = watchReload; |
|||
|
|||
exports.build = build; |
|||
exports.dev = dev; |
|||
exports.default = build; |
|||
@ -0,0 +1,33 @@ |
|||
{ |
|||
"name": "luckysheet", |
|||
"version": "1.0.0", |
|||
"main": "dist/luckysheet.cjs.js", |
|||
"module": "dist/luckysheet.esm.js", |
|||
"browser": "dist/luckysheet.umd.js", |
|||
"devDependencies": { |
|||
"@babel/preset-env": "^7.10.2", |
|||
"@rollup/plugin-babel": "^5.0.3", |
|||
"@rollup/plugin-commonjs": "^13.0.0", |
|||
"@rollup/plugin-node-resolve": "^8.0.1", |
|||
"browser-sync": "^2.26.7", |
|||
"delete": "^1.1.0", |
|||
"gulp": "^4.0.2", |
|||
"gulp-clean-css": "^4.3.0", |
|||
"gulp-if": "^3.0.0", |
|||
"gulp-uglify": "^3.0.2", |
|||
"gulp-useref": "^4.0.1", |
|||
"rollup": "^2.16.1", |
|||
"rollup-plugin-terser": "^6.1.0", |
|||
"vuepress": "^1.5.0" |
|||
}, |
|||
"dependencies": {}, |
|||
"scripts": { |
|||
"build": "gulp build", |
|||
"dev": "gulp dev", |
|||
"docs:dev": "vuepress dev docs", |
|||
"docs:build": "vuepress build docs" |
|||
}, |
|||
"files": [ |
|||
"dist" |
|||
] |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
/** |
|||
* The default luckysheet config object. |
|||
*/ |
|||
export default { |
|||
container: "luckysheet", //容器的ID
|
|||
column: 60, //空表格默认的列数量
|
|||
row: 84, //空表格默认的行数据量
|
|||
allowCopy: true, //是否允许拷贝
|
|||
showtoolbar: true, //是否第二列显示工具栏
|
|||
showinfobar: true, //是否显示顶部名称栏
|
|||
showsheetbar: true, //是否显示底部表格名称区域
|
|||
showstatisticBar: true, //是否显示底部计数栏
|
|||
pointEdit: false, //是否是编辑器插入表格模式
|
|||
pointEditUpdate: null, //编辑器表格更新函数
|
|||
pointEditZoom: 1, //编辑器表格编辑时缩放比例
|
|||
// menu: "undo|redo|freezenrow|freezencolumn|download|share|chart|pivot",
|
|||
data: [{ "name": "Sheet1", color: "", "status": "1", "order": "0", "data": [], "config": {}, "index":0 }, { "name": "Sheet2", color: "", "status": "0", "order": "1", "data": [], "config": {}, "index":1 }, { "name": "Sheet3", color: "", "status": "0", "order": "2", "data": [], "config": {}, "index":2 }], //客户端sheet数据[shee1, sheet2, sheet3]
|
|||
title: "Luckysheet Demo", //表格的名称
|
|||
userInfo: '<i style="font-size:16px;color:#ff6a00;" class="fa fa-taxi" aria-hidden="true"></i> rabbit', //右上角的用户信息展示样式
|
|||
userMenuItem: [{url:"www.baidu.com", "icon":'<i class="fa fa-folder" aria-hidden="true"></i>', "name":"我的表格"}, {url:"www.baidu.com", "icon":'<i class="fa fa-sign-out" aria-hidden="true"></i>', "name":"退出登陆"}], //点击右上角的用户信息弹出的菜单
|
|||
myFolderUrl: "www.baidu.com", //左上角<返回按钮的链接
|
|||
config: {}, //表格行高、列宽、合并单元格、公式等设置
|
|||
fullscreenmode: true, //是否全屏模式,非全屏模式下,标记框不会强制选中。
|
|||
devicePixelRatio: window.devicePixelRatio, //设备比例,比例越大表格分标率越高
|
|||
allowEdit: true, //是否允许前台编辑
|
|||
loadUrl: "", // 配置loadUrl的地址,luckysheet会通过ajax请求表格数据,默认载入status为1的sheet数据中的所有data,其余的sheet载入除data字段外的所有字段
|
|||
loadSheetUrl: "", //配置loadSheetUrl的地址,参数为gridKey(表格主键) 和 index(sheet主键合集,格式为[1,2,3]),返回的数据为sheet的data字段数据集合
|
|||
gridKey: "", // 表格唯一标识符
|
|||
updateUrl: "", //表格数据的更新地址
|
|||
updateImageUrl: "", //缩略图的更新地址
|
|||
allowUpdate: false, //是否允许编辑后的后台更新
|
|||
functionButton: "", //右上角功能按钮,例如'<button id="" class="btn btn-primary" style="padding:3px 6px;font-size: 12px;margin-right: 10px;">下载</button> <button id="" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 10px;">分享</button> <button id="luckysheet-share-btn-title" class="btn btn-primary btn-danger" style=" padding:3px 6px; font-size: 12px; margin-right: 10px;">秀数据</button>'
|
|||
showConfigWindowResize: true, //图表和数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进
|
|||
enableAddRow: true,//允许增加行
|
|||
enableAddCol: true,//允许增加列
|
|||
enablePage: false,//允许加载下一页
|
|||
autoFormatw: false, //自动格式化超过4位数的数字为 亿万格式 例:true or "true" or "TRUE"
|
|||
accuracy: undefined, //设置传输来的数值的精确位数,小数点后n位 传参数为数字或数字字符串,例: "0" 或 0
|
|||
pageInfo:{ |
|||
'queryExps':'', |
|||
'reportId':'', |
|||
'fields':'', |
|||
'mobile':'', |
|||
'frezon':'', |
|||
'currentPage':'', |
|||
"totalPage":10, |
|||
"pageUrl":"", |
|||
}, |
|||
editMode: false, //是否为编辑模式
|
|||
chartConfigChange: null,//图表插件中图表更新触发的自定义方法
|
|||
beforeCreateDom: null,//表格创建之前的方法
|
|||
fireMousedown: null //单元格数据下钻
|
|||
} |
|||
@ -0,0 +1 @@ |
|||
// const
|
|||
@ -0,0 +1,114 @@ |
|||
|
|||
import defaultSetting from './config.js' |
|||
import luckysheet from './luckysheet-chart' |
|||
|
|||
|
|||
|
|||
|
|||
luckysheet.create = function (setting) { |
|||
var extendsetting = common_extend(defaultSetting, setting); |
|||
var //defaultflow = extendsetting.defaultflow,
|
|||
loadurl = extendsetting.loadUrl, |
|||
//data1 = extendsetting.data,
|
|||
menu = extendsetting.menu, |
|||
title = extendsetting.title; |
|||
|
|||
container = extendsetting.container; |
|||
//config = extendsetting.config;
|
|||
luckysheetfile = extendsetting.data; |
|||
defaultcolumnNum = extendsetting.column; |
|||
defaultrowNum = extendsetting.row; |
|||
fullscreenmode = extendsetting.fullscreenmode; |
|||
|
|||
luckysheet.server.gridKey = extendsetting.gridKey; |
|||
luckysheet.server.loadUrl = extendsetting.loadUrl; |
|||
luckysheet.server.updateUrl = extendsetting.updateUrl; |
|||
luckysheet.server.updateImageUrl = extendsetting.updateImageUrl; |
|||
luckysheet.server.title = extendsetting.title; |
|||
luckysheet.server.loadSheetUrl = extendsetting.loadSheetUrl; |
|||
luckysheet.server.allowUpdate = extendsetting.allowUpdate; |
|||
|
|||
luckysheetConfigsetting.autoFormatw = extendsetting.autoFormatw; |
|||
luckysheetConfigsetting.accuracy = extendsetting.accuracy; |
|||
luckysheetConfigsetting.total = luckysheetfile[0].total; |
|||
|
|||
luckysheetConfigsetting.allowCopy = extendsetting.allowCopy; |
|||
luckysheetConfigsetting.showtoolbar = extendsetting.showtoolbar; |
|||
luckysheetConfigsetting.showinfobar = extendsetting.showinfobar; |
|||
luckysheetConfigsetting.showsheetbar = extendsetting.showsheetbar; |
|||
luckysheetConfigsetting.showstatisticBar = extendsetting.showstatisticBar; |
|||
luckysheetConfigsetting.pointEdit = extendsetting.pointEdit; |
|||
luckysheetConfigsetting.pointEditUpdate = extendsetting.pointEditUpdate; |
|||
luckysheetConfigsetting.pointEditZoom = extendsetting.pointEditZoom; |
|||
|
|||
luckysheetConfigsetting.userInfo = extendsetting.userInfo; |
|||
luckysheetConfigsetting.userMenuItem = extendsetting.userMenuItem; |
|||
luckysheetConfigsetting.myFolderUrl = extendsetting.myFolderUrl; |
|||
|
|||
luckysheetConfigsetting.functionButton = extendsetting.functionButton; |
|||
|
|||
luckysheetConfigsetting.showConfigWindowResize = extendsetting.showConfigWindowResize; |
|||
|
|||
luckysheetConfigsetting.enableAddRow = extendsetting.enableAddRow; |
|||
luckysheetConfigsetting.enableAddCol = extendsetting.enableAddCol; |
|||
luckysheetConfigsetting.enablePage = extendsetting.enablePage; |
|||
luckysheetConfigsetting.pageInfo = extendsetting.pageInfo; |
|||
|
|||
luckysheetConfigsetting.editMode = extendsetting.editMode; |
|||
luckysheetConfigsetting.chartConfigChange = extendsetting.chartConfigChange; |
|||
luckysheetConfigsetting.beforeCreateDom = extendsetting.beforeCreateDom; |
|||
|
|||
luckysheetConfigsetting.fireMousedown = extendsetting.fireMousedown; |
|||
|
|||
devicePixelRatio = extendsetting.devicePixelRatio; |
|||
if(devicePixelRatio==null){ |
|||
devicePixelRatio = 1; |
|||
} |
|||
devicePixelRatio = Math.ceil(devicePixelRatio); |
|||
|
|||
//luckysheet.tooltip.chartPointConfig("luckysheet-chart-point-config");
|
|||
|
|||
//loading
|
|||
$("#" + container).append('<div id="luckysheetloadingdata" style="width:100%;text-align:center;position:absolute;top:0px;height:100%;font-size: 16px;z-index:1000000000;background:#fff;"><div style="position:relative;top:45%;width:100%;"> <div class="luckysheetLoaderGif"> </div> <span>渲染中...</span></div></div>'); |
|||
|
|||
if(luckysheetConfigsetting.pointEdit){ |
|||
//编辑器qksheet表格编辑状态
|
|||
$("#" + container).attr("tabindex", 0).focus(); |
|||
$("#luckysheetloadingdata .luckysheetLoaderGif").css({ "width": "4em", "height": "4em" }); |
|||
} |
|||
|
|||
var data = []; |
|||
if (loadurl == "") { |
|||
luckysheet.sheetmanage.initialjfFile(menu, title); |
|||
luckysheet.luckysheetsizeauto(); |
|||
luckysheet.luckysheetHandler(); |
|||
luckysheet.chartInitial(); |
|||
//luckysheet.luckysheetactiveCell();
|
|||
} |
|||
else { |
|||
$.post(loadurl, {"gridKey" : luckysheet.server.gridKey}, function (d) { |
|||
var data = eval("(" + d + ")"); |
|||
luckysheetfile = data; |
|||
|
|||
luckysheet.sheetmanage.initialjfFile(menu, title); |
|||
luckysheet.luckysheetsizeauto(); |
|||
luckysheet.luckysheetHandler(); |
|||
luckysheet.chartInitial(); |
|||
|
|||
//需要更新数据给后台时,建立WebSocket连接
|
|||
if(luckysheet.server.allowUpdate){ |
|||
luckysheet.server.openWebSocket(); |
|||
} |
|||
|
|||
// setTimeout(function(){
|
|||
// $("#luckysheetloadingdata").fadeOut().remove();
|
|||
// }, 500);
|
|||
//luckysheet.luckysheetactiveCell();
|
|||
}); |
|||
} |
|||
|
|||
return luckysheet; |
|||
} |
|||
export { |
|||
luckysheet |
|||
} |
|||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 85 B |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 1022 B |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 434 KiB |
@ -0,0 +1,13 @@ |
|||
import './utils/math' |
|||
import luckysheet from './core' |
|||
import __firefox from './utils/polyfill' |
|||
|
|||
// polyfill event in firefox
|
|||
if(window.addEventListener && (navigator.userAgent.indexOf("Firefox") > 0)){ |
|||
__firefox(); |
|||
} |
|||
|
|||
export default luckysheet; |
|||
export { |
|||
luckysheet |
|||
} |
|||
@ -0,0 +1,421 @@ |
|||
.daterangepicker { |
|||
display: none; |
|||
position: absolute; |
|||
color: inherit; |
|||
background: #fff; |
|||
border-radius: 4px; |
|||
width: 278px; |
|||
padding: 4px; |
|||
margin-top: 1px; |
|||
top: 100px; |
|||
left: 20px; |
|||
padding-bottom: 50px; |
|||
font-size: 14px; |
|||
border: 1px solid rgba(0,0,0,.15); |
|||
} |
|||
.daterangepicker table{ |
|||
border-collapse: collapse; |
|||
border-spacing: 0; |
|||
} |
|||
.daterangepicker table td,.daterangepicker table th{ |
|||
padding: 5px; |
|||
box-sizing: border-box; |
|||
-webkit-box-sizing: border-box; |
|||
} |
|||
.daterangepicker:before, .daterangepicker:after { |
|||
position: absolute; |
|||
display: inline-block; |
|||
border-bottom-color: rgba(0, 0, 0, 0.2); |
|||
content: ''; |
|||
} |
|||
.daterangepicker:before { |
|||
top: -7px; |
|||
border-right: 7px solid transparent; |
|||
border-left: 7px solid transparent; |
|||
border-bottom: 7px solid #ccc; |
|||
} |
|||
.daterangepicker:after { |
|||
top: -6px; |
|||
border-right: 6px solid transparent; |
|||
border-bottom: 6px solid #fff; |
|||
border-left: 6px solid transparent; |
|||
} |
|||
.daterangepicker.opensleft:before { |
|||
right: 9px; |
|||
} |
|||
.daterangepicker.opensleft:after { |
|||
right: 10px; |
|||
} |
|||
.daterangepicker.openscenter:before { |
|||
left: 0; |
|||
right: 0; |
|||
width: 0; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
.daterangepicker.openscenter:after { |
|||
left: 0; |
|||
right: 0; |
|||
width: 0; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
.daterangepicker.opensright:before { |
|||
left: 9px; |
|||
} |
|||
.daterangepicker.opensright:after { |
|||
left: 10px; |
|||
} |
|||
.daterangepicker.dropup { |
|||
margin-top: -5px; |
|||
} |
|||
.daterangepicker.dropup:before { |
|||
top: initial; |
|||
bottom: -7px; |
|||
border-bottom: initial; |
|||
border-top: 7px solid #ccc; |
|||
} |
|||
.daterangepicker.dropup:after { |
|||
top: initial; |
|||
bottom: -6px; |
|||
border-bottom: initial; |
|||
border-top: 6px solid #fff; |
|||
} |
|||
.daterangepicker.dropdown-menu { |
|||
max-width: none; |
|||
z-index: 1000000; |
|||
} |
|||
.daterangepicker.single .ranges, .daterangepicker.single .calendar { |
|||
float: none; |
|||
} |
|||
.daterangepicker.show-calendar .calendar { |
|||
display: block; |
|||
} |
|||
.daterangepicker .calendar { |
|||
display: block; |
|||
max-width: 270px; |
|||
margin: 4px; |
|||
margin-top: -30px; |
|||
} |
|||
.daterangepicker .calendar.single .calendar-table { |
|||
border: none; |
|||
} |
|||
.daterangepicker .calendar th, .daterangepicker .calendar td { |
|||
white-space: nowrap; |
|||
text-align: center; |
|||
min-width: 32px; |
|||
} |
|||
.daterangepicker .calendar-table { |
|||
border: 1px solid #fff; |
|||
padding: 4px; |
|||
border-radius: 4px; |
|||
background: #fff; |
|||
} |
|||
.daterangepicker table { |
|||
width: 100%; |
|||
margin: 0; |
|||
} |
|||
.daterangepicker td, .daterangepicker th { |
|||
text-align: center; |
|||
width: 20px; |
|||
height: 20px; |
|||
line-height: 20px; |
|||
border-radius: 4px; |
|||
border: 1px solid transparent; |
|||
white-space: nowrap; |
|||
cursor: pointer; |
|||
} |
|||
.daterangepicker td.available:hover, .daterangepicker th.available:hover { |
|||
background: #eee; |
|||
} |
|||
.daterangepicker td.week, .daterangepicker th.week { |
|||
font-size: 80%; |
|||
color: #ccc; |
|||
} |
|||
.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { |
|||
background-color: #fff; |
|||
border-color: transparent; |
|||
color: #999; |
|||
} |
|||
.daterangepicker td.in-range { |
|||
background-color: #d9e3ff; |
|||
border-color: transparent; |
|||
color: #000; |
|||
border-radius: 0; |
|||
} |
|||
.daterangepicker td.start-date { |
|||
border-radius: 4px 0 0 4px; |
|||
} |
|||
.daterangepicker td.end-date { |
|||
border-radius: 0 4px 4px 0; |
|||
} |
|||
.daterangepicker td.start-date.end-date { |
|||
border-radius: 4px; |
|||
} |
|||
.daterangepicker td.active, .daterangepicker td.active:hover { |
|||
background-color: #477cff; |
|||
border-color: transparent; |
|||
color: #fff; |
|||
} |
|||
.daterangepicker th.month { |
|||
width: auto; |
|||
} |
|||
.daterangepicker td.disabled, .daterangepicker option.disabled { |
|||
color: #999; |
|||
cursor: not-allowed; |
|||
text-decoration: line-through; |
|||
} |
|||
.daterangepicker select.monthselect, .daterangepicker select.yearselect { |
|||
font-size: 12px; |
|||
padding: 1px; |
|||
height: auto; |
|||
margin: 0; |
|||
cursor: default; |
|||
vertical-align: top; |
|||
} |
|||
.daterangepicker select.monthselect { |
|||
margin-right: 2%; |
|||
width: 56%; |
|||
} |
|||
.daterangepicker select.yearselect { |
|||
width: 40%; |
|||
} |
|||
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { |
|||
width: 50px; |
|||
margin-bottom: 0; |
|||
} |
|||
.daterangepicker .input-mini { |
|||
border: 1px solid #ccc; |
|||
border-radius: 4px; |
|||
color: #555; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
display: block; |
|||
vertical-align: middle; |
|||
margin: 0 0 5px 0; |
|||
padding: 0 6px 0 0px; |
|||
width: 100%; |
|||
} |
|||
.daterangepicker .input-mini.active { |
|||
/*border: 1px solid #08c; |
|||
border-radius: 4px; */ |
|||
} |
|||
.daterangepicker .daterangepicker_input { |
|||
position: relative; |
|||
} |
|||
.daterangepicker .daterangepicker_input input{ |
|||
border:0; |
|||
color: #477cff; |
|||
} |
|||
.daterangepicker .daterangepicker_input i { |
|||
position: absolute; |
|||
left: 8px; |
|||
top: 8px; |
|||
} |
|||
.daterangepicker .calendar-time { |
|||
text-align: center; |
|||
margin: 5px auto; |
|||
line-height: 30px; |
|||
position: relative; |
|||
padding-left: 28px; |
|||
} |
|||
.daterangepicker .calendar-time select.disabled { |
|||
color: #ccc; |
|||
cursor: not-allowed; |
|||
} |
|||
.ranges { |
|||
font-size: 11px; |
|||
float: none; |
|||
margin: 4px; |
|||
text-align: left; |
|||
border-right: 1px solid #efeff0; |
|||
margin-right: 15px; |
|||
} |
|||
.ranges ul { |
|||
list-style: none; |
|||
margin: 0 auto; |
|||
padding: 0; |
|||
width: 100%; |
|||
} |
|||
.ranges li { |
|||
font-size: 12px; |
|||
/*background: #f5f5f5;*/ |
|||
/*border: 1px solid #f5f5f5;*/ |
|||
/*border-radius: 4px;*/ |
|||
color: #72777a; |
|||
padding: 3px 12px; |
|||
height: 20px; |
|||
line-height: 14px; |
|||
margin-bottom: 8px; |
|||
cursor: pointer; |
|||
box-sizing: border-box; |
|||
-webkit-box-sizing: border-box; |
|||
} |
|||
.ranges li:hover { |
|||
/*background: #08c; |
|||
border: 1px solid #08c;*/ |
|||
color: #6072FF; |
|||
} |
|||
.ranges li.active { |
|||
/*background: #08c;*/ |
|||
border: 1px solid #efeff0; |
|||
color: #477cff; |
|||
} |
|||
@media (min-width: 564px) { |
|||
.daterangepicker { |
|||
width: auto; |
|||
} |
|||
.daterangepicker .ranges ul { |
|||
width: 120px; |
|||
} |
|||
.daterangepicker.single .ranges ul { |
|||
width: 100%; |
|||
} |
|||
.daterangepicker.single .calendar.left { |
|||
clear: none; |
|||
} |
|||
.daterangepicker.single .ranges, .daterangepicker.single .calendar { |
|||
float: left; |
|||
} |
|||
.daterangepicker .calendar.left { |
|||
clear: left; |
|||
margin-right: 0; |
|||
} |
|||
.daterangepicker .calendar.left .calendar-table { |
|||
border-right: none; |
|||
border-top-right-radius: 0; |
|||
border-bottom-right-radius: 0; |
|||
} |
|||
.daterangepicker .calendar.right { |
|||
margin-left: 0; |
|||
} |
|||
.daterangepicker .calendar.right .calendar-table { |
|||
border-left: none; |
|||
border-top-left-radius: 0; |
|||
border-bottom-left-radius: 0; |
|||
} |
|||
.daterangepicker .left .daterangepicker_input { |
|||
padding-right: 12px; |
|||
} |
|||
.daterangepicker .calendar.left .calendar-table { |
|||
padding-right: 12px; |
|||
} |
|||
.daterangepicker .ranges, .daterangepicker .calendar { |
|||
float: left; |
|||
} |
|||
} |
|||
@media (min-width: 730px){ |
|||
.daterangepicker .ranges { |
|||
width: auto; |
|||
float: left; |
|||
} |
|||
.daterangepicker .calendar.left { |
|||
clear: none; |
|||
} |
|||
} |
|||
.applyBtn,.cancelBtn{ |
|||
padding: 0; |
|||
width: 60px; |
|||
height: 28px !important; |
|||
font-size: 12px; |
|||
} |
|||
.applyBtn{ |
|||
border-color: #2196f3; |
|||
background-color: #2196f3; |
|||
color: #fff; |
|||
} |
|||
.cancelBtn{ |
|||
background: #ffffff; |
|||
color: #666 !important; |
|||
border: 1px solid #d9dbdc; |
|||
} |
|||
.applyBtn:hover{ |
|||
border-color: #2196f3 !important; |
|||
background-color: #2196f3 !important; |
|||
color: #fff !important; |
|||
} |
|||
.cancelBtn:hover{ |
|||
background: #ffffff !important; |
|||
color: #666 !important; |
|||
border: 1px solid #d9dbdc !important; |
|||
} |
|||
.ranges_1 ul { |
|||
display: none; |
|||
} |
|||
.ranges_1 .range_inputs { |
|||
position: absolute; |
|||
bottom: 0; |
|||
margin-bottom: 15px; |
|||
right: 60px; |
|||
} |
|||
.calendar_1 { |
|||
position: absolute; |
|||
right: 340px; |
|||
bottom: 4px; |
|||
width: 125px; |
|||
} |
|||
.calendar_2 { |
|||
position: absolute; |
|||
right: 238px; |
|||
bottom: 4px; |
|||
width: 125px; |
|||
} |
|||
.line_date { |
|||
width: 100%; |
|||
height: 1px; |
|||
border-bottom: 1px solid #efeff0; |
|||
position: absolute; |
|||
bottom: 53px; |
|||
right: 0; |
|||
} |
|||
.line_date_2 { |
|||
width: 7px; |
|||
height: 1px; |
|||
border-bottom: 1px solid #477cff; |
|||
position: absolute; |
|||
bottom: 28px; |
|||
right: 380px; |
|||
} |
|||
.daterangepicker .all{ |
|||
position: absolute; |
|||
bottom: 14px; |
|||
right: 282px; |
|||
width: 188px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
background-color: #ffffff; |
|||
color: #477cff; |
|||
display: none; |
|||
} |
|||
.daterangepicker .prev { |
|||
position: relative; |
|||
left: 33px; |
|||
} |
|||
.daterangepicker .next { |
|||
position: relative; |
|||
right: 33px; |
|||
} |
|||
.prev_year,.prev_month{ |
|||
width: 30px; |
|||
height:30px; |
|||
position: relative; |
|||
display: inline-block; |
|||
line-height: 30px; |
|||
text-align: center; |
|||
} |
|||
.prev_year:hover,.prev_month:hover{ |
|||
background: #eeeeee; |
|||
cursor: pointer; |
|||
} |
|||
.prev_year i,.prev_month i{ |
|||
font-size: 16px; |
|||
color: #000; |
|||
} |
|||
.prev_year{ |
|||
left: 15px; |
|||
top: 36px; |
|||
} |
|||
.prev_month{ |
|||
left: 191px; |
|||
top: 36px; |
|||
} |
|||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 230 B |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
@ -0,0 +1,8 @@ |
|||
/*! |
|||
* jQuery Mousewheel 3.1.13 |
|||
* |
|||
* Copyright 2015 jQuery Foundation and other contributors |
|||
* Released under the MIT license. |
|||
* http://jquery.org/license
|
|||
*/ |
|||
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}); |
|||
@ -0,0 +1,97 @@ |
|||
'use strict'; |
|||
|
|||
(function(root, factory) { |
|||
/*global define*/ |
|||
if (typeof define === 'function' && define.amd) { |
|||
define(['moment', 'moment-timezone'], factory); // AMD
|
|||
} else if (typeof module === 'object' && module.exports) { |
|||
module.exports = factory(require('moment'), require('moment-timezone')); // Node
|
|||
} else { |
|||
factory(root.moment, root.moment.tz); // Browser
|
|||
} |
|||
}(this, function(moment, momentTimezone) { |
|||
var MINUTE_MILLISECONDS = 60 * 1000; |
|||
var DAY_MILLISECONDS = 86400000; |
|||
var MS_DAY_OFFSET = 25569; |
|||
|
|||
var momentVersion = moment.version.split('.'); |
|||
var major = +momentVersion[0]; |
|||
var minor = +momentVersion[1]; |
|||
|
|||
if (major < 2 || (major === 2 && minor < 6)) { |
|||
throw new Error('moment-msdate requires Moment.js >= 2.6.0. You are using Moment.js ${moment.version}. See momentjs.com'); |
|||
} |
|||
|
|||
if (!momentTimezone || !moment.tz) { |
|||
throw new Error('moment-msdate requires moment-timezone.js. see momentjs.com/timezone'); |
|||
} |
|||
|
|||
var oaDateToTicks = function(oaDate) { |
|||
return ((oaDate - MS_DAY_OFFSET) * DAY_MILLISECONDS) + (oaDate >= 0.0 ? 0.5 : -0.5); |
|||
}; |
|||
|
|||
var ticksToOADate = function(ticks) { |
|||
return (ticks / DAY_MILLISECONDS) + MS_DAY_OFFSET; |
|||
}; |
|||
|
|||
/** |
|||
* @description takes an oaDate that is not in utc and converts it to a utc moment offset by a number of minutes |
|||
* |
|||
* @param {double} oaDate |
|||
* @param {string} offsetToUtcInMinutes |
|||
* @returns moment |
|||
*/ |
|||
var fromOADateOffsetToUtcByMinutes = function(oaDate, offsetToUtcInMinutes) { |
|||
var offsetInTicks = offsetToUtcInMinutes * MINUTE_MILLISECONDS; |
|||
var ticks = oaDateToTicks(oaDate); |
|||
return moment(ticks + offsetInTicks).utc(); |
|||
}; |
|||
|
|||
/** |
|||
* @description takes an oaDate that is not in utc and converts it to a utc moment offset by the specified timezone |
|||
* |
|||
* @param {double} oaDate |
|||
* @param {string} timezone |
|||
* @returns moment |
|||
*/ |
|||
var fromOADateOffsetToUtcByTimezone = function(oaDate, timezone) { |
|||
if (!moment.tz.zone(timezone)) { throw new Error('timezone provided is not available in moment-timezone.js', 'moment-msdate.js', 59); } |
|||
var ticks = oaDateToTicks(oaDate); |
|||
var offset = moment(ticks).tz(timezone).utcOffset() * MINUTE_MILLISECONDS; |
|||
return moment.tz(ticks - offset, timezone).utc(); |
|||
}; |
|||
|
|||
/** |
|||
* @description takes an oaDate that is in utc and converts it to a utc moment or takes an oaDate and an offset to utc and converts it to a utc moment. The offset can be an int representing the offset to utc in minutes or a string indicating the timezone of the oaDate. |
|||
* |
|||
* @param {double} oaDate |
|||
* @param {string=} {int=} offset |
|||
* @returns moment |
|||
*/ |
|||
moment.fromOADate = function(oaDate, offset) { |
|||
if (isNaN(parseInt(oaDate, 10))) { throw new TypeError('fromOADate requires an oaDate that is not null or undefined', 'moment-msdate.js', 72); } |
|||
|
|||
/* no offset */ |
|||
if (!offset) { return fromOADateOffsetToUtcByMinutes(oaDate, 0); } |
|||
|
|||
/* timezone */ |
|||
var parsedOffset = parseInt(offset, 10); |
|||
if (isNaN(parsedOffset)) { return fromOADateOffsetToUtcByTimezone(oaDate, offset); } |
|||
|
|||
/* minutes */ |
|||
return fromOADateOffsetToUtcByMinutes(oaDate, parsedOffset); |
|||
}; |
|||
|
|||
/** |
|||
* @description converts a moment to a UTC OLE automation date represented as a double |
|||
* |
|||
* @returns {double} |
|||
*/ |
|||
moment.fn.toOADate = function() { |
|||
var milliseconds = this.valueOf(); |
|||
return ticksToOADate(milliseconds); |
|||
}; |
|||
|
|||
|
|||
return moment; |
|||
})); |
|||
@ -0,0 +1,158 @@ |
|||
import { isRealNum } from './util' |
|||
|
|||
/* |
|||
* 判断obj是否为一个整数 |
|||
*/ |
|||
function isInteger(obj) { |
|||
return Math.floor(obj) === obj; |
|||
} |
|||
|
|||
/* |
|||
* 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100 |
|||
* @param floatNum {number} 小数 |
|||
* @return {object} |
|||
* {times:100, num: 314} |
|||
*/ |
|||
function toInteger(floatNum) { |
|||
var ret = { times: 1, num: 0 }; |
|||
|
|||
if (isInteger(floatNum)) { |
|||
ret.num = floatNum; |
|||
return ret; |
|||
} |
|||
|
|||
var strfi = floatNum + ''; |
|||
var dotPos = strfi.indexOf('.'); |
|||
var len = strfi.substr(dotPos + 1).length; |
|||
var times = Math.pow(10, len); |
|||
var intNum = parseInt(floatNum * times + 0.5, 10); |
|||
|
|||
ret.times = times; |
|||
ret.num = intNum; |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/* |
|||
* 核心方法,实现加减乘除运算,确保不丢失精度 |
|||
* 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除) |
|||
* |
|||
* @param a {number} 运算数1 |
|||
* @param b {number} 运算数2 |
|||
* @param digits {number} 精度,保留的小数点数,比如 2, 即保留为两位小数 |
|||
* @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide) |
|||
* |
|||
*/ |
|||
function operation(a, b, op) { |
|||
var o1 = toInteger(a); |
|||
var o2 = toInteger(b); |
|||
var n1 = o1.num; |
|||
var n2 = o2.num; |
|||
var t1 = o1.times; |
|||
var t2 = o2.times; |
|||
var max = t1 > t2 ? t1 : t2; |
|||
var result = null; |
|||
|
|||
switch (op) { |
|||
case 'add': |
|||
if (t1 === t2) { // 两个小数位数相同
|
|||
result = n1 + n2; |
|||
} |
|||
else if (t1 > t2) { // o1 小数位 大于 o2
|
|||
result = n1 + n2 * (t1 / t2); |
|||
} |
|||
else { // o1 小数位 小于 o2
|
|||
result = n1 * (t2 / t1) + n2; |
|||
} |
|||
|
|||
return result / max; |
|||
case 'subtract': |
|||
if (t1 === t2) { |
|||
result = n1 - n2; |
|||
} |
|||
else if (t1 > t2) { |
|||
result = n1 - n2 * (t1 / t2); |
|||
} |
|||
else { |
|||
result = n1 * (t2 / t1) - n2; |
|||
} |
|||
|
|||
return result / max; |
|||
case 'multiply': |
|||
result = (n1 * n2) / (t1 * t2); |
|||
|
|||
return result; |
|||
case 'divide': |
|||
return result = function () { |
|||
var r1 = n1 / n2; |
|||
var r2 = t2 / t1; |
|||
return operation(r1, r2, 'multiply'); |
|||
}(); |
|||
} |
|||
} |
|||
/** |
|||
* 做小数点的四舍五入计算 |
|||
* @param {*} num |
|||
* @param {*} precision |
|||
*/ |
|||
function fixed(num, precision) { |
|||
if (!precision) { |
|||
precision = 2; |
|||
} |
|||
if (!isRealNum(num)) return num; |
|||
let s = num.toFixed(precision); |
|||
let index = s.indexOf('.'); |
|||
let prefix = s.substring(0, index); |
|||
let suffix = s.substring(index + 1, s.length); |
|||
if (suffix) { |
|||
for (let i = suffix.length - 1; i != 0; i--) { |
|||
//最末位不为0,直接break;
|
|||
if (suffix.charAt(i) != '0' && i == suffix.length - 1) { |
|||
break; |
|||
} else { |
|||
suffix = suffix.substring(0, i); |
|||
} |
|||
} |
|||
} |
|||
return Number(prefix + '.' + suffix); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* Calculation +-/* Solve the problem of js accuracy |
|||
*/ |
|||
Number.prototype.add = function (value) { |
|||
let number = parseFloat(value); |
|||
if (typeof number !== 'number' || Number.isNaN(number)) { |
|||
throw new Error('请输入数字或者数字字符串~'); |
|||
}; |
|||
return operation(this, number, 'add'); |
|||
}; |
|||
Number.prototype.subtract = function (value) { |
|||
let number = parseFloat(value); |
|||
if (typeof number !== 'number' || Number.isNaN(number)) { |
|||
throw new Error('请输入数字或者数字字符串~'); |
|||
} |
|||
return operation(this, number, 'subtract'); |
|||
}; |
|||
Number.prototype.multiply = function (value) { |
|||
let number = parseFloat(value); |
|||
if (typeof number !== 'number' || Number.isNaN(number)) { |
|||
throw new Error('请输入数字或者数字字符串~'); |
|||
} |
|||
return operation(this, number, 'multiply'); |
|||
}; |
|||
Number.prototype.divide = function (value) { |
|||
let number = parseFloat(value); |
|||
if (typeof number !== 'number' || Number.isNaN(number)) { |
|||
throw new Error('请输入数字或者数字字符串~'); |
|||
} |
|||
return operation(this, number, 'divide'); |
|||
}; |
|||
Number.prototype.tofixed = function (value) { |
|||
let precision = parseFloat(value); |
|||
if (typeof precision !== 'number' || Number.isNaN(precision)) { |
|||
throw new Error('请输入数字或者数字字符串~'); |
|||
} |
|||
return fixed(this, precision); |
|||
}; |
|||
@ -0,0 +1,46 @@ |
|||
/** |
|||
* polyfill event in firefox |
|||
*/ |
|||
function __firefox(){ |
|||
HTMLElement.prototype.__defineGetter__("runtimeStyle", __element_style); |
|||
window.constructor.prototype.__defineGetter__("event", __window_event); |
|||
Event.prototype.__defineGetter__("srcElement", __event_srcElement); |
|||
} |
|||
|
|||
function __element_style(){ |
|||
return this.style; |
|||
} |
|||
|
|||
function __window_event(){ |
|||
return __window_event_constructor(); |
|||
} |
|||
|
|||
function __event_srcElement(){ |
|||
return this.target; |
|||
} |
|||
|
|||
function __window_event_constructor(){ |
|||
if(document.all){ |
|||
return window.event; |
|||
} |
|||
|
|||
var _caller = __window_event_constructor.caller; |
|||
|
|||
while(_caller != null){ |
|||
var _argument = _caller.arguments[0]; |
|||
|
|||
if(_argument){ |
|||
var _temp = _argument.constructor; |
|||
|
|||
if(_temp.toString().indexOf("Event") != -1){ |
|||
return _argument; |
|||
} |
|||
} |
|||
|
|||
_caller = _caller.caller; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
export default __firefox; |
|||
@ -0,0 +1,36 @@ |
|||
/** |
|||
* Common tool methods |
|||
*/ |
|||
|
|||
/** |
|||
* Determine whether a string is in standard JSON format |
|||
* @param {String} str |
|||
*/ |
|||
function isJsonString(str) { |
|||
try { |
|||
if (typeof JSON.parse(str) == "object") { |
|||
return true; |
|||
} |
|||
} catch (e) { } |
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* Determine whether a variable is a pure number, null/""/undefined/"34rt"/"34e" is not a number, 34/"34"/"34e10" is a number |
|||
* @param {Number | String | } val |
|||
*/ |
|||
function isRealNum(val) { |
|||
if (val == null || val.toString().replace(/\s/g, "") === "") { |
|||
return false; |
|||
} |
|||
if (!isNaN(val)) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
export { |
|||
isJsonString, |
|||
isRealNum |
|||
} |
|||