Browse Source

'merge'

master
swen-xiong 5 years ago
parent
commit
5f95ee7b17
  1. 25
      README-zh.md
  2. 26
      README.md
  3. 8
      docs/guide/data.md
  4. 2
      docs/zh/guide/README.md
  5. 95
      docs/zh/guide/api.md
  6. 9
      docs/zh/guide/cell.md
  7. 268
      docs/zh/guide/config.md
  8. 192
      docs/zh/guide/operate.md
  9. 544
      docs/zh/guide/sheet.md
  10. 2
      src/config.js
  11. 55
      src/controllers/constant.js
  12. 187
      src/controllers/handler.js
  13. 283
      src/controllers/imageCtrl.js
  14. 3
      src/controllers/luckysheetConfigsetting.js
  15. 29
      src/controllers/server.js
  16. 150
      src/controllers/sheetmanage.js
  17. 4
      src/controllers/updateCell.js
  18. 7
      src/core.js
  19. 218
      src/css/luckysheet-core.css
  20. 2
      src/demoData/sheetCell.js
  21. 40
      src/demoData/sheetFormula.js
  22. 8
      src/expendPlugins/chart/plugin.js
  23. 3
      src/function/func.js
  24. 6
      src/function/functionImplementation.js
  25. 8
      src/global/createdom.js
  26. 334
      src/global/draw.js
  27. 18
      src/global/extend.js
  28. 70
      src/global/formula.js
  29. 16
      src/global/getRowlen.js
  30. 43
      src/global/getdata.js
  31. 4
      src/global/method.js
  32. 5
      src/global/refresh.js
  33. 6
      src/global/rhchInit.js
  34. 6
      src/global/setdata.js
  35. 44
      src/index.html
  36. 4
      src/store/index.js

25
README-zh.md

@ -16,6 +16,10 @@
![演示](/docs/.vuepress/public/img/LuckysheetDemo.gif)
## 插件
- excel导入导出库: [Luckyexcel](https://github.com/mengshukeji/Luckyexcel)
- 图表插件: [chartMix](https://github.com/mengshukeji/chartMix)
## 特性
### 🛠️格式设置
@ -85,6 +89,7 @@
+ **矩阵计算** (通过右键菜单进行支持:对选区内的数据进行转置、旋转、数值计算)
+ **截图** (把选区的内容进行截图展示)
+ **复制到其他格式** (右键菜单的"复制为", 支持复制为json、array、对角线数据、去重等)
+ **EXCEL,CSV,TXT 导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出)
### ⏱️未来开发计划
+ **插入图表和svg形状** (支持JPG,PNG,SVG,Pen tool的插入、修改和删除,并且随表格的变动而产生变化)
@ -93,7 +98,6 @@
+ **单元格内多样式** (Alt+Enter单元格内换行、上标、下标、单元格内科定义每个文字的不同样式)
+ **树形菜单** (类似excel中的分级显示(分组))
+ **表格新功能** (类似excel中表格的筛选器和切片器)
+ **EXCEL,CSV,TXT 导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出)
+ **文档** (完善文档和API)
+ **敬请期待...** (可以提出好的建议给我们)
@ -150,11 +154,17 @@ npm run build
```
## 加入共建
如果你想为 Luckysheet 实现一个重要功能,需要先撰写 RFC 文档,按照Luckysheet的 [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) 机制进行操作,在经过社区讨论完善后才可以进行代码的提交。
## 联系
- 欢迎提交 PR 或者 [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose)
- Email: mengshu@office2.cn
1. 任何疑问或者建议,欢迎提交[Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose)
2. 如果您想为 Luckysheet 实现一个重要功能,需要先撰写 RFC 文档,按照Luckysheet的 [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) 机制进行操作,在经过社区讨论完善后才可以进行代码的提交。
3. 如果您对Luckysheet感兴趣,非常欢迎加入开发组,一起来完善这个插件(下方扫码添加小编微信备注:共建),有4类任务可以认领
- BUG修复
- 新功能添加
- 文档
- 推广
您将收获:
- Luckysheet官方readme文档贡献者链接
- 参与大型开源项目,技术和视野提升
## 交流
@ -171,7 +181,10 @@ npm run build
[英文社群](./README.md)
## 贡献者和感谢
- [@wbfsa](https://github.com/wbfsa)
- [@wpxp123456](https://github.com/wpxp123456)
- [@swen-xiong](https://github.com/swen-xiong)
- [@tonytonychopper123](https://github.com/tonytonychopper123)
- [@Dushusir](https://github.com/Dushusir)
## 版权信息

26
README.md

@ -22,6 +22,10 @@ English| [简体中文](./README-zh.md)
![Demo](/docs/.vuepress/public/img/LuckysheetDemo.gif)
## Plugins
- Excel import and export library: [Luckyexcel](https://github.com/mengshukeji/Luckyexcel)
- Chart plugin: [chartMix](https://github.com/mengshukeji/chartMix)
## Features
### 🛠️Formatting
@ -91,6 +95,7 @@ English| [简体中文](./README-zh.md)
+ **Matrix operation** (Operate selection through the right-click menu: transpose, rotate, numerical calculation)
+ **Screenshot** (Take a screenshot with selection)
+ **Copy to** (In the right-click menu, copy selection to json, array etc.)
+ **EXCEL,CSV,TXT import/export** (Specially adapted to Luckysheet)
### ⏱️Coming soon
+ **Insert picture and Shapes** (JPG,PNG,SVG,Pen tool and so on)
@ -99,7 +104,6 @@ English| [简体中文](./README-zh.md)
+ **Cell segmentation style** (Alt+Enter line break, sub,super, in-cell style)
+ **Tree menu** (Just like the outline (group) function of excel)
+ **Table new Features** (filter, slicer)
+ **EXCEL,CSV,TXT import/export** (Specially adapted to Luckysheet)
+ **Documentation** (Improve documentation and API)
+ **More...** (Please advise us)
@ -154,13 +158,20 @@ Create a table
})
</script>
```
## Join the co-construction
If you want to implement an important function for Luckysheet, you need to write an RFC document first, follow Luckysheet's [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) to operate, and submit the code after community discussion and improvement.
## Co-construction
## Contact
- Welcome to submit PR or [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose)
- Email: mengshu@office2.cn
1. Any questions or suggestions are welcome to submit [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose)
2. If you want to implement an important function for Luckysheet, you need to write an RFC document first, follow Luckysheet's [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) mechanism to operate, and only after community discussion and improvement, you can submit the code.
3. If you are interested in Luckysheet, you are very welcome to join the development team to improve this plugin together (Email: alexads@foxmail.com), there are 4 types of tasks that can be claimed
- BUG
- New features
- Documentation
- Popularize
You will gain:
- Luckysheet official readme document contributor link
- Participate in large open source projects, improve technology and vision
## Communication
@ -169,7 +180,10 @@ If you want to implement an important function for Luckysheet, you need to write
[Chinese community](./README-zh.md)
## Authors and acknowledgment
- [@wbfsa](https://github.com/wbfsa)
- [@wpxp123456](https://github.com/wpxp123456)
- [@swen-xiong](https://github.com/swen-xiong)
- [@tonytonychopper123](https://github.com/tonytonychopper123)
- [@Dushusir](https://github.com/Dushusir)
## License

8
docs/guide/data.md

@ -26,7 +26,7 @@
"rowlen":{}, //Table row height
"columnlen":{}, //Table column width
"rowhidden":{}, //hidden rows
"columnhidden":{}, //hidden columns
"colhidden":{}, //hidden columns
"borderInfo":{}, //borders
},
"celldata": [], //initialize the cell data used
@ -204,15 +204,15 @@
}
```
### config.columnhidden
### config.colhidden
- Type:Object
- Default:{}
- Usage:Hidden column information, Columns:`columnhidden[Columns]: 0`,
- Usage:Hidden column information, Columns:`colhidden[Columns]: 0`,
`key` specify the number of columns,`value` is always `0`
- example:
```js
"columnhidden": {
"colhidden": {
"30": 0,
"31": 0
}

2
docs/zh/guide/README.md

@ -171,7 +171,7 @@ luckysheetfile = [ {sheet1设置}, {sheet2设置}, {sheet3设置} ]`
"rowlen":{}, //表格行高
"columnlen":{}, //表格列宽
"rowhidden":{}, //隐藏行
"columnhidden":{}, //隐藏列
"colhidden":{}, //隐藏列
"borderInfo":{}, //边框
},
"celldata": [], //初始化使用的单元格数据

95
docs/zh/guide/api.md

@ -50,7 +50,9 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
- **说明**
设置某个单元格的值,也可以设置整个单元格对象,用于同时设置多个单元格属性
设置某个单元格的值,也可以设置整个单元格对象,用于同时设置多个单元格属性。
如果需要更新公式,也可以在这里赋值,Luckysheet在内部会主动把这个公式做计算并加入到公式链中,最后重刷界面。
- **示例**:
@ -59,6 +61,54 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
------------
### clearCell(row, column [,setting])
- **参数**
- {Number} [row]: 单元格所在行数;从0开始的整数,0表示第一行
- {Number} [column]: 单元格所在列数;从0开始的整数,0表示第一列
- {PlainObject} [setting]: 可选参数
+ {Number} [order]: 工作表索引;默认值为当前工作表索引
+ {Function} [success]: 操作结束的回调函数
- **说明**
清除指定工作表指定单元格的内容,返回清除掉的数据,不同于删除单元格的功能,不需要设定单元格移动情况
- **示例**:
- 清空单元格`B2`内容
`luckysheet.clearCell(1,1)`
------------
### deleteCell(move, row, column [,setting])
- **参数**
- {String} [move]: 删除后,右侧还是下方的单元格移动
`move`可能的值有:
+ `"left"`: 右侧单元格左移
+ `"up"`: 下方单元格上移
- {Number} [row]: 单元格所在行数;从0开始的整数,0表示第一行
- {Number} [column]: 单元格所在列数;从0开始的整数,0表示第一列
- {PlainObject} [setting]: 可选参数
+ {Number} [order]: 工作表索引;默认值为当前工作表索引
+ {Function} [success]: 操作结束的回调函数
- **说明**
删除指定工作表指定单元格,返回删除掉的数据,同时,指定是右侧单元格左移还是下方单元格上移
- **示例**:
- 删除当前单元格并且在删除后,右侧单元格左移
`luckysheet.deleteCell('left')`
------------
### setCellFormat(row, column, attr, value [,setting])
- **参数**
@ -66,9 +116,9 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
- {Number} [row]: 单元格所在行数;从0开始的整数,0表示第一行
- {Number} [column]: 单元格所在列数;从0开始的整数,0表示第一列
- {String} [attr]: 属性类型,参考 [单元格属性表](/zh/guide/cell.html)的属性值
- {String | Number | Object} [value]: 具体的设置值,一个属性会对应多个值,参考 [单元格属性表](/zh/guide/cell.html)的值示例,特殊情况:如果属性类型`attr`是单元格格式`ct`,则设置值`value`应提供`ct.fa`,比如设置A1单元格的格式为百分比格式:
- {String | Number | Object} [value]: 具体的设置值,一个属性会对应多个值,参考 [单元格属性表](/zh/guide/cell.html)的值示例,如果属性类型`attr`是单元格格式`ct`,则设置值`value`应提供ct对象,如:`{fa:"General", t:"g"}`,比如设置A1单元格的格式为百分比格式:
`luckysheet.setCellFormat(0, 0, "ct", "0.00%")`
`luckysheet.setCellFormat(0, 0, "ct", {fa:"0.00%", t:"n"})`
- {PlainObject} [setting]: 可选参数
+ {Number} [order]: 工作表索引;默认值为当前工作表索引
@ -143,7 +193,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
- **示例**:
- 当前工作表查找`"value"`字符串并替换为`"out"`
`luckysheet.replaces("value", "out)`
`luckysheet.replace("value", "out")`
------------
@ -910,6 +960,8 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
将一个单元格数组数据赋值到指定的区域,数据格式同`getRangeValue`方法取到的数据。
注意一点,通常`getRangeValue`方法只是取得选区数据,但是不包含边框和合并单元格信息,当执行`setRangeValue`的时候,会动态判断上一步是否执行过`getRangeValue`,如果执行过,会将边框和合并单元格信息一并从Luckysheet配置中取得。
- **示例**:
+ 赋值到当前选区
@ -1810,6 +1862,41 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开
`luckysheet.setSheetMove("left")`
- 第二个工作表移动到第四个工作表的索引位置
`luckysheet.setSheetMove(3,{order:1})`
------------
### setSheetOrder(orderList [,setting])
- **参数**
- {Array} [orderList]: 工作表顺序,设置工作表的index和order来指定位置,如:
```json
[
{index:'sheet_01',order: 2},
{index:'sheet_02',order: 1},
{index:'sheet_03',order: 0},
]
```
数组中顺序并不重要,关键是指定sheet index和order的对应关系。
- {PlainObject} [setting]: 可选参数
+ {Function} [success]: 操作结束的回调函数
- **说明**
重新排序所有工作表的位置,指定工作表顺序的数组。
- **示例**:
- 重排工作表,此工作簿含有3个工作表
```js
luckysheet.setSheetOrder([
{index:'sheet_01',order: 2},
{index:'sheet_02',order: 1},
{index:'sheet_03',order: 0},
])
```
------------

9
docs/zh/guide/cell.md

@ -147,6 +147,15 @@
</td>
<td></td>
</tr>
<tr>
<td>ae</td>
<td>allowEdit</td>
<td>是否允许编辑</td>
<td>
0: 只读,不可编辑 1:可以编辑,默认为 1
</td>
<td></td>
</tr>
</table>
一个规范的单元格对象如下:

268
docs/zh/guide/config.md

@ -22,48 +22,59 @@ luckysheet.create(options)
这里的`options`配置项会作用于整个表格,特别的,单个sheet的配置则需要在`options.data`数组中,分别设置对应更详细的参数,参考[工作表配置](/zh/guide/sheet.html)
针对个性化的需求,除了允许配置名称栏([showinfobar](#showinfobar))、工具栏([showtoolbar](#showtoolbar))、底部sheet页([showsheetbar](#showsheetbar))、底部计数栏([showstatisticBar](#showstatisticBar))之外,
Luckysheet开放了更细致的自定义配置选项,分别有
- 自定义工具栏([showtoolbarConfig](#showtoolbarConfig))
- 自定义底部sheet页([showsheetbarConfig](#showsheetbarConfig))
- 自定义计数栏([showstatisticBarConfig](#showstatisticBarConfig))
- 自定义添加行和回到顶部([sheetBottomConfig](#sheetBottomConfig))
- 自定义单元格右键菜单([cellRightClickConfig](#cellRightClickConfig))
- 自定义sheet页右击菜单([sheetRightClickConfig](#sheetRightClickConfig))
## 配置项
以下为所有支持的设置参数
- [container](#container)
- [title](#title)
- [lang](#lang)
- [gridKey](#gridKey)
- [loadUrl](#loadUrl)
- [loadSheetUrl](#loadSheetUrl)
- [allowUpdate](#allowUpdate)
- [updateUrl](#updateUrl)
- [updateImageUrl](#updateImageUrl)
- [data](#data)
- [plugins](#plugins)
- [column](#column)
- [row](#row)
- [autoFormatw](#autoFormatw)
- [accuracy](#accuracy)
- [allowCopy](#allowCopy)
- [showtoolbar](#showtoolbar)
- [showtoolbarConfig](#showtoolbarConfig)
- [showinfobar](#showinfobar)
- [showsheetbar](#showsheetbar)
- [showsheetbarConfig](#showsheetbarConfig)
- [showstatisticBar](#showstatisticBar)
- [showstatisticBarConfig](#showstatisticBarConfig)
- [allowEdit](#allowEdit)
- [enableAddRow](#enableAddRow)
- [enableAddCol](#enableAddCol)
- [userInfo](#userInfo)
- [userMenuItem](#userMenuItem)
- [myFolderUrl](#myFolderUrl)
- [devicePixelRatio](#devicePixelRatio)
- [functionButton](#functionButton)
- [showConfigWindowResize](#showConfigWindowResize)
- [enablePage](#enablePage)
- [fullscreenmode](#fullscreenmode)
- [beforeCreateDom](#beforeCreateDom)
- [fireMousedown](#fireMousedown)
- [forceCalculation](#forceCalculation)
- [rightClickConfig](#rightClickConfig)
- 容器ID [container](#container)
- 工作簿名称 [title](#title)
- 语言 [lang](#lang)
- 唯一key [gridKey](#gridKey)
- 加载整个工作簿 [loadUrl](#loadUrl)
- 加载其它页celldata [loadSheetUrl](#loadSheetUrl)
- 允许更新 [allowUpdate](#allowUpdate)
- 更新地址 [updateUrl](#updateUrl)
- 缩略图更新地址 [updateImageUrl](#updateImageUrl)
- 工作表配置 [data](#data)
- 插件 [plugins](#plugins)
- 列数 [column](#column)
- 行数 [row](#row)
- 亿万格式 [autoFormatw](#autoFormatw)
- 精度 [accuracy](#accuracy)
- 允许复制 [allowCopy](#allowCopy)
- 工具栏 [showtoolbar](#showtoolbar)
- 自定义工具栏[showtoolbarConfig](#showtoolbarConfig)
- 名称栏 [showinfobar](#showinfobar)
- 底部sheet页 [showsheetbar](#showsheetbar)
- 自定义底部sheet页 [showsheetbarConfig](#showsheetbarConfig)
- 底部计数栏 [showstatisticBar](#showstatisticBar)
- 自定义计数栏 [showstatisticBarConfig](#showstatisticBarConfig)
- 自定义添加行和回到顶部 [sheetBottomConfig](#sheetBottomConfig)
- 允许编辑 [allowEdit](#allowEdit)
- 允许增加行 [enableAddRow](#enableAddRow)
- 允许增加列 [enableAddCol](#enableAddCol)
- 用户信息 [userInfo](#userInfo)
- 用户信息菜单 [userMenuItem](#userMenuItem)
- 返回按钮链接 [myFolderUrl](#myFolderUrl)
- 比例 [devicePixelRatio](#devicePixelRatio)
- 功能按钮 [functionButton](#functionButton)
- 自动缩进界面 [showConfigWindowResize](#showConfigWindowResize)
- 加载下一页 [enablePage](#enablePage)
- 全屏模式 [fullscreenmode](#fullscreenmode)
- 刷新公式 [forceCalculation](#forceCalculation)
- 自定义单元格右键菜单 [cellRightClickConfig](#cellRightClickConfig)
- 自定义sheet页右击菜单 [sheetRightClickConfig](#sheetRightClickConfig)
### container
- 类型:String
@ -74,7 +85,7 @@ luckysheet.create(options)
### title
- 类型:String
- 默认值:"Luckysheet Demo"
- 作用:表格的名称
- 作用:工作簿名称
------------
### lang
@ -167,7 +178,7 @@ luckysheet.create(options)
- 作用:是否第二列显示工具栏
------------
#### showtoolbarConfig
### showtoolbarConfig
- 类型:Object
- 默认值:{}
- 作用:自定义配置工具栏
@ -218,13 +229,13 @@ luckysheet.create(options)
### showsheetbar
- 类型:Boolean
- 默认值:true
- 作用:是否显示底部表格名称区域
- 作用:是否显示底部sheet页按钮
------------
### showsheetbarConfig
- 类型:Object
- 默认值:{}
- 作用:自定义配置底部表格名称区域
- 作用:自定义配置底部sheet页按钮
- 格式:
```json
{
@ -252,6 +263,18 @@ luckysheet.create(options)
zoom: false // 缩放
}
------------
### sheetBottomConfig
- 类型:Object
- 默认值:{}
- 作用:sheet页下方的添加行按钮和回到顶部按钮配置
- 格式:
```json
{
addRow: false, // 添加行按钮
backTop: false // 回到顶部
}
------------
### allowEdit
- 类型:Boolean
@ -318,18 +341,6 @@ luckysheet.create(options)
- 默认值:true
- 作用:是否全屏模式。非全屏模式下,标记框不会强制选中
------------
### beforeCreateDom
- 类型:Function
- 默认值:null
- 作用:表格创建之前自定义方法
------------
### fireMousedown
- 类型:Function
- 默认值:null
- 作用:单元格数据下钻自定义方法
------------
### forceCalculation
- 类型:Boolean
@ -343,33 +354,54 @@ luckysheet.create(options)
⚠️提醒,公式较多时会有性能问题,慎用!
------------
### rightClickConfig
### cellRightClickConfig
- 类型:Object
- 默认值:{}
- 作用:自定义配置右击菜单
- 作用:自定义配置单元格右击菜单
- 格式:
```json
{
copy:false, // '复制'
copyAs:false, // '复制为'
paste:false, // '粘贴',
insert:false, // '插入',
delete:false, // '删除',
hide:false, // '隐藏',
deleteCell:false, // '删除单元格',
clear:false, // '清除内容',
matrix:false, // '矩阵操作选区',
sort:false, // '排序选区',
filter:false, //'筛选选区',
chart:false, // '图表生成',
copy: false, // '复制'
copyAs: false, // '复制为'
paste: false, // '粘贴'
insert: false, // '插入'
delete: false, // '删除'
hide: false, // '隐藏'
deleteCell: false, // '删除单元格'
clear: false, // '清除内容'
matrix: false, // '矩阵操作选区'
sort: false, // '排序选区'
filter: false, //'筛选选区'
chart: false // '图表生成'
}
## 钩子函数
------------
### sheetRightClickConfig
- 类型:Object
- 默认值:{}
- 作用:自定义配置sheet页右击菜单
- 格式:
```json
{
delete: false, // '删除'
copy: false, // '复制'
rename: false, //重命名
color: false, //更改颜色
hide: false, //隐藏
show: false, //取消隐藏
left: false, //向左移
right: false //向右移
}
------------
## 钩子函数(TODO)
钩子函数应用于二次开发时,会在各个常用鼠标或者键盘操作时植入钩子,调用开发者传入的函数,起到扩展Luckysheet功能的作用。
钩子函数统一配置在`options.hook`下,可以分别针对单元格、sheet页、表格创建配置hook
钩子函数统一配置在`options.hook`下,可以分别针对单元格、sheet页、表格创建配置hook
------------
### cellHover
- 类型:Function
- 默认值:null
@ -380,38 +412,116 @@ luckysheet.create(options)
- {Object} [v]: 单元格对象
------------
### cellClickBefore
- 类型:Function
- 默认值:null
- 作用:点击单元格前触发,即在点击单元格的时候,最先触发这个方法
- 参数:
- {Number} [r]: 单元格所在行数
- {Number} [c]: 单元格所在列数
- {Object} [v]: 单元格对象
------------
### cellClickAfter
### cellClicked
- 类型:Function
- 默认值:null
- 作用:点击单元格后触发,即在点击单元格的时候,最后触发这个方法
- 参数:
- {Number} [r]: 单元格所在行数
- {Number} [c]: 单元格所在列数
- {Object} [v]: 单元格对象
------------
### cellEditBefore
- 类型:Function
- 默认值:null
- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最先触发这个方法
- 参数:
- {Number} [r]: 单元格所在行数
- {Number} [c]: 单元格所在列数
- {Object} [v]: 单元格对象
------------
### cellEdited
- 类型:Function
- 默认值:null
- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最后触发这个方法
- 参数:
- {Number} [r]: 单元格所在行数
- {Number} [c]: 单元格所在列数
- {Object} [oldV]: 修改前单元格对象
- {Object} [newV]: 修改后单元格对象
------------
### sheetClickBefore
- 类型:Function
- 默认值:null
- 作用:点击sheet页前触发
- 参数:
- {Number} [i]: sheet页的index
- {Object} [sheet]: sheet页的配置
------------
### sheetClickAfter
### sheetClicked
- 类型:Function
- 默认值:null
- 作用:点击sheet页后触发
- 参数:
- {Number} [i]: sheet页的index
- {Object} [sheet]: sheet页的配置
------------
### sheetClickAfter
### workbookCreateBefore
- 类型:Function
- 默认值:null
- 作用:点击sheet页后触发
- 作用:表格创建之前触发。旧的钩子函数叫做`beforeCreateDom`
- 参数:
- {Object} [book]: 整个工作簿的配置(options)
------------
### workbookCreated
- 类型:Function
- 默认值:null
- 作用:表格创建之后触发
- 参数:
- {Object} [book]: 整个工作簿的配置(options)
------------
### workbookUpdated
- 类型:Function
- 默认值:null
- 作用:表格创建之后触发
- 参数:
- {Object} [book]: 整个工作簿的配置(options)
------------
### workbookDestroyBefore
- 类型:Function
- 默认值:null
- 作用:表格创建之后触发
- 参数:
- {Object} [book]: 整个工作簿的配置(options)
------------
### workbookDestroyed
- 类型:Function
- 默认值:null
- 作用:表格创建之后触发
- 参数:
- {Object} [book]: 整个工作簿的配置(options)
------------
### updated
- 类型:Function
- 默认值:null
- 作用:每次操作更新后执行的方法,即客户端每执行一次表格操作,Luckysheet将这次操作存到历史记录中后触发,撤销时因为也算一次操作,当然也会触发此钩子函数。
- 参数:
- {Object} [operate]: 本次操作的历史记录信息,根据不同的操作,会有不同的历史记录,参考源码 [历史记录](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/controlHistory.js)
------------
### fireMousedown
- 类型:Function
- 默认值:null
- 作用:单元格数据下钻自定义方法
------------

192
docs/zh/guide/operate.md

@ -8,6 +8,8 @@
以下为所有的支持传输到后台的操作类型,并且以MongoDB做存储示例,讲解如何做前后端交互。
注意一点,对象中的i为当前sheet的index值,而不是order。
## 单元格刷新
### 单个单元格刷新
@ -33,7 +35,7 @@
|参数|说明|
| ------------ | ------------ |
|t|操作类型表示符号|
|i|当前sheet的索引值|
|i|当前sheet的index值|
|v|单元格的值,数字、字符串或着对象格式,对象参考 [单元格属性表](/zh/guide/cell.html#基本单元格)|
|r|单元格的行号|
|c|单元格的列号|
@ -113,7 +115,7 @@
|t|操作类型表示符号|
|i|当前sheet的index值|
|v|需要更新value值|
|k|操作的key值,可选 边框:`'borderInfo'` / :行隐藏:`'rowhidden'` / 列隐藏:`'columnhidden'` / 行高:`'rowlen'` / 列宽:`'columnlen'` |
|k|操作的key值,可选 边框:`'borderInfo'` / :行隐藏:`'rowhidden'` / 列隐藏:`'colhidden'` / 行高:`'rowlen'` / 列宽:`'columnlen'` |
- **后台更新**
@ -1079,4 +1081,188 @@
- **后台更新**
Luckysheet配置,修改title为`"Luckysheet Demo1"`
Luckysheet配置,修改title为`"Luckysheet Demo1"`
## 图表(TODO)
图表操作类型有4种,分别为新增图表"add"、移动图表位置"xy"、缩放图表"wh"、修改图表配置"update"
### 新增图表
- **格式**
```json
{
"t": "c",
"i": 0,
"op":"add",
"v": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"width": 400,
"height": 250,
"left": 20,
"top": 120,
"sheetIndex": "Sheet_6az6nei65t1i_1596209937084",
"needRangeShow": true,
"chartOptions": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"chartAllType": "echarts|line|default",
"rangeArray": [ { "row": [ 0, 4 ], "column": [ 0, 7 ] } ],
"rangeColCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeRowCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeConfigCheck": false,
"defaultOption": {
"title": {
"show": true,
"text": "默认标题"
}
}
},
"isShow": true
}
}
```
- **说明**
|参数|说明|
| ------------ | ------------ |
|t|操作类型表示符号|
|i|当前sheet的index值|
|op|操作选项|
|v|图表的配置信息|
- **后台更新**
更新对应sheet页中的图表设置,如果`luckysheetfile[i].chart`为null,则初始化为空数组 `[]`
```json
luckysheetfile[0].chart.push(v)
```
### 移动图表位置
- **格式**
```json
{
"t": "c",
"i": 0,
"op":"xy",
"v": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"left": 20,
"top": 120
}
}
```
- **说明**
|参数|说明|
| ------------ | ------------ |
|t|操作类型表示符号|
|i|当前sheet的index值|
|op|操作选项|
|v|图表的配置信息|
- **后台更新**
更新对应sheet页中的图表设置
```js
luckysheetfile[0].chart[v.chart_id].left = v.left;
luckysheetfile[0].chart[v.chart_id].top = v.top;
```
### 缩放图表
- **格式**
```json
{
"t": "c",
"i": 0,
"op":"wh",
"v": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"width": 400,
"height": 250,
"left": 20,
"top": 120
}
}
```
- **说明**
|参数|说明|
| ------------ | ------------ |
|t|操作类型表示符号|
|i|当前sheet的index值|
|op|操作选项|
|v|图表的配置信息|
- **后台更新**
更新对应sheet页中的图表设置
```js
luckysheetfile[0].chart[v.chart_id].left = v.left;
luckysheetfile[0].chart[v.chart_id].top = v.top;
luckysheetfile[0].chart[v.chart_id].width = v.width;
luckysheetfile[0].chart[v.chart_id].height = v.height;
```
### 修改图表配置
- **格式**
```json
{
"t": "c",
"i": 0,
"op":"update",
"v": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"width": 400,
"height": 250,
"left": 20,
"top": 120,
"sheetIndex": "Sheet_6az6nei65t1i_1596209937084",
"needRangeShow": true,
"chartOptions": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"chartAllType": "echarts|line|default",
"rangeArray": [ { "row": [ 0, 4 ], "column": [ 0, 7 ] } ],
"rangeColCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeRowCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeConfigCheck": false,
"defaultOption": {
"title": {
"show": true,
"text": "默认标题"
}
}
},
"isShow": true
}
}
```
- **说明**
|参数|说明|
| ------------ | ------------ |
|t|操作类型表示符号|
|i|当前sheet的index值|
|op|操作选项|
|v|图表的配置信息|
- **后台更新**
更新对应sheet页中的图表设置
```js
luckysheetfile[0].chart[v.chart_id] = v;
```

544
docs/zh/guide/sheet.md

@ -23,7 +23,7 @@ options.data示例如下:
"rowlen":{}, //表格行高
"columnlen":{}, //表格列宽
"rowhidden":{}, //隐藏行
"columnhidden":{}, //隐藏列
"colhidden":{}, //隐藏列
"borderInfo":{}, //边框
},
"scrollLeft": 0, //左右滚动条位置
@ -37,8 +37,10 @@ options.data示例如下:
"luckysheet_alternateformat_save": [], //交替颜色
"luckysheet_alternateformat_save_modelCustom": [], //自定义交替颜色
"luckysheet_conditionformat_save": {},//条件格式
"frozen": {}, //冻结行列
"frozen": {}, //冻结行列配置
"chart": [], //图表配置
"allowEdit": true, //是否允许编辑
"zoomRatio":1, // 缩放比例
},
{
"name": "Sheet2",
@ -219,16 +221,16 @@ options.data示例如下:
}
```
#### config.columnhidden
#### config.colhidden
- 类型:Object
- 默认值:{}
- 作用:隐藏列
格式为:`columnhidden[列数]: 0`,
格式为:`colhidden[列数]: 0`,
`key`指定列数即可,`value`总是为`0`
- 示例:
```js
"columnhidden": {
"colhidden": {
"30": 0,
"31": 0
}
@ -383,11 +385,11 @@ options.data示例如下:
- 示例:
```js
[{
"r": 6,
"c": 3,
"index": 1,
"func": [true, 23.75, "=AVERAGE(D3:D6)"],
"color": "w",
"r": 6, //行数
"c": 3, //列数
"index": 1, //工作表id
"func": [true, 23.75, "=AVERAGE(D3:D6)"], //公式信息,包含公式计算结果和公式字符串
"color": "w", //"w":采用深度优先算法 "b":普通计算
"parent": null,
"chidren": {},
"times": 0
@ -421,7 +423,7 @@ options.data示例如下:
"row": [0, 12],
"column": [0, 4]
},
"pivotDataSheetIndex": 6, //The sheet index where the source data is located
"pivotDataSheetIndex": 6, //源数据所在的sheet页
"column": [{
"index": 3,
"name": "subject",
@ -441,7 +443,7 @@ options.data示例如下:
"nameindex": 0
}],
"showType": "column",
"pivotDatas": [
"pivotDatas": [ //数据透视表的源数据
["count:score", "science", "mathematics", "foreign language", "English", "total"],
["Alex", 1, 1, 1, 1, 4],
["Joy", 1, 1, 1, 1, 4],
@ -510,30 +512,30 @@ options.data示例如下:
- 示例:
```js
[{
"cellrange": {
"cellrange": { //单元格范围
"row": [1, 6],
"column": [1, 5]
},
"format": {
"head": {
"head": { //页眉颜色
"fc": "#000",
"bc": "#5ed593"
},
"one": {
"one": { //第一种颜色
"fc": "#000",
"bc": "#ffffff"
},
"two": {
"two": { //第二种颜色
"fc": "#000",
"bc": "#e5fbee"
},
"foot": {
"foot": { //页脚颜色
"fc": "#000",
"bc": "#a5efcc"
}
},
"hasRowHeader": false,
"hasRowFooter": false
"hasRowHeader": false, //含有页眉
"hasRowFooter": false //含有页脚
}, {
"cellrange": {
"row": [1, 6],
@ -570,19 +572,19 @@ options.data示例如下:
- 示例:
```js
[{
"head": {
"head": { //页眉颜色
"fc": "#6aa84f",
"bc": "#ffffff"
},
"one": {
"one": { //第一种颜色
"fc": "#000",
"bc": "#ffffff"
},
"two": {
"two": { //第二种颜色
"fc": "#000",
"bc": "#e5fbee"
},
"foot": {
"foot": { //页脚颜色
"fc": "#000",
"bc": "#a5efcc"
}
@ -603,22 +605,23 @@ options.data示例如下:
"colorGradation": 色阶
API中对此设置也有介绍[API setRangeConditionalFormat](/zh/guide/api.html)
- 示例:
```js
[
{
"type": "default",
"cellrange": [
"cellrange": [ //应用的范围
{
"row": [ 2, 7 ],
"column": [ 2, 2 ]
}
],
"format": {
"format": { //type 为 default 时 应设置文本颜色和单元格颜色
"textColor": "#000000",
"cellColor": "#ff0000"
},
"conditionName": "betweenness",
"conditionName": "betweenness", //类型
"conditionRange": [
{
"row": [ 4, 4 ],
@ -721,7 +724,486 @@ options.data示例如下:
### chart
- 类型:Array
- 默认值:[]
- 作用: 图表配置
- 作用: 图表配置,参照chartMix的配置格式,允许只设置想要的图表属性,一个完整的配置案例如下。
- 示例:
:::::: details
```json
{
"chart_id": "chart_p145W6i73otw_1596209943446",
"width": 400,
"height": 250,
"left": 20,
"top": 120,
"sheetIndex": "Sheet_6az6nei65t1i_1596209937084",
"needRangeShow": true,
"chartOptions": {
"chart_id": "chart_p145W6i73otw_1596209943446",
"chartAllType": "echarts|line|default",
"rangeArray": [ { "row": [ 0, 4 ], "column": [ 0, 7 ] } ],
"rangeColCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeRowCheck": { "exits": true, "range": [ 0, 0 ] },
"rangeConfigCheck": false,
"defaultOption": {
"title": {
"show": false,
"text": "默认标题",
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"position": {
"value": "left-top",
"offsetX": 40,
"offsetY": 50
}
},
"subtitle": {
"show": false,
"text": "",
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"distance": {
"value": "auto",
"cusGap": 40
}
},
"config": {
"color": "transparent",
"fontFamily": "Sans-serif",
"grid": {
"value": "normal",
"top": 5,
"left": 10,
"right": 20,
"bottom": 10
}
},
"legend": {
"show": true,
"selectMode": "multiple",
"selected": [
{
"seriesName": "衣服",
"isShow": true
},
{
"seriesName": "食材",
"isShow": true
},
{
"seriesName": "图书",
"isShow": true
}
],
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"position": {
"value": "left-top",
"offsetX": 40,
"offsetY": 50,
"direction": "horizontal"
},
"width": {
"value": "auto",
"cusSize": 25
},
"height": {
"value": "auto",
"cusSize": 14
},
"distance": {
"value": "auto",
"cusGap": 10
},
"itemGap": 10,
"data": [
"Mon",
"Tues",
"Wed",
"Thur",
"Fri",
"Sat",
"Sun"
]
},
"tooltip": {
"show": true,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"backgroundColor": "rgba(50,50,50,0.7)",
"triggerOn": "mousemove",
"triggerType": "item",
"axisPointer": {
"type": "line",
"style": {
"color": "#555",
"width": "normal",
"type": "solid"
}
},
"format": [
{
"seriesName": "衣服",
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto"
},
{
"seriesName": "食材",
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto"
},
{
"seriesName": "图书",
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto"
}
],
"position": "auto"
},
"axis": {
"axisType": "xAxisDown",
"xAxisUp": {
"show": false,
"title": {
"showTitle": false,
"text": "",
"nameGap": 15,
"rotate": 0,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"fzPosition": "end"
},
"name": "显示X轴",
"inverse": false,
"tickLine": {
"show": true,
"width": 1,
"color": "auto"
},
"tick": {
"show": true,
"position": "outside",
"length": 5,
"width": 1,
"color": "auto"
},
"tickLabel": {
"show": true,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"rotate": 0,
"prefix": "",
"suffix": "",
"optimize": 0,
"distance": 0,
"min": "auto",
"max": "auto",
"ratio": 1,
"digit": "auto"
},
"netLine": {
"show": false,
"width": 1,
"type": "solid",
"color": "auto",
"interval": {
"value": "auto",
"cusNumber": 0
}
},
"netArea": {
"show": false,
"interval": {
"value": "auto",
"cusNumber": 0
},
"colorOne": "auto",
"colorTwo": "auto"
},
"axisLine": {
"onZero": false
}
},
"xAxisDown": {
"show": true,
"title": {
"showTitle": false,
"text": "",
"nameGap": 15,
"rotate": 0,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"fzPosition": "end"
},
"name": "显示X轴",
"inverse": false,
"tickLine": {
"show": true,
"width": 1,
"color": "auto"
},
"tick": {
"show": true,
"position": "outside",
"length": 5,
"width": 1,
"color": "auto"
},
"tickLabel": {
"show": true,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"rotate": 0,
"prefix": "",
"suffix": "",
"optimize": 0,
"distance": 0,
"min": null,
"max": null,
"ratio": 1,
"digit": "auto"
},
"netLine": {
"show": false,
"width": 1,
"type": "solid",
"color": "auto",
"interval": {
"value": "auto",
"cusNumber": 0
}
},
"netArea": {
"show": false,
"interval": {
"value": "auto",
"cusNumber": 0
},
"colorOne": "auto",
"colorTwo": "auto"
},
"data": [
"BUS",
"UBER",
"TAXI",
"SUBWAY"
],
"type": "category"
},
"yAxisLeft": {
"show": true,
"title": {
"showTitle": false,
"text": "",
"nameGap": 15,
"rotate": 0,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"fzPosition": "end"
},
"name": "显示Y轴",
"inverse": false,
"tickLine": {
"show": true,
"width": 1,
"color": "auto"
},
"tick": {
"show": true,
"position": "outside",
"length": 5,
"width": 1,
"color": "auto"
},
"tickLabel": {
"show": true,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"rotate": 0,
"formatter": {
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto"
},
"split": 5,
"min": null,
"max": null,
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto",
"distance": 0
},
"netLine": {
"show": false,
"width": 1,
"type": "solid",
"color": "auto",
"interval": {
"value": "auto",
"cusNumber": 0
}
},
"netArea": {
"show": false,
"interval": {
"value": "auto",
"cusNumber": 0
},
"colorOne": "auto",
"colorTwo": "auto"
},
"type": "value"
},
"yAxisRight": {
"show": false,
"title": {
"showTitle": false,
"text": "",
"nameGap": 15,
"rotate": 0,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"fzPosition": "end"
},
"name": "显示Y轴",
"inverse": false,
"tickLine": {
"show": true,
"width": 1,
"color": "auto"
},
"tick": {
"show": true,
"position": "outside",
"length": 5,
"width": 1,
"color": "auto"
},
"tickLabel": {
"show": true,
"label": {
"fontSize": 12,
"color": "#333",
"fontFamily": "sans-serif",
"fontGroup": [],
"cusFontSize": 12
},
"rotate": 0,
"formatter": {
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto"
},
"split": 5,
"min": null,
"max": null,
"prefix": "",
"suffix": "",
"ratio": 1,
"digit": "auto",
"distance": 0
},
"netLine": {
"show": false,
"width": 1,
"type": "solid",
"color": "auto",
"interval": {
"value": "auto",
"cusNumber": 0
}
},
"netArea": {
"show": false,
"interval": {
"value": "auto",
"cusNumber": 0
},
"colorOne": "auto",
"colorTwo": "auto"
}
}
}
}
},
"isShow": true
}
```
:::
------------
### allowEdit
- 类型:Boolean
- 默认值:true
- 作用: 此sheet页是否允许编辑
------------
### zoomRatio
- 类型:Number
- 默认值:1
- 作用: 此sheet页的缩放比例,为0~1之间的二位小数数字。比如`0.1`、`0.56`
------------
@ -751,7 +1233,7 @@ Luckysheet在初始化完成之后进行的一系列操作,会将更多本地
"rowlen":{}, //表格行高
"columnlen":{}, //表格列宽
"rowhidden":{}, //隐藏行
"columnhidden":{}, //隐藏列
"colhidden":{}, //隐藏列
"borderInfo":{}, //边框
},
"scrollLeft": 0, //左右滚动条位置
@ -765,8 +1247,12 @@ Luckysheet在初始化完成之后进行的一系列操作,会将更多本地
"luckysheet_alternateformat_save": [], //交替颜色
"luckysheet_alternateformat_save_modelCustom": [], //自定义交替颜色
"luckysheet_conditionformat_save": {},//条件格式
"freezen": {}, //冻结行列
"frozen": {}, //冻结行列配置
"freezen": {}, //冻结行列的渲染数据存储
"chart": [], //图表配置
"allowEdit": true, //是否允许编辑
"zoomRatio":1, // 缩放比例
"visibledatarow": [], //所有行的位置
"visibledatacolumn": [], //所有列的位置

2
src/config.js

@ -54,4 +54,6 @@ export default {
forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用
rowHeaderWidth: 46,
columeHeaderHeight: 20,
defaultColWidth:73,
defaultRowHeight:19,
}

55
src/controllers/constant.js

@ -127,6 +127,57 @@ const gridHTML = function(){
<div id="luckysheet-postil-showBoxs"></div>
<div id="luckysheet-multipleRange-show"></div>
<div id="luckysheet-dynamicArray-hightShow"></div>
<div id="luckysheet-image-showBoxs">
<div id="luckysheet-modal-dialog-activeImage" class="luckysheet-modal-dialog" style="display:none;padding:0;position:absolute;z-index:300;">
<div class="luckysheet-modal-dialog-content"></div>
<div class="luckysheet-modal-dialog-resize">
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-lt" data-type="lt"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-mt" data-type="mt"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-lm" data-type="lm"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-rm" data-type="rm"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-rt" data-type="rt"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-lb" data-type="lb"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-mb" data-type="mb"></div>
<div class="luckysheet-modal-dialog-resize-item luckysheet-modal-dialog-resize-item-rb" data-type="rb"></div>
</div>
<div class="luckysheet-modal-dialog-controll">
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-crop" role="button" tabindex="0" aria-label="裁剪" title="裁剪">
<i class="fa fa-pencil" aria-hidden="true"></i>
</span>
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-restore" role="button" tabindex="0" aria-label="恢复原图" title="恢复原图">
<i class="fa fa-window-maximize" aria-hidden="true"></i>
</span>
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-del" role="button" tabindex="0" aria-label="删除" title="删除">
<i class="fa fa-trash" aria-hidden="true"></i>
</span>
</div>
</div>
<div id="luckysheet-modal-dialog-cropping" class="luckysheet-modal-dialog" style="display:none;padding:0;position:absolute;z-index:300;">
<div class="cropping-mask"></div>
<div class="cropping-content"></div>
<div class="luckysheet-modal-dialog-resize">
<div class="resize-item lt" data-type="lt"></div>
<div class="resize-item mt" data-type="mt"></div>
<div class="resize-item lm" data-type="lm"></div>
<div class="resize-item rm" data-type="rm"></div>
<div class="resize-item rt" data-type="rt"></div>
<div class="resize-item lb" data-type="lb"></div>
<div class="resize-item mb" data-type="mb"></div>
<div class="resize-item rb" data-type="rb"></div>
</div>
<div class="luckysheet-modal-dialog-controll">
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-crop" role="button" tabindex="0" aria-label="裁剪" title="裁剪">
<i class="fa fa-pencil" aria-hidden="true"></i>
</span>
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-restore" role="button" tabindex="0" aria-label="恢复原图" title="恢复原图">
<i class="fa fa-window-maximize" aria-hidden="true"></i>
</span>
<span class="luckysheet-modal-controll-btn luckysheet-modal-controll-del" role="button" tabindex="0" aria-label="删除" title="删除">
<i class="fa fa-trash" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<div class="luckysheet-cell-copy"></div>
<div class="luckysheet-grdblkflowpush"></div> \${flow}
</div>
@ -1209,6 +1260,10 @@ function menuToolBar (){
<i class="fa fa-gg">
</i>
${toolbar.splitColumn}
</div>
<div class="luckysheetfulltoolbar" id="luckysheet-insertImg-btn-title">
插入图片
<input id="luckysheet-imgUpload" type="file" accept="image/*" style="display:none;">
</div>`;
}

187
src/controllers/handler.js

@ -4,6 +4,7 @@ import luckysheetFreezen from './freezen';
import pivotTable from './pivotTable';
import luckysheetDropCell from './dropCell';
import luckysheetPostil from './postil';
import imageCtrl from './imageCtrl';
import menuButton from './menuButton';
import conditionformat from './conditionformat';
import alternateformat from './alternateformat';
@ -1114,7 +1115,7 @@ export default function luckysheetHandler() {
});
//表格mousemove
$(document).mousemove(function (event) {
$(document).on("mousemove.luckysheetEvent",function (event) {
luckysheetPostil.overshow(event); //有批注显示
window.cancelAnimationFrame(Store.jfautoscrollTimeout);
@ -1945,6 +1946,119 @@ export default function luckysheetHandler() {
// resize chart
Store.resizeChart(Store.chartparam.luckysheetCurrentChart)
}
//image move
else if (imageCtrl.move) {
let mouse = mouseposition(event.pageX, event.pageY);
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
let y = mouse[1] + $("#luckysheet-cell-main").scrollTop();
let myh = $("#luckysheet-modal-dialog-activeImage").outerHeight(),
myw = $("#luckysheet-modal-dialog-activeImage").outerWidth();
let top = y - imageCtrl.moveXY[1],
left = x - imageCtrl.moveXY[0];
if (top < 0) {
top = 0;
}
if (top + myh + 42 + 6 > imageCtrl.currentWinH) {
top = imageCtrl.currentWinH - myh - 42 - 6;
}
if (left < 0) {
left = 0;
}
if (left + myw + 22 + 36 > imageCtrl.currentWinW) {
left = imageCtrl.currentWinW - myw - 22 - 36;
}
$("#luckysheet-modal-dialog-activeImage").css({ "left": left, "top": top });
}
//image resize
else if (!!imageCtrl.resize) {
let mouse = mouseposition(event.pageX, event.pageY);
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
let y = mouse[1] + $("#luckysheet-cell-main").scrollTop();
if (x < 0 || y < 0) {
return false;
}
let resizeXY = imageCtrl.resizeXY;
let topchange = y - resizeXY[1],
leftchange = x - resizeXY[0];
let top = resizeXY[5],
height = resizeXY[3],
left = resizeXY[4],
width = resizeXY[2];
let resize = imageCtrl.resize;
if (resize == "lm" || resize == "lt" || resize == "lb") {
left = x;
width = resizeXY[2] - leftchange;
if (left > resizeXY[2] + resizeXY[4] - 60) {
left = resizeXY[2] + resizeXY[4] - 60;
width = resizeXY[2] - (resizeXY[2] + resizeXY[4] - 60 - resizeXY[0]);
}
else if (left <= 0) {
left = 0;
width = resizeXY[2] + resizeXY[0];
}
}
if (resize == "rm" || resize == "rt" || resize == "rb") {
width = resizeXY[2] + leftchange;
if (width < 60) {
width = 60;
}
else if (width >= imageCtrl.currentWinW - resizeXY[4] - 22 - 36) {
width = imageCtrl.currentWinW - resizeXY[4] - 22 - 36;
}
}
if (resize == "mt" || resize == "lt" || resize == "rt") {
top = y;
height = resizeXY[3] - topchange;
if (top > resizeXY[3] + resizeXY[5] - 60) {
top = resizeXY[3] + resizeXY[5] - 60;
height = resizeXY[3] - (resizeXY[3] + resizeXY[5] - 60 - resizeXY[1]);
}
else if (top <= 0) {
top = 0;
height = resizeXY[3] + resizeXY[1];
}
}
if (resize == "mb" || resize == "lb" || resize == "rb") {
height = resizeXY[3] + topchange;
if (height < 60) {
height = 60;
}
else if (height >= imageCtrl.currentWinH - resizeXY[5] - 42 - 6) {
height = imageCtrl.currentWinH - resizeXY[5] - 42 - 6;
}
}
$("#luckysheet-modal-dialog-activeImage").css({
"width": width,
"height": height,
"left": left,
"top": top
});
$("#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content").css({
"background-size": width + "px " + height + "px",
"background-position": "0px 0px"
})
}
else if (luckysheetPostil.move) {
let mouse = mouseposition(event.pageX, event.pageY);
let x = mouse[0] + $("#luckysheet-cell-main").scrollLeft();
@ -2052,7 +2166,8 @@ export default function luckysheetHandler() {
}
else if (!!formula.rangeMove) {
formula.rangeMoveDraging(event, formula.rangeMovexy, formula.rangeMoveObj.data("range"), formula.rangeMoveObj, Store.sheetBarHeight, Store.statisticBarHeight);
} else if (!!Store.chart_selection.rangeResize) {
}
else if (!!Store.chart_selection.rangeResize) {
Store.chart_selection.rangeResizeDraging(event, Store.sheetBarHeight, Store.statisticBarHeight);
}
else if (!!Store.chart_selection.rangeMove) {
@ -2066,7 +2181,7 @@ export default function luckysheetHandler() {
}
});
//表格mouseup
$(document).mouseup(function (event) {
$(document).on("mouseup.luckysheetEvent",function (event) {
//数据窗格主体
if (Store.luckysheet_select_status) {
clearTimeout(Store.countfuncTimeout);
@ -2231,6 +2346,16 @@ export default function luckysheetHandler() {
formula.rangeResizeDragged(event, formula.rangeResizeObj, formula.rangeResize, formula.rangeResizexy, formula.rangeResizeWinW, formula.rangeResizeWinH);
}
//image move
if (imageCtrl.move) {
imageCtrl.moveImgItem();
}
//image resize
if (imageCtrl.resize) {
imageCtrl.resizeImgItem();
}
//批注框 移动
if (luckysheetPostil.move) {
luckysheetPostil.move = false;
@ -3380,7 +3505,7 @@ export default function luckysheetHandler() {
});
//截图下载
$(document).on("click", "a.download", function () {
$(document).on("click.luckysheetEvent", "a.download", function () {
let dataURI = $("#luckysheet-confirm-screenshot-save img").attr("src");
const locale_screenshot = _locale.screenshot;
let binStr = atob(dataURI.split(",")[1]),
@ -3437,6 +3562,48 @@ export default function luckysheetHandler() {
splitColumn.init();
});
//菜单栏 插入图片按钮
$("#luckysheet-insertImg-btn-title").click(function () {
$("#luckysheet-imgUpload").click();
});
$("#luckysheet-imgUpload").click(function (e) {
e.stopPropagation();
});
$("#luckysheet-imgUpload").on("change", function(e){
let file = e.currentTarget.files[0];
let render = new FileReader();
render.readAsDataURL(file);
render.onload = function(event){
let src = event.target.result;
let rowIndex = Store.luckysheet_select_save[0].row_focus;
let colIndex = Store.luckysheet_select_save[0].column_focus;
let left = colIndex == 0 ? 0 : Store.visibledatacolumn[colIndex - 1];
let top = rowIndex == 0 ? 0 : Store.visibledatarow[rowIndex - 1];
let image = new Image();
image.onload = function(){
let width = image.width,
height = image.height;
let img = {
src: src,
left: left,
top: top,
originWidth: width,
originHeight: height
}
imageCtrl.addImgItem(img);
$("#luckysheet-imgUpload").val("");
}
image.src = src;
}
});
//冻结行列
$("#luckysheet-freezen-btn-horizontal").click(function () {
if ($.trim($(this).text()) == locale().freezen.freezenCancel) {
@ -3506,9 +3673,9 @@ export default function luckysheetHandler() {
}
}
$(document).on("visibilitychange webkitvisibilitychange msvisibilitychange", copychange).mouseleave(function () {
$(document).on("visibilitychange.luckysheetEvent webkitvisibilitychange.luckysheetEvent msvisibilitychange.luckysheetEvent", copychange).on("mouseleave.luckysheetEvent", function () {
Store.iscopyself = false;
}).mousedown(function (event) {
}).on("mousedown.luckysheetEvent", function (event) {
//有批注在编辑时
luckysheetPostil.removeActivePs();
@ -3555,7 +3722,7 @@ export default function luckysheetHandler() {
//模态框拖动
$(document).on("mousedown", "div.luckysheet-modal-dialog", function (e) {
$(document).on("mousedown.luckysheetEvent", "div.luckysheet-modal-dialog", function (e) {
if (!$(e.target).is(".luckysheet-modal-dialog")) {
return;
}
@ -3568,7 +3735,7 @@ export default function luckysheetHandler() {
});
//模态框关闭
$(document).on("click", ".luckysheet-modal-dialog-title-close, .luckysheet-model-close-btn", function (e) {
$(document).on("click.luckysheetEvent", ".luckysheet-modal-dialog-title-close, .luckysheet-model-close-btn", function (e) {
//选择文本颜色和单元格颜色弹出框取消
if ($("#textcolorselect").is(":visible") || $("#cellcolorselect").is(":visible")) {
$("#luckysheet-conditionformat-dialog").show();
@ -3764,7 +3931,7 @@ export default function luckysheetHandler() {
let dpi_y = document.getElementById('testdpidiv').offsetHeight * Store.devicePixelRatio;
//粘贴事件处理
$(document).on("paste", function (e) {
$(document).on("paste.luckysheetEvent", function (e) {
if (isEditMode()) {//此模式下禁用粘贴
return;
}
@ -3914,7 +4081,7 @@ export default function luckysheetHandler() {
let bg = $td.css("background-color");
if (bg == "rgba(0, 0, 0, 0)") {
bg = "rgba(255,255,255)";
bg = null;
}
cell.bg = bg;

283
src/controllers/imageCtrl.js

@ -0,0 +1,283 @@
import {
rowLocation,
colLocation,
mouseposition
} from '../global/location';
import { setluckysheet_scroll_status } from '../methods/set';
const imageCtrl = {
imgItem: {
src: '', //图片url
originWidth: null, //图片原始宽度
originHeight: null, //图片原始高度
default: {
width: null, //图片 宽度
height: null, //图片 高度
left: null, //图片离表格左边的 位置
top: null, //图片离表格顶部的 位置
},
crop: {
width: null, //图片裁剪后 宽度
height: null, //图片裁剪后 高度
offsetLeft: 0, //图片裁剪后离未裁剪时 左边的位移
offsetTop: 0, //图片裁剪后离未裁剪时 顶部的位移
}
},
images: null,
currentImgId: null,
currentWinW: null,
currentWinH: null,
resize: null,
resizeXY: null,
move: false,
moveXY: null,
generateRandomId: function(prefix) {
if(prefix == null){
prefix = "img";
}
let userAgent = window.navigator.userAgent.replace(/[^a-zA-Z0-9]/g, "").split("");
let mid = "";
for(let i = 0; i < 12; i++){
mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))];
}
let time = new Date().getTime();
return prefix + "_" + mid + "_" + time;
},
modelHtml: function(id, imgItem) {
let src = imgItem.src;
let width = imgItem.default.width,
height = imgItem.default.height,
left = imgItem.default.left,
top = imgItem.default.top;
return `<div id="${id}" class="luckysheet-modal-dialog luckysheet-modal-dialog-image" style="width:${width}px;height:${height}px;padding:0;position:absolute;left:${left}px;top:${top}px;z-index:200;">
<div class="luckysheet-modal-dialog-content">
<img src="${src}" style="width:100%;height:100%;" />
</div>
</div>`;
},
init: function() {
let _this = this;
//image active
$("#luckysheet-image-showBoxs").off("mousedown.active").on("mousedown.active", ".luckysheet-modal-dialog-image", function(e) {
$(this).hide();
let id = $(this).attr("id");
_this.currentImgId = id;
let item = _this.images[id];
let width = item.default.width,
height = item.default.height,
left = item.default.left,
top = item.default.top;
if(item.crop.width != width || item.crop.height != height){
width = item.crop.width;
height = item.crop.height;
left = left + item.crop.offsetLeft;
top = top + item.crop.offsetTop;
}
$("#luckysheet-modal-dialog-activeImage").show().css({
"width": width,
"height": height,
"left": left,
"top": top
});
$("#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content").css({
"background-image": "url(" + item.src + ")",
"background-size": item.default.width + "px " + item.default.height + "px",
"background-position": -item.crop.offsetLeft + "px " + -item.crop.offsetTop + "px"
})
e.stopPropagation();
})
//image move
$("#luckysheet-modal-dialog-activeImage").off("mousedown.move").on("mousedown.move", ".luckysheet-modal-dialog-content", function(e) {
_this.move = true;
_this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth;
_this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight;
let scrollTop = $("#luckysheet-cell-main").scrollTop(),
scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let offset = $("#luckysheet-modal-dialog-activeImage").offset();
let position = $("#luckysheet-modal-dialog-activeImage").position();
_this.moveXY = [
e.pageX - offset.left,
e.pageY - offset.top,
position.left,
position.top,
scrollLeft,
scrollTop
];
setluckysheet_scroll_status(true);
e.stopPropagation();
})
//image resize
$("#luckysheet-modal-dialog-activeImage").off("mousedown.resize").on("mousedown.resize", ".luckysheet-modal-dialog-resize-item", function(e) {
_this.currentWinW = $("#luckysheet-cell-main")[0].scrollWidth;
_this.currentWinH = $("#luckysheet-cell-main")[0].scrollHeight;
_this.resize = $(this).data("type");
let scrollTop = $("#luckysheet-cell-main").scrollTop(),
scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let mouse = mouseposition(e.pageX, e.pageY);
let x = mouse[0] + scrollLeft;
let y = mouse[1] + scrollTop;
let position = $("#luckysheet-modal-dialog-activeImage").position();
let width = $("#luckysheet-modal-dialog-activeImage").width();
let height = $("#luckysheet-modal-dialog-activeImage").height();
_this.resizeXY = [
x,
y,
width,
height,
position.left + scrollLeft,
position.top + scrollTop,
scrollLeft,
scrollTop
];
setluckysheet_scroll_status(true);
e.stopPropagation();
})
//image crop
$("#luckysheet-modal-dialog-activeImage").off("mousedown.crop").on("mousedown.crop", ".luckysheet-modal-controll-crop", function(e) {
$("#luckysheet-modal-dialog-activeImage").hide();
let item = _this.images[_this.currentImgId];
let width = item.default.width,
height = item.default.height,
left = item.default.left,
top = item.default.top;
if(item.crop.width != width || item.crop.height != height){
width = item.crop.width;
height = item.crop.height;
left = left + item.crop.offsetLeft;
top = top + item.crop.offsetTop;
}
$("#luckysheet-modal-dialog-cropping").show().css({
"width": width,
"height": height,
"left": left,
"top": top
});
$("#luckysheet-modal-dialog-cropping .cropping-mask").css({
"width": item.default.width,
"height": item.default.height,
"background-image": "url(" + item.src + ")",
"left": -item.crop.offsetLeft,
"top": -item.crop.offsetTop
})
$("#luckysheet-modal-dialog-cropping .cropping-content").css({
"background-image": "url(" + item.src + ")",
"background-size": item.default.width + "px " + item.default.height + "px",
"background-position": -item.crop.offsetLeft + "px " + -item.crop.offsetTop + "px"
})
e.stopPropagation();
})
//image delete
$("#luckysheet-modal-dialog-activeImage").off("mousedown.delete").on("mousedown.delete", ".luckysheet-modal-controll-del", function(e) {
_this.removeImgItem();
})
},
addImgItem: function(img) {
let _this = this;
let width, height;
let max = 400;
if(img.originHeight < img.originWidth){
height = Math.round(img.originHeight * (max / img.originWidth));
width = max;
}
else{
width = Math.round(img.originWidth * (max / img.originHeight));
height = max;
}
if(_this.images == null){
_this.images = {};
}
let imgItem = $.extend(true, {}, _this.imgItem);
imgItem.src = img.src;
imgItem.originWidth = img.originWidth;
imgItem.originHeight = img.originHeight;
imgItem.default.width = width;
imgItem.default.height = height;
imgItem.default.left = img.left;
imgItem.default.top = img.top;
imgItem.crop.width = width;
imgItem.crop.height = height;
let id = _this.generateRandomId();
let modelHtml = _this.modelHtml(id, imgItem);
$("#luckysheet-image-showBoxs").append(modelHtml);
_this.images[id] = imgItem;
_this.init();
},
moveImgItem: function() {
let _this = this;
_this.move = false;
let position = $("#luckysheet-modal-dialog-activeImage").position();
_this.images[_this.currentImgId].left = position.left;
_this.images[_this.currentImgId].top = position.top;
},
resizeImgItem: function() {
let _this = this;
_this.resize = null;
let position = $("#luckysheet-modal-dialog-activeImage").position();
let width = $("#luckysheet-modal-dialog-activeImage").outerWidth();
let height = $("#luckysheet-modal-dialog-activeImage").outerHeight();
_this.images[_this.currentImgId].width = width;
_this.images[_this.currentImgId].height = height;
_this.images[_this.currentImgId].left = position.left;
_this.images[_this.currentImgId].top = position.top;
},
removeImgItem: function() {
let _this = this;
delete _this.images[_this.currentImgId];
$("#luckysheet-modal-dialog-activeImage").hide();
},
}
export default imageCtrl;

3
src/controllers/luckysheetConfigsetting.js

@ -29,6 +29,9 @@ const luckysheetConfigsetting = {
fireMousedown: null,
plugins:[],
forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用
defaultColWidth:73,
defaultRowHeight:19,
}
export default luckysheetConfigsetting;

29
src/controllers/server.js

@ -53,7 +53,12 @@ const server = {
let v_row = [];
for(let c = c1; c <= c2; c++){
v_row.push(data[r][c]);
if(data[r]==null){
v_row.push(null);
}
else{
v_row.push(data[r][c]);
}
}
v.push(v_row);
@ -124,7 +129,10 @@ const server = {
let msg = pako.gzip(encodeURIComponent(JSON.stringify(d)), { to: "string" });
_this.websocket.send(msg);
if(_this.websocket!=null){
_this.websocket.send(msg);
}
},
websocket: null,
wxErrorCount: 0,
@ -401,7 +409,6 @@ const server = {
}
let r = value.r, c = value.c;
let func = value.func;
let calcChain = file["calcChain"] == null ? [] : file["calcChain"];
@ -415,13 +422,13 @@ const server = {
}
}
}
else if(op == "update"){
for(let a = 0; a < calcChain.length; a++){
if(r == calcChain[a].r && c == calcChain[a].c && index == calcChain[a].index){
calcChain[a].func = func;
}
}
}
// else if(op == "update"){
// for(let a = 0; a < calcChain.length; a++){
// if(r == calcChain[a].r && c == calcChain[a].c && index == calcChain[a].index){
// calcChain[a].func = func;
// }
// }
// }
setTimeout(function () {
luckysheetrefreshgrid();
@ -657,7 +664,7 @@ const server = {
$("#luckysheet-sheets-item" + index).show();
}
}
else if(type == "c"){ //图表操作
else if(type == "c"){ //图表操作 TODO
let op = item.op, cid = item.cid;
if(op == "add"){ //插入

150
src/controllers/sheetmanage.js

@ -1,6 +1,6 @@
import { isEditMode } from '../global/validate';
import cleargridelement from '../global/cleargridelement';
import { getcellvalue, datagridgrowth } from '../global/getdata';
import { getcellvalue, datagridgrowth,getcellFormula } from '../global/getdata';
import { setcellvalue } from '../global/setdata';
import luckysheetcreatedom from '../global/createdom';
import tooltip from '../global/tooltip';
@ -442,7 +442,7 @@ const sheetmanage = {
return true;
}
},
createSheetbydata: function(data, isrenew) {
createSheetbydata: function(data, isrenew, isBefore=true) {
let _this = this;
let colorset = '';
@ -452,13 +452,15 @@ const sheetmanage = {
$("#luckysheet-sheet-container-c").append(replaceHtml(sheetHTML, { "index": data.index, "active": "", "name": data.name, "order": data.order, "style": "", "colorset": colorset }));
let previndex = data.order;
if(previndex >= Store.luckysheetfile.length){
previndex = Store.luckysheetfile.length - 1;
$("#luckysheet-sheets-item" + data.index).insertAfter($("#luckysheet-sheets-item" + Store.luckysheetfile[previndex].index));
}
else{
$("#luckysheet-sheets-item" + data.index).insertBefore($("#luckysheet-sheets-item" + Store.luckysheetfile[previndex].index));
if(isBefore){
let previndex = data.order;
if(previndex >= Store.luckysheetfile.length){
previndex = Store.luckysheetfile.length - 1;
$("#luckysheet-sheets-item" + data.index).insertAfter($("#luckysheet-sheets-item" + Store.luckysheetfile[previndex].index));
}
else{
$("#luckysheet-sheets-item" + data.index).insertBefore($("#luckysheet-sheets-item" + Store.luckysheetfile[previndex].index));
}
}
Store.luckysheetfile.push(data);
@ -598,14 +600,7 @@ const sheetmanage = {
return data;
},
initialjfFile: function(menu, title) {
let _this = this;
_this.getCurSheet();
let file = Store.luckysheetfile[_this.getSheetIndex(Store.currentSheetIndex)];
_this.nulldata = datagridgrowth([], Store.defaultrowNum, Store.defaultcolumnNum);
let data = _this.buildGridData(file);
sheetParamRestore: function(file, data) {
Store.luckysheet_select_save = file["luckysheet_select_save"];
if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){
if(data[0] != null && data[0][0] != null && data[0][0].mc != null){
@ -627,6 +622,43 @@ const sheetmanage = {
Store.zoomRatio = file["zoomRatio"] == null ? 1 : file["zoomRatio"];
if(file["defaultRowHeight"]!=null){
Store.defaultrowlen = parseFloat(file["defaultRowHeight"]);
}
else{
Store.defaultrowlen = luckysheetConfigsetting["defaultRowHeight"];
}
if(file["defaultColWidth"]!=null){
Store.defaultcollen = parseFloat(file["defaultColWidth"]);
}
else{
Store.defaultcollen = luckysheetConfigsetting["defaultColWidth"];
}
if(file["showGridLines"]!=null){
let showGridLines = file["showGridLines"];
if(showGridLines==0 || showGridLines==false){
Store.showGridLines = false;
}
else{
Store.showGridLines = true;
}
}
else{
Store.showGridLines = true;
}
},
initialjfFile: function(menu, title) {
let _this = this;
_this.getCurSheet();
let file = Store.luckysheetfile[_this.getSheetIndex(Store.currentSheetIndex)];
_this.nulldata = datagridgrowth([], Store.defaultrowNum, Store.defaultcolumnNum);
let data = _this.buildGridData(file);
this.sheetParamRestore(file, data);
let r2 = Store.luckysheet_select_save[0].row[1],
c2 = Store.luckysheet_select_save[0].column[1];
@ -695,6 +727,7 @@ const sheetmanage = {
let execF = function(){
_this.mergeCalculation(file["index"]);
editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
_this.storeSheetParam();
_this.restoreselect();
_this.CacheNotLoadControll = [];
@ -832,25 +865,7 @@ const sheetmanage = {
luckysheetPostil.buildAllPs(Store.flowdata);
Store.config = file["config"];
Store.luckysheet_select_save = file["luckysheet_select_save"];
if(Store.luckysheet_select_save == null || Store.luckysheet_select_save.length == 0){
if(Store.flowdata[0] != null && Store.flowdata[0][0] != null && Store.flowdata[0][0].mc != null){
Store.luckysheet_select_save = [{
"row": [0, Store.flowdata[0][0].mc.rs - 1],
"column": [0, Store.flowdata[0][0].mc.cs - 1]
}];
}
else{
Store.luckysheet_select_save = [{
"row": [0, 0],
"column": [0, 0]
}];
}
}
Store.luckysheet_selection_range = file["luckysheet_selection_range"] == null ? [] : file["luckysheet_selection_range"];
this.sheetParamRestore(file, Store.flowdata);
if(file["freezen"] == null){
luckysheetFreezen.freezenhorizontaldata = null;
@ -860,17 +875,12 @@ const sheetmanage = {
luckysheetFreezen.freezenhorizontaldata = file["freezen"].horizontal == null ? null : file["freezen"].horizontal.freezenhorizontaldata;
luckysheetFreezen.freezenverticaldata = file["freezen"].vertical == null ? null : file["freezen"].vertical.freezenverticaldata;
}
if(file["zoomRatio"] != null){
Store.zoomRatio = file["zoomRatio"];
}
else{
Store.zoomRatio = 1;
}
createFilterOptions(file["filter_select"], file["filter"]);
rhchInit(Store.flowdata.length, Store.flowdata[0].length);
createFilterOptions(file["filter_select"], file["filter"]);
},
restoreselect: function() {
let index = this.getSheetIndex(Store.currentSheetIndex);
@ -907,7 +917,11 @@ const sheetmanage = {
mergeCalculationSheet:{},
mergeCalculation:function(index){
let file = Store.luckysheetfile[this.getSheetIndex(index)];
let config = file.config, data = file.data, mergeConfig = config.merge;
let config = file.config, data = file.data;
if(config==null){
return;
}
let mergeConfig = config.merge;
if(mergeConfig==null || index in this.mergeCalculationSheet || file["autoCalculationMerge"]===false){
return;
}
@ -981,10 +995,11 @@ const sheetmanage = {
}
let load = file["load"];
if (load != null) {
if (load != null) {
_this.mergeCalculation(index);
_this.setSheetParam(true);
_this.showSheet();
_this.mergeCalculation(index);
setTimeout(function () {
formula.execFunctionGroup();
luckysheetrefreshgrid();
@ -999,9 +1014,32 @@ const sheetmanage = {
file["data"] = data;
file["load"] = "1";
let sheetindexset = _this.checkLoadSheetIndex(file);
let sheetindex = [];
for(let i = 0; i < sheetindexset.length; i++){
let item = sheetindexset[i];
if(item == file["index"]){
continue;
}
sheetindex.push(item);
}
for(let i = 0;i<sheetindex.length;i++){
let item = sheetindex[i];
let otherfile = Store.luckysheetfile[_this.getSheetIndex(item)];
if(otherfile["load"] == null || otherfile["load"] == "0"){
otherfile["data"] = _this.buildGridData(otherfile);
otherfile["load"] = "1";
}
}
_this.mergeCalculation(index);
_this.setSheetParam();
_this.showSheet();
_this.mergeCalculation(index);
setTimeout(function () {
_this.restoreCache();
formula.execFunctionGroupForce(luckysheetConfigsetting.forceCalculation);
@ -1041,10 +1079,10 @@ const sheetmanage = {
file["data"] = data;
file["load"] = "1";
_this.mergeCalculation(index);
_this.setSheetParam();
_this.showSheet();
_this.mergeCalculation(index);
setTimeout(function () {
_this.restoreCache();
formula.execFunctionGroupForce(luckysheetConfigsetting.forceCalculation);
@ -1078,9 +1116,10 @@ const sheetmanage = {
let dataNameList = {};
for(let i = 0; i < calchain.length; i++){
let f = calchain[i];
let dataindex = f.index, func = f.func;
let dataindex = f.index;
let formulaTxt = getcellFormula(f.r, f.c, dataindex);
formula.functionParser(func[2], (str)=>{
formula.functionParser(formulaTxt, (str)=>{
if(str.indexOf("!")>-1){
let name = str.substr(0, str.indexOf('!'));
dataNameList[name] = true;
@ -1140,7 +1179,7 @@ const sheetmanage = {
return ret;
},
showSheet: function() {
changeSheetContainerSize();
// changeSheetContainerSize();
$("#luckysheet-cell-flow_0").css({ "width": Store.ch_width, "top": "-1px" }); //width更新
$("#luckysheet-sheettable_0").css({ "width": Store.ch_width - 1, "height": Store.rh_height });
$("#luckysheetrowHeader_0").css("height", Store.rh_height);
@ -1521,13 +1560,12 @@ const sheetmanage = {
}
let r = value.r, c = value.c;
let func = value.func;
if(op == "del" ){
formula.delFunctionGroup(r, c, index);
}
else {
formula.insertUpdateFunctionGroup(r, c, func, index);
formula.insertUpdateFunctionGroup(r, c, index);
}
}
else if(type == "cg"){

4
src/controllers/updateCell.js

@ -205,7 +205,9 @@ export function luckysheetupdateCell(row_index1, col_index1, d, cover, isnotfocu
export function setCenterInputPosition(row_index, col_index, d){
if(row_index==null ||col_index==null){
return;
}
let cell = d[row_index][col_index];
if(cell==null){
return;

7
src/core.js

@ -97,6 +97,11 @@ luckysheet.create = function (setting) {
luckysheetConfigsetting.rowHeaderWidth = extendsetting.rowHeaderWidth;
luckysheetConfigsetting.columeHeaderHeight = extendsetting.columeHeaderHeight;
luckysheetConfigsetting.defaultColWidth = extendsetting.defaultColWidth;
luckysheetConfigsetting.defaultRowHeight = extendsetting.defaultRowHeight;
luckysheetConfigsetting.title = extendsetting.title;
// Register plugins
initPlugins(extendsetting.plugins , extendsetting.data);
@ -180,6 +185,8 @@ luckysheet.setcellvalue = setcellvalue;
// Get selection range value
luckysheet.getdatabyselection = getdatabyselection;
luckysheet.sheetmanage = sheetmanage;
// Data of the current table
luckysheet.flowdata = function () {
return Store.flowdata;

218
src/css/luckysheet-core.css

@ -6721,4 +6721,222 @@ fieldset[disabled] .btn-danger.focus {
.luckysheet-modal-controll-max-close:hover {
background: #FC6666;
cursor: pointer;
}
/* 图片 */
#luckysheet-modal-dialog-activeImage .luckysheet-modal-dialog-content{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
cursor: move;
}
#luckysheet-modal-dialog-cropping::before{
content: "";
outline: 1px solid #fff;
position: absolute;
left: 33.3%;
right: 33.3%;
top: 0;
bottom: 0;
z-index: 1;
pointer-events: none;
}
#luckysheet-modal-dialog-cropping::after{
content: "";
outline: 1px solid #fff;
position: absolute;
left: 0;
right: 0;
top: 33.3%;
bottom: 33.3%;
z-index: 1;
pointer-events: none;
}
#luckysheet-modal-dialog-cropping .cropping-mask{
filter: brightness(.5);
position: absolute;
background-size: 100% 100%;
left: 0;
top: 0;
}
#luckysheet-modal-dialog-cropping .cropping-content{
position: absolute;
overflow: hidden;
background-position: 0 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
#luckysheet-modal-dialog-cropping .luckysheet-modal-dialog-resize{
border: none;
position: absolute;
margin: 0px;
padding: 0px;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
#luckysheet-modal-dialog-cropping .resize-item{
width: 0;
height: 0;
background: none;
border: none;
position: absolute;
z-index: 3;
}
#luckysheet-modal-dialog-cropping .resize-item::before{
content: "";
display: block;
position: absolute;
background: #000;
}
#luckysheet-modal-dialog-cropping .resize-item::after{
content: "";
display: block;
position: absolute;
background: #000;
}
#luckysheet-modal-dialog-cropping .lt{
left: 0;
top: 0;
cursor: nwse-resize;
}
#luckysheet-modal-dialog-cropping .lt::before{
width: 18px;
height: 4px;
left: 0;
top: 0;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .lt::after{
width: 4px;
height: 14px;
left: 0;
top: 4px;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .mt{
left: 50%;
top: 0;
cursor: ns-resize;
}
#luckysheet-modal-dialog-cropping .mt::before{
width: 18px;
height: 4px;
left: -11px;
top: 0;
border-left: 2px solid #fff;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .rt{
right: 0;
top: 0;
cursor: nesw-resize;
}
#luckysheet-modal-dialog-cropping .rt::before{
width: 18px;
height: 4px;
right: 0;
top: 0;
border-left: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .rt::after{
width: 4px;
height: 14px;
right: 0;
top: 4px;
border-left: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .lm{
left: 0;
top: 50%;
cursor: ew-resize;
}
#luckysheet-modal-dialog-cropping .lm::before{
width: 4px;
height: 18px;
left: 0;
top: -11px;
border-right: 2px solid #fff;
border-top: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .rm{
right: 0;
top: 50%;
cursor: ew-resize;
}
#luckysheet-modal-dialog-cropping .rm::before{
width: 4px;
height: 18px;
right: 0;
top: -11px;
border-left: 2px solid #fff;
border-top: 2px solid #fff;
border-bottom: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .lb{
left: 0;
bottom: 0;
cursor: nesw-resize;
}
#luckysheet-modal-dialog-cropping .lb::before{
width: 18px;
height: 4px;
left: 0;
bottom: 0;
border-right: 2px solid #fff;
border-top: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .lb::after{
width: 4px;
height: 14px;
left: 0;
bottom: 4px;
border-right: 2px solid #fff;
border-top: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .rb{
right: 0;
bottom: 0;
cursor: nwse-resize;
}
#luckysheet-modal-dialog-cropping .rb::before{
width: 18px;
height: 4px;
right: 0;
bottom: 0;
border-left: 2px solid #fff;
border-top: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .rb::after{
width: 4px;
height: 14px;
right: 0;
bottom: 4px;
border-left: 2px solid #fff;
border-top: 2px solid #fff;
}
#luckysheet-modal-dialog-cropping .mb{
left: 50%;
bottom: 0;
cursor: ns-resize;
}
#luckysheet-modal-dialog-cropping .mb::before{
width: 18px;
height: 4px;
left: -11px;
bottom: 0;
border-left: 2px solid #fff;
border-right: 2px solid #fff;
border-top: 2px solid #fff;
}

2
src/demoData/sheetCell.js

@ -1171,6 +1171,8 @@ const sheetCell = {
},
"index": "0",
"zoomRatio":1,
// "defaultColWidth":20,
// "showGridLines":0,
"chart": [],
"status": "1",
"order": "0",

40
src/demoData/sheetFormula.js

@ -6399,7 +6399,7 @@ const sheetFormula = {
"r": 6,
"c": 3,
"index": 1,
"func": [true, 23.75, "=AVERAGE(D3:D6)"],
// "func": [true, 23.75, "=AVERAGE(D3:D6)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6408,7 +6408,7 @@ const sheetFormula = {
"r": 7,
"c": 3,
"index": 1,
"func": [true, 30, "=MAX(D3:D6)"],
// "func": [true, 30, "=MAX(D3:D6)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6417,7 +6417,7 @@ const sheetFormula = {
"r": 8,
"c": 3,
"index": 1,
"func": [true, 17, "=MIN(D3:D6)"],
// "func": [true, 17, "=MIN(D3:D6)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6426,7 +6426,7 @@ const sheetFormula = {
"r": 5,
"c": 9,
"index": 1,
"func": [true, "J2", "=INDIRECT(\"I2\")"],
// "func": [true, "J2", "=INDIRECT(\"I2\")"],
"color": "w",
"parent": null,
"chidren": {},
@ -6435,7 +6435,7 @@ const sheetFormula = {
"r": 6,
"c": 9,
"index": 1,
"func": [true, 1, "=INDIRECT(I2)"],
// "func": [true, 1, "=INDIRECT(I2)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6444,7 +6444,7 @@ const sheetFormula = {
"r": 7,
"c": 9,
"index": 1,
"func": [true, "I", "=INDIRECT(\"I\"&(1+2))"],
// "func": [true, "I", "=INDIRECT(\"I\"&(1+2))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6453,7 +6453,7 @@ const sheetFormula = {
"r": 8,
"c": 9,
"index": 1,
"func": [true, 1, "=INDIRECT(I4&J3)"],
// "func": [true, 1, "=INDIRECT(I4&J3)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6462,7 +6462,7 @@ const sheetFormula = {
"r": 16,
"c": 7,
"index": 1,
"func": [true, 152, "=SUBTOTAL(9,OFFSET(F15,ROW(F15:F18)-ROW(F15),1,3))"],
// "func": [true, 152, "=SUBTOTAL(9,OFFSET(F15,ROW(F15:F18)-ROW(F15),1,3))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6471,7 +6471,7 @@ const sheetFormula = {
"r": 17,
"c": 7,
"index": 1,
"func": [true, 541, "=SUBTOTAL(9,OFFSET(G15,ROW(G15:G18)-ROW(G15),1,3))"],
// "func": [true, 541, "=SUBTOTAL(9,OFFSET(G15,ROW(G15:G18)-ROW(G15),1,3))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6480,7 +6480,7 @@ const sheetFormula = {
"r": 22,
"c": 8,
"index": 1,
"func": [true, "dumpling", "=INDEX(D21:D25,MATCH(\"dumpling\",D21:D25),1)"],
// "func": [true, "dumpling", "=INDEX(D21:D25,MATCH(\"dumpling\",D21:D25),1)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6489,7 +6489,7 @@ const sheetFormula = {
"r": 38,
"c": 6,
"index": 1,
"func": [true, 1, "=SUM(IF((C31:C39=\"Fax\")+(D31:D39=\"Jones\")<>2,1,0))"],
// "func": [true, 1, "=SUM(IF((C31:C39=\"Fax\")+(D31:D39=\"Jones\")<>2,1,0))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6498,7 +6498,7 @@ const sheetFormula = {
"r": 30,
"c": 6,
"index": 1,
"func": [true, "#NAME?", "=SUM((C31:C39=\"Fax\")*(D31:D39=\"Brown\")*(E31:E39))"],
// "func": [true, "#NAME?", "=SUM((C31:C39=\"Fax\")*(D31:D39=\"Brown\")*(E31:E39))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6507,7 +6507,7 @@ const sheetFormula = {
"r": 32,
"c": 6,
"index": 1,
"func": [true, "#NAME?", "=SUM((C31:C39=\"Fax\")*(D31:D39=\"Brown\"))"],
// "func": [true, "#NAME?", "=SUM((C31:C39=\"Fax\")*(D31:D39=\"Brown\"))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6516,7 +6516,7 @@ const sheetFormula = {
"r": 34,
"c": 6,
"index": 1,
"func": [true, 1, "=SUM(IF((C31:C39=\"Fax\")+(D31:D39=\"Jones\"),1,0))"],
// "func": [true, 1, "=SUM(IF((C31:C39=\"Fax\")+(D31:D39=\"Jones\"),1,0))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6525,7 +6525,7 @@ const sheetFormula = {
"r": 36,
"c": 6,
"index": 1,
"func": [true, 1, "=SUM(IF(MOD((C31:C39=\"Fax\")+(D31:D39=\"Jones\"),2),1,0))"],
// "func": [true, 1, "=SUM(IF(MOD((C31:C39=\"Fax\")+(D31:D39=\"Jones\"),2),1,0))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6534,7 +6534,7 @@ const sheetFormula = {
"r": 9,
"c": 9,
"index": 1,
"func": [true, 1, "=INDIRECT(\"Formula!\"&I2)"],
// "func": [true, 1, "=INDIRECT(\"Formula!\"&I2)"],
"color": "w",
"parent": null,
"chidren": {},
@ -6543,7 +6543,7 @@ const sheetFormula = {
"r": 10,
"c": 9,
"index": 1,
"func": [true, "J2", "=INDIRECT(\"Formula!I2\")"],
// "func": [true, "J2", "=INDIRECT(\"Formula!I2\")"],
"color": "w",
"parent": null,
"chidren": {},
@ -6552,7 +6552,7 @@ const sheetFormula = {
"r": 14,
"c": 7,
"index": 1,
"func": [true, 207, "=SUBTOTAL(9,OFFSET($D$15,ROW($D$15:$D$18)-ROW($D$15),1,3))"],
// "func": [true, 207, "=SUBTOTAL(9,OFFSET($D$15,ROW($D$15:$D$18)-ROW($D$15),1,3))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6561,7 +6561,7 @@ const sheetFormula = {
"r": 15,
"c": 7,
"index": 1,
"func": [true, 182, "=SUBTOTAL(9,OFFSET(E15,ROW(E15:E18)-ROW(E15),1,3))"],
// "func": [true, 182, "=SUBTOTAL(9,OFFSET(E15,ROW(E15:E18)-ROW(E15),1,3))"],
"color": "w",
"parent": null,
"chidren": {},
@ -6570,7 +6570,7 @@ const sheetFormula = {
"r": 23,
"c": 8,
"index": 1,
"func": [true, false, "=ISNA(MATCH(D21:D25,C21:C27,0))"],
// "func": [true, false, "=ISNA(MATCH(D21:D25,C21:C27,0))"],
"color": "w",
"parent": null,
"chidren": {},

8
src/expendPlugins/chart/plugin.js

@ -1387,10 +1387,10 @@ function selectRangeBorderShow(chart_id) {
//luckysheet取cell-main,后续扩展到其他的用户自定义元素
$('#luckysheet-cell-main')
.find('.luckysheet-modal-dialog-resize')
.find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize')
.hide()
$('#luckysheet-cell-main')
.find('.luckysheet-modal-dialog-controll')
.find('.luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll')
.hide()
$t.css('z-index', chartInfo.chartparam.luckysheetCurrentChartZIndexRank++)
@ -1413,7 +1413,7 @@ function selectRangeBorderShow(chart_id) {
//选择区域高亮隐藏
function selectRangeBorderHide(settingShow) {
$('#luckysheet-cell-main .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-controll').hide()
$('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide()
$('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove()
chartInfo.chartparam.luckysheetCurrentChartActive = false
@ -1447,7 +1447,7 @@ function hideChartSettingComponent(refresh) {
//隐藏设置界面
$('.chartSetting').hide();
//.luckysheet-modal-dialog-resize为图表显示框的缩放框,.luckysheet-modal-dialog-controll为显示框右边的控制按钮
$('#luckysheet-cell-main .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-controll').hide()
$('#luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-resize, #luckysheet-cell-main .luckysheet-modal-dialog-chart .luckysheet-modal-dialog-controll').hide()
$('#luckysheet-cell-main').find('.luckysheet-datavisual-selection-set div').remove()

3
src/function/func.js

@ -93,6 +93,9 @@ function luckysheet_compareWith() {
else if(sp == "-" && fp == null){
fp = 0;
}
else if(sp == "/" && (tp == 0 || tp == null)){
return error.d;
}
//计算result
function booleanOperation(a, operator, b){

6
src/function/functionImplementation.js

@ -7,7 +7,7 @@ import formula from '../global/formula';
import func_methods from '../global/func_methods';
import editor from '../global/editor';
import { isdatetime, diff, isdatatype } from '../global/datecontroll';
import { isRealNum, isRealNull, valueIsError } from '../global/validate';
import { isRealNum, isRealNull, valueIsError,error } from '../global/validate';
import { jfrefreshgrid } from '../global/refresh';
import { genarate, update } from '../global/format';
import { orderbydata } from '../global/sort';
@ -19496,7 +19496,7 @@ const functionImplementation = {
//结果为 TRUE
var value_if_true = func_methods.getFirstValue(arguments[1], "text");
if(valueIsError(value_if_true)){
if(valueIsError(value_if_true) && value_if_false!=error.d){
return value_if_true;
}
@ -19504,7 +19504,7 @@ const functionImplementation = {
var value_if_false = "";
if(arguments.length == 3){
value_if_false = func_methods.getFirstValue(arguments[2], "text");
if(valueIsError(value_if_false)){
if(valueIsError(value_if_false) && value_if_false!=error.d){
return value_if_false;
}
}

8
src/global/createdom.js

@ -50,8 +50,6 @@ export default function luckysheetcreatedom(colwidth, rowheight, data, menu, tit
else {
Store.flowdata = data;
}
editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据
let flowHTML = flow;
if(Store.config == null){
@ -112,6 +110,12 @@ export default function luckysheetcreatedom(colwidth, rowheight, data, menu, tit
$("body").append(replaceHtml(filtersubmenuHTML(), { "menuid": "filter" }));
$("body").append(sheetconfigHTML());
$("#luckysheet-rows-h").width((Store.rowHeaderWidth-1.5));
$("#luckysheet-cols-h-c").height((Store.columeHeaderHeight-1.5));
$("#luckysheet-left-top").css({width:Store.rowHeaderWidth-1.5, height:Store.columeHeaderHeight-1.5});
//批注
luckysheetPostil.buildAllPs(Store.flowdata);
$("#luckysheet_info_detail_input").val(luckysheetConfigsetting.title);
}

334
src/global/draw.js

@ -7,7 +7,7 @@ import { luckysheetdefaultstyle, luckysheet_CFiconsImg,luckysheetdefaultFont } f
import { luckysheet_searcharray } from '../controllers/sheetSearch';
import { dynamicArrayCompute } from './dynamicArray';
import browser from './browser';
import { isRealNull } from './validate';
import { isRealNull, isRealNum } from './validate';
import { getCellTextSplitArr,getMeasureText } from './getRowlen';
import { getcellvalue } from './getdata';
import { getBorderInfoCompute } from './border';
@ -63,7 +63,7 @@ function luckysheetDrawgridRowTitle(scrollHeight, drawHeight, offsetTop) {
let end_r, start_r;
let bodrder05 = 0.5;//Default 0.5
let preEndR;
for (let r = dataset_row_st; r <= dataset_row_ed; r++) {
if (r == 0) {
start_r = -scrollHeight - 1;
@ -123,19 +123,55 @@ function luckysheetDrawgridRowTitle(scrollHeight, drawHeight, offsetTop) {
luckysheetTableContent.closePath();
//行标题栏横线,horizen
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
-1,
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineTo(
(Store.rowHeaderWidth - 1) ,
(end_r + offsetTop - 2 + bodrder05)
);
// luckysheetTableContent.lineWidth = 1;
// luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
if (Store.config["rowhidden"] != null && Store.config["rowhidden"][r] == null && Store.config["rowhidden"][r+1] != null) {
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
-1,
(end_r + offsetTop - 4 + bodrder05)
);
luckysheetTableContent.lineTo(
(Store.rowHeaderWidth - 1) ,
(end_r + offsetTop - 4 + bodrder05)
);
// luckysheetTableContent.lineWidth = 1;
// luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
else if(Store.config["rowhidden"]==null || Store.config["rowhidden"][r] == null){
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
-1,
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineTo(
(Store.rowHeaderWidth - 1) ,
(end_r + offsetTop - 2 + bodrder05)
);
// luckysheetTableContent.lineWidth = 1;
// luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
if (Store.config["rowhidden"] != null && Store.config["rowhidden"][r-1] != null && preEndR!=null) {
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
-1,
(preEndR + offsetTop + bodrder05)
);
luckysheetTableContent.lineTo(
(Store.rowHeaderWidth - 1) ,
(preEndR + offsetTop + bodrder05)
);
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
preEndR = end_r;
}
//行标题栏竖线
@ -210,6 +246,7 @@ function luckysheetDrawgridColumnTitle(scrollWidth, drawWidth, offsetLeft) {
let end_c, start_c;
let bodrder05 = 0.5;//Default 0.5
let preEndC;
for (let c = dataset_col_st; c <= dataset_col_ed; c++) {
if (c == 0) {
start_c = -scrollWidth;
@ -252,19 +289,54 @@ function luckysheetDrawgridColumnTitle(scrollWidth, drawWidth, offsetLeft) {
}
//列标题栏竖线 vertical
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(end_c + offsetLeft - 2 + bodrder05) ,
0
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2 + bodrder05) ,
(Store.columeHeaderHeight - 2)
);
luckysheetTableContent.lineWidth = 1;
luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
if (Store.config["colhidden"] != null && Store.config["colhidden"][c] == null && Store.config["colhidden"][c+1] != null) {
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(end_c + offsetLeft - 4 + bodrder05) ,
0
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 4 + bodrder05) ,
(Store.columeHeaderHeight - 2)
);
luckysheetTableContent.lineWidth = 1;
luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
else if(Store.config["colhidden"]==null || Store.config["colhidden"][c] == null) {
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(end_c + offsetLeft - 2 + bodrder05) ,
0
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2 + bodrder05) ,
(Store.columeHeaderHeight - 2)
);
luckysheetTableContent.lineWidth = 1;
luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
if (Store.config["colhidden"] != null && Store.config["colhidden"][c-1] != null && preEndC!=null) {
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(preEndC + offsetLeft + bodrder05) ,
0
);
luckysheetTableContent.lineTo(
(preEndC + offsetLeft + bodrder05) ,
(Store.columeHeaderHeight - 2)
);
// luckysheetTableContent.lineWidth = 1;
// luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.closePath();
luckysheetTableContent.stroke();
}
//horizen
luckysheetTableContent.beginPath();
@ -281,6 +353,8 @@ function luckysheetDrawgridColumnTitle(scrollWidth, drawWidth, offsetLeft) {
// luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
luckysheetTableContent.stroke();
luckysheetTableContent.closePath();
preEndC = end_c;
}
//列标题栏横线
@ -623,7 +697,7 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
if((r + "_" + c) in dynamicArray_compute){//动态数组公式
value = dynamicArray_compute[r + "_" + c].v;
}
cellRender(r, c, start_r, start_c, end_r, end_c, value,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05);
}
}
@ -653,6 +727,8 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
r = margeMaindata.r;
c = margeMaindata.c;
let mainCell = Store.flowdata[r][c];
if (c == 0) {
start_c = -scrollWidth;
}
@ -667,8 +743,8 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
start_r = Store.visibledatarow[r - 1] - scrollHeight - 1;
}
end_r = Store.visibledatarow[r+margeMaindata.rs-1] - scrollHeight;
end_c = Store.visibledatacolumn[c+margeMaindata.cs-1] - scrollWidth;
end_r = Store.visibledatarow[r+mainCell["mc"].rs-1] - scrollHeight;
end_c = Store.visibledatacolumn[c+mainCell["mc"].cs-1] - scrollWidth;
if(value == null || value.toString().length == 0){
nullCellRender(r, c, start_r, start_c, end_r, end_c,luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05, true);
@ -687,7 +763,6 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
if((r + "_" + c) in dynamicArray_compute){//动态数组公式
value = dynamicArray_compute[r + "_" + c].v;
}
cellRender(r, c, start_r, start_c, end_r, end_c, value, luckysheetTableContent,af_compute, cf_compute,offsetLeft,offsetTop,dynamicArray_compute,cellOverflowMap, dataset_col_st, dataset_col_ed,scrollHeight,scrollWidth,bodrder05, true);
}
}
@ -716,7 +791,7 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
let end_c = Store.visibledatacolumn[c] - scrollWidth;
//数据透视表\
//数据透视表
if (!!Store.luckysheetcurrentisPivotTable && pivotTable.drawPivotTable) {
if ((c == 0 || c == 5) && r <= 11) {
luckysheetTableContent.beginPath();
@ -997,7 +1072,7 @@ let nullCellRender = function(r, c, start_r, start_c, end_r, end_c,luckysheetTab
}
if(fillStyle==null){
luckysheetTableContent.fillStyle = "rgba(255,255,255)";
luckysheetTableContent.fillStyle = "#FFFFFF";
}
else{
luckysheetTableContent.fillStyle = fillStyle;
@ -1063,15 +1138,15 @@ let nullCellRender = function(r, c, start_r, start_c, end_r, end_c,luckysheetTab
//即溢出单元格跨此单元格,此单元格不绘制右边框
if(!cellOverflow_colInObj.colIn || cellOverflow_colInObj.colLast){
//右边框
if(!Store.luckysheetcurrentisPivotTable && !fillStyle){
if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(end_c + offsetLeft - 2 + bodrder05),
(start_r + offsetTop - 2)
(start_r + offsetTop)
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2 + bodrder05),
(end_r + offsetTop - 2)
(end_r + offsetTop)
);
luckysheetTableContent.lineWidth = 1;
@ -1082,14 +1157,14 @@ let nullCellRender = function(r, c, start_r, start_c, end_r, end_c,luckysheetTab
}
//下边框
if(!Store.luckysheetcurrentisPivotTable && !fillStyle){
if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(start_c + offsetLeft - 2),
(start_c + offsetLeft - 1),
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2),
(end_c + offsetLeft - 1),
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineWidth = 1;
@ -1137,14 +1212,16 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
}
if(fillStyle==null){
luckysheetTableContent.fillStyle = "rgba(255,255,255)";
luckysheetTableContent.fillStyle = "#FFFFFF";
}
else{
luckysheetTableContent.fillStyle = fillStyle;
}
let borderfix = menuButton.borderfix(Store.flowdata, r, c);
let borderfix = menuButton.borderfix(Store.flowdata, r, c);
// console.log(value, fillStyle,borderfix);
let cellsize = [
(start_c + offsetLeft + borderfix[0]),
(start_r + offsetTop + borderfix[1]),
@ -1162,7 +1239,7 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
//若单元格有批注(单元格右上角红色小三角标示)
if(cell.ps != null){
let ps_w = 5*Store.zoomRatio, ps_h = 5*Store.zoomRatio; //红色小三角宽高
let ps_w = 8*Store.zoomRatio, ps_h = 8*Store.zoomRatio; //红色小三角宽高
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
@ -1182,6 +1259,28 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
luckysheetTableContent.closePath();
}
//若单元格强制为字符串,则显示绿色小三角
if(cell.qp==1 && isRealNum(cell.v)){
let ps_w = 6*Store.zoomRatio, ps_h = 6*Store.zoomRatio; //红色小三角宽高
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(start_c + offsetLeft + ps_w-1),
(start_r + offsetTop)
);
luckysheetTableContent.lineTo(
(start_c + offsetLeft-1),
(start_r + offsetTop)
);
luckysheetTableContent.lineTo(
(start_c + offsetLeft-1),
(start_r + offsetTop + ps_h)
);
luckysheetTableContent.fillStyle = "#487f1e";
luckysheetTableContent.fill();
luckysheetTableContent.closePath();
}
//溢出单元格
let cellOverflow_bd_r_render = true; //溢出单元格右边框是否需要绘制
let cellOverflow_colInObj = cellOverflow_colIn(cellOverflowMap, r, c, dataset_col_st, dataset_col_ed);
@ -1401,13 +1500,15 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
horizonAlignPos = (pos_x + cellWidth - space_width) - textMetrics;
}
let verticalAlignPos = (pos_y + cellHeight - space_height) - oneLineTextHeight; //默认为2,下对齐
let verticalAlignPos_text = (pos_y + cellHeight - space_height) ; //文本垂直方向基准线
let verticalCellHeight = cellHeight>oneLineTextHeight?cellHeight:oneLineTextHeight;
let verticalAlignPos = (pos_y + verticalCellHeight - space_height) - oneLineTextHeight; //默认为2,下对齐
let verticalAlignPos_text = (pos_y + verticalCellHeight - space_height) ; //文本垂直方向基准线
luckysheetTableContent.textBaseline = "bottom";
if(verticalAlign == "0"){ //居中对齐
verticalAlignPos = (pos_y + cellHeight / 2) - (oneLineTextHeight / 2);
verticalAlignPos = (pos_y + verticalCellHeight / 2) - (oneLineTextHeight / 2);
verticalAlignPos_text = (pos_y + cellHeight / 2) ;
verticalAlignPos_text = (pos_y + verticalCellHeight / 2) ;
luckysheetTableContent.textBaseline = "middle";
}
else if(verticalAlign == "1"){ //上对齐
@ -1467,63 +1568,74 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
//自动换行
// luckysheetTableContent.textBaseline = 'top'; //textBaseline以top计算
let strArr = [];//文本截断数组
strArr = getCellTextSplitArr(value.toString(), strArr, (cellWidth - space_width * 2), luckysheetTableContent);
let word_space_height = oneLineTextHeight/3;
for(let i = 0; i < strArr.length; i++){
let strV = strArr[i];
let strWidth = getMeasureText(strV, luckysheetTableContent).width;
// luckysheetTableContent.measureText(strV).width;
let strHeight = oneLineTextHeight;
if(cell.ct!=null && cell.ct.t=="inlineStr" && cell.ct.sharedStrings!=null && cell.ct.sharedStrings.length>0){
let strArr = [],lineMaxHeight=[];
let sharedStrings = cell.ct.sharedStrings;
for(let i=0;i<cell.ct.sharedStrings.length;i++){
//水平对齐计算
if(horizonAlign == "0"){
horizonAlignPos = (pos_x + cellWidth / 2) - (strWidth / 2);
}
else if(horizonAlign == "2"){
horizonAlignPos = (pos_x + cellWidth - space_width) - strWidth;
}
else{
horizonAlignPos = (pos_x + space_width) ;
}
//垂直对齐计算
let clLine = 0;
if(verticalAlign == "0"){
verticalAlignPos = (pos_y + cellHeight / 2) - (strHeight+word_space_height) * (strArr.length-1)/2;
}
else if(verticalAlign == "1"){
verticalAlignPos = (pos_y + space_height) ;
clLine = strHeight / 2;
}
else{
verticalAlignPos = (pos_y + cellHeight - space_height) - (strHeight+word_space_height) * (strArr.length-1);
clLine = -strHeight / 2;
}
}
else{
let strArr = [];
strArr = getCellTextSplitArr(value.toString(), strArr, (cellWidth - space_width * 2), luckysheetTableContent);
let word_space_height = oneLineTextHeight/3;
for(let i = 0; i < strArr.length; i++){
let strV = strArr[i];
let strWidth = getMeasureText(strV, luckysheetTableContent).width;
// luckysheetTableContent.measureText(strV).width;
let strHeight = oneLineTextHeight;
//水平对齐计算
if(horizonAlign == "0"){
horizonAlignPos = (pos_x + cellWidth / 2) - (strWidth / 2);
}
else if(horizonAlign == "2"){
horizonAlignPos = (pos_x + cellWidth - space_width) - strWidth;
}
else{
horizonAlignPos = (pos_x + space_width) ;
}
//垂直对齐计算
let clLine = 0;
if(verticalAlign == "0"){
verticalAlignPos = (pos_y + cellHeight / 2) - (strHeight+word_space_height) * (strArr.length-1)/2;
}
else if(verticalAlign == "1"){
verticalAlignPos = (pos_y + space_height) ;
clLine = strHeight / 2;
}
else{
verticalAlignPos = (pos_y + cellHeight - space_height) - (strHeight+word_space_height) * (strArr.length-1);
clLine = -strHeight / 2;
}
verticalAlignPos = (verticalAlignPos + i * (strHeight+word_space_height));
verticalAlignPos = verticalAlignPos/Store.zoomRatio;
horizonAlignPos = horizonAlignPos/Store.zoomRatio;
verticalAlignPos = (verticalAlignPos + i * (strHeight+word_space_height));
verticalAlignPos = verticalAlignPos/Store.zoomRatio;
horizonAlignPos = horizonAlignPos/Store.zoomRatio;
luckysheetTableContent.fillText(strV, horizonAlignPos, verticalAlignPos);
luckysheetTableContent.fillText(strV, horizonAlignPos, verticalAlignPos);
if(cl == "1" && !isRealNull(strV)){
luckysheetTableContent.beginPath();
luckysheetTableContent.strokeStyle = "#000";
clLine = clLine/Store.zoomRatio;
luckysheetTableContent.moveTo(
horizonAlignPos,
verticalAlignPos +clLine
);
luckysheetTableContent.lineTo(
horizonAlignPos + strWidth/Store.zoomRatio,
verticalAlignPos + clLine
);
luckysheetTableContent.stroke();
luckysheetTableContent.closePath();
if(cl == "1" && !isRealNull(strV)){
luckysheetTableContent.beginPath();
luckysheetTableContent.strokeStyle = "#000";
clLine = clLine/Store.zoomRatio;
luckysheetTableContent.moveTo(
horizonAlignPos,
verticalAlignPos +clLine
);
luckysheetTableContent.lineTo(
horizonAlignPos + strWidth/Store.zoomRatio,
verticalAlignPos + clLine
);
luckysheetTableContent.stroke();
luckysheetTableContent.closePath();
}
}
}
}
else if(cell.tr != null && cell.tr != '0'){
//旋转
@ -1910,15 +2022,15 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
if(cellOverflow_bd_r_render){
//右边框
if(!Store.luckysheetcurrentisPivotTable && !fillStyle){
if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(end_c + offsetLeft - 2 + bodrder05),
(start_r + offsetTop - 2)
(start_r + offsetTop)
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2 + bodrder05),
(end_r + offsetTop - 2)
(end_r + offsetTop)
);
luckysheetTableContent.lineWidth = 1;
luckysheetTableContent.strokeStyle = luckysheetdefaultstyle.strokeStyle;
@ -1928,14 +2040,14 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
}
//下边框
if(!Store.luckysheetcurrentisPivotTable && !fillStyle){
if(!Store.luckysheetcurrentisPivotTable && !fillStyle && Store.showGridLines){
luckysheetTableContent.beginPath();
luckysheetTableContent.moveTo(
(start_c + offsetLeft - 2),
(start_c + offsetLeft - 1),
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineTo(
(end_c + offsetLeft - 2),
(end_c + offsetLeft - 1),
(end_r + offsetTop - 2 + bodrder05)
);
luckysheetTableContent.lineWidth = 1;
@ -2009,15 +2121,16 @@ let cellOverflowRender = function(r, c, stc, edc,luckysheetTableContent,scrollHe
horizonAlignPos = (pos_x + cellWidth - space_width) - textMetrics;
}
let verticalCellHeight = cellHeight>oneLineTextHeight?cellHeight:oneLineTextHeight;
//溢出单元格 垂直对齐
let verticalAlign = menuButton.checkstatus(Store.flowdata, r, c, "vt");
let verticalAlignPos = (pos_y + cellHeight - space_height) - oneLineTextHeight; //默认为2,下对齐
let verticalAlignPos_text = (pos_y + cellHeight - space_height) ; //文本垂直方向基准线
let verticalAlignPos = (pos_y + verticalCellHeight - space_height) - oneLineTextHeight; //默认为2,下对齐
let verticalAlignPos_text = (pos_y + verticalCellHeight - space_height) ; //文本垂直方向基准线
luckysheetTableContent.textBaseline = "bottom";
if(verticalAlign == "0"){ //居中对齐
verticalAlignPos = (pos_y + cellHeight / 2) - (oneLineTextHeight / 2);
verticalAlignPos = (pos_y + verticalCellHeight / 2) - (oneLineTextHeight / 2);
verticalAlignPos_text = (pos_y + cellHeight / 2) ;
verticalAlignPos_text = (pos_y + verticalCellHeight / 2) ;
luckysheetTableContent.textBaseline = "middle";
}
else if(verticalAlign == "1"){ //上对齐
@ -2080,6 +2193,10 @@ function getCellOverflowMap(canvas, col_st, col_ed, row_st, row_end){
for(let c = 0; c < data[r].length; c++){
let cell = data[r][c];
if (Store.config["colhidden"] != null && Store.config["colhidden"][c] != null) {
continue
}
if(cell != null && !isRealNull(cell.v) && cell.mc == null && cell.tb == '1'){
let fontset = luckysheetfontformat(cell);
canvas.font = fontset;
@ -2147,7 +2264,8 @@ function getCellOverflowMap(canvas, col_st, col_ed, row_st, row_end){
edc = c;
}
if(((stc >= col_st && stc <= col_ed) || (edc >= col_st && edc <= col_ed)) && stc < edc){
// if(((stc >= col_st && stc <= col_ed) || (edc >= col_st && edc <= col_ed)) && stc < edc){
if(((stc <= col_ed) || (edc >= col_st)) && stc < edc){
map[r + '_' + c] = {
r: r,
stc: stc,

18
src/global/extend.js

@ -1,7 +1,7 @@
import editor from './editor';
import formula from './formula';
import { jfrefreshgrid_adRC, jfrefreshgrid_deleteCell, jfrefreshgrid_rhcw } from './refresh';
import { datagridgrowth } from './getdata';
import { datagridgrowth, getcellFormula } from './getdata';
import { setcellvalue } from './setdata';
import conditionformat from '../controllers/conditionformat';
import luckysheetFreezen from '../controllers/freezen';
@ -96,7 +96,7 @@ function luckysheetextendtable(type, index, value, direction, order) {
if(calcChain != null && calcChain.length > 0){
for(let i = 0; i < calcChain.length; i++){
let calc = $.extend(true, {}, calcChain[i]);
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = calc.func[2];
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);
if(type == "row"){
let functionStr = "=" + formula.functionStrChange(calc_funcStr, "add", "row", direction, index, value);
@ -105,7 +105,7 @@ function luckysheetextendtable(type, index, value, direction, order) {
d[calc_r][calc_c].f = functionStr;
}
calc.func[2] = functionStr;
// calc.func[2] = functionStr;
if(direction == "lefttop"){
if(calc_r >= index){
@ -127,7 +127,7 @@ function luckysheetextendtable(type, index, value, direction, order) {
d[calc_r][calc_c].f = functionStr;
}
calc.func[2] = functionStr;
// calc.func[2] = functionStr;
if(direction == "lefttop"){
if(calc_c >= index){
@ -890,7 +890,7 @@ function luckysheetdeletetable(type, st, ed, order) {
if(calcChain != null && calcChain.length > 0){
for(let i = 0; i < calcChain.length; i++){
let calc = $.extend(true, {}, calcChain[i]);
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = calc.func[2];
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);
if(type == "row"){
if(calc_r < st || calc_r > ed){
@ -900,7 +900,7 @@ function luckysheetdeletetable(type, st, ed, order) {
d[calc_r][calc_c].f = functionStr;
}
calc.func[2] = functionStr;
// calc.func[2] = functionStr;
if(calc_r > ed){
calc.r = calc_r - slen;
@ -917,7 +917,7 @@ function luckysheetdeletetable(type, st, ed, order) {
d[calc_r][calc_c].f = functionStr;
}
calc.func[2] = functionStr;
// calc.func[2] = functionStr;
if(calc_c > ed){
calc.c = calc_c - slen;
@ -1543,7 +1543,7 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
if(calcChain != null && calcChain.length > 0){
for(let i = 0; i < calcChain.length; i++){
let calc = $.extend(true, {}, calcChain[i]);
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = calc.func[2];
let calc_r = calc.r, calc_c = calc.c, calc_i = calc.index, calc_funcStr = getcellFormula(calc_r, calc_c, calc_i);
if((calc_r < str || calc_r > edr) && (calc_c < stc || calc_c > edc)){
let functionStr;
@ -1567,7 +1567,7 @@ function luckysheetDeleteCell(type, str, edr, stc, edc, order) {
d[calc_r][calc_c].f = functionStr;
}
calc.func[2] = functionStr;
// calc.func[2] = functionStr;
newCalcChain.push(calc);
}

70
src/global/formula.js

@ -10,7 +10,7 @@ import { seletedHighlistByindex, luckysheet_count_show } from '../controllers/se
import { isRealNum, isRealNull, valueIsError, isEditMode } from './validate';
import { isdatetime, isdatatype } from './datecontroll';
import { getCellTextSplitArr } from '../global/getRowlen';
import { getcellvalue } from './getdata';
import { getcellvalue,getcellFormula } from './getdata';
import { setcellvalue } from './setdata';
import { genarate, valueShowEs } from './format';
import editor from './editor';
@ -309,10 +309,8 @@ const luckysheetformula = {
oldvalue: null,
dontupdate: function() {
let _this = this;
Store.luckysheetCellUpdate.length = 0; //clear array
$("#luckysheet-functionbox-cell, #luckysheet-rich-text-editor").html(_this.oldvalue);
_this.cancelNormalSelected();
if (_this.rangetosheet != Store.currentSheetIndex) {
sheetmanage.changeSheetExec(_this.rangetosheet);
@ -1209,7 +1207,7 @@ const luckysheetformula = {
return;
}
}
else{
else if(curv!=null && curv.qp != 1){
if (getObjType(curv) == "object" && (value == curv.f || value == curv.v || value == curv.m)) {
_this.cancelNormalSelected();
return;
@ -1267,6 +1265,14 @@ const luckysheetformula = {
delete curv.f;
delete curv.spl;
if(curv.qp == 1 && value.substr(0,1)!="'"){//if quotePrefix is 1, cell is force string, cell clear quotePrefix when it is updated
curv.qp = 0;
if(curv.ct!=null){
curv.ct.fa = "General";
curv.ct.t = "n";
}
}
}
value = curv;
@ -3614,7 +3620,10 @@ const luckysheetformula = {
_this.operatorjson = op;
}
if (txt.substr(0, 1) == "=") {
if (txt.substr(0, 2) == "=+") {
txt = txt.substr(2);
}
else if (txt.substr(0, 1) == "=") {
txt = txt.substr(1);
}
@ -3845,7 +3854,7 @@ const luckysheetformula = {
i++;
}
console.log(function_str);
// console.log(function_str);
return function_str;
},
addFunctionGroup: function(r, c, func, index) {
@ -3887,7 +3896,7 @@ const luckysheetformula = {
return file.calcChain;
},
updateFunctionGroup: function(r, c, func, index) {
updateFunctionGroup: function(r, c, index) {
if (index == null) {
index = Store.currentSheetIndex;
}
@ -3900,7 +3909,6 @@ const luckysheetformula = {
for (let i = 0; i < calcChain.length; i++) {
let calc = calcChain[i];
if (calc.r == r && calc.c == c && calc.index == index) {
calcChain[i].func = func;
server.saveParam("fc", index, JSON.stringify(calc), {
"op": "update",
"pos": i
@ -3912,15 +3920,16 @@ const luckysheetformula = {
setluckysheetfile(luckysheetfile);
},
insertUpdateFunctionGroup: function(r, c, func, index) {
insertUpdateFunctionGroup: function(r, c, index) {
if (index == null) {
index = Store.currentSheetIndex;
}
if (func == null) {
this.delFunctionGroup(r, c, index);
return;
}
// let func = getcellFormula(r, c, index);
// if (func == null || func.length==0) {
// this.delFunctionGroup(r, c, index);
// return;
// }
let luckysheetfile = getluckysheetfile();
let file = luckysheetfile[getSheetIndex(index)];
@ -3933,7 +3942,6 @@ const luckysheetformula = {
for (let i = 0; i < calcChain.length; i++) {
let calc = calcChain[i];
if (calc.r == r && calc.c == c && calc.index == index) {
calc.func = func;
server.saveParam("fc", index, JSON.stringify(calc), {
"op": "update",
"pos": i
@ -3945,8 +3953,7 @@ const luckysheetformula = {
let cc = {
"r": r,
"c": c,
"index": index,
"func": func
"index": index
};
calcChain.push(cc);
file.calcChain = calcChain;
@ -4485,10 +4492,13 @@ const luckysheetformula = {
for (let i = 0; i < group.length; i++) {
let item = group[i];
let cell = luckysheetfile[getSheetIndex(item["index"])].data[item.r][item.c];
if(cell != null && cell.f != null && cell.f == item.func[2]){
let file =luckysheetfile[getSheetIndex(item["index"])];
if(file==null){
continue;
}
let cell = file.data[item.r][item.c];
let calc_funcStr = getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
if(cell != null && cell.f != null && cell.f == calc_funcStr){
if(!(item instanceof Object)){
item = eval('('+ item +')');
}
@ -4505,10 +4515,10 @@ const luckysheetformula = {
_this.isFunctionRangeSave = true;
}
else if (origin_r != null && origin_c != null) {
_this.isFunctionRange(item.func[2], origin_r, origin_c);
_this.isFunctionRange(calc_funcStr, origin_r, origin_c);
}
else {
_this.isFunctionRange(item.func[2]);
_this.isFunctionRange(calc_funcStr);
}
if (_this.isFunctionRangeSave) {
@ -4529,7 +4539,7 @@ const luckysheetformula = {
for (let i = 0; i < group.length; i++) {
let item = group[i];
let calc_funcStr = getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
item.color = "w";
item.parent = null;
item.chidren = {};
@ -4541,7 +4551,7 @@ const luckysheetformula = {
_this.isFunctionRangeSave = true;
}
else{
_this.isFunctionRange(item.func[2], cell.r, cell.c);
_this.isFunctionRange(calc_funcStr, cell.r, cell.c);
}
if (_this.isFunctionRangeSave) {
@ -4562,7 +4572,9 @@ const luckysheetformula = {
}
_this.isFunctionRangeSave = false;
_this.isFunctionRange(vertex1[name].func[2], u.r, u.c);
let item = vertex1[name];
let calc_funcStr = getcellFormula(item.r, item.c, item.index, _this.execFunctionGroupData);
_this.isFunctionRange(calc_funcStr, u.r, u.c);
if (_this.isFunctionRangeSave) {
let v = vertex1[name];
@ -4613,8 +4625,8 @@ const luckysheetformula = {
u.color = "b";
window.luckysheet_getcelldata_cache = null;
let v = _this.execfunction(u.func[2], u.r, u.c);
let calc_funcStr = getcellFormula(u.r, u.c, u.index, _this.execFunctionGroupData);
let v = _this.execfunction(calc_funcStr, u.r, u.c);
let value = _this.execFunctionGroupData[u.r][u.c];
if(value == null){
@ -4787,7 +4799,7 @@ const luckysheetformula = {
if (isrefresh) {
_this.execFunctionGroup(r, c, result);
}
_this.insertUpdateFunctionGroup(r, c, [true, result, txt]);
_this.insertUpdateFunctionGroup(r, c);
}
return [true, result, txt];
@ -4920,7 +4932,7 @@ const luckysheetformula = {
}
if(!notInsertFunc){
_this.insertUpdateFunctionGroup(r, c, [true, result, txt]);
_this.insertUpdateFunctionGroup(r, c);
}
}

16
src/global/getRowlen.js

@ -43,7 +43,7 @@ function rowlenByRange(d, r1, r2, cfg) {
let textMetrics = measureText.width; //文本宽度
let oneLineTextHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
let spaceHeight = Math.ceil(oneLineTextHeight/3);
let computeRowlen; //计算行高
let word_space_height = oneLineTextHeight/3;
if(cell.tb == "2"){
@ -54,10 +54,10 @@ function rowlenByRange(d, r1, r2, cfg) {
let strArr = []; //文本截断数组
strArr = getCellTextSplitArr(value, strArr, cellWidth, canvas);
computeRowlen = (oneLineTextHeight+word_space_height) * strArr.length + 4;
computeRowlen = (oneLineTextHeight+word_space_height) * strArr.length + spaceHeight;
}
else{
computeRowlen = oneLineTextHeight + 4;
computeRowlen = oneLineTextHeight + spaceHeight;
}
}
else if(cell.tr != null){
@ -66,25 +66,25 @@ function rowlenByRange(d, r1, r2, cfg) {
if(tr == "0"){
//无旋转
computeRowlen = oneLineTextHeight + 4;
computeRowlen = oneLineTextHeight + spaceHeight;
}
else if(tr == "1" || tr == "2"){
//向下倾斜(45 旋转)----向上倾斜(-45 旋转)
computeRowlen = 0.707 * (textMetrics + oneLineTextHeight) + 4;
computeRowlen = 0.707 * (textMetrics + oneLineTextHeight) + spaceHeight;
}
else if(tr == "3"){
//竖排文字
computeRowlen = value.length * oneLineTextHeight + 4;
computeRowlen = value.length * oneLineTextHeight + spaceHeight;
}
else if(tr == "4" || tr == "5"){
//向下90(90 旋转)----向上90(-90 旋转)
computeRowlen = textMetrics + 4;
computeRowlen = textMetrics + spaceHeight;
}
computeRowlen = Math.round(computeRowlen);
}
else{
computeRowlen = oneLineTextHeight + 4;
computeRowlen = oneLineTextHeight + spaceHeight;
}
//比较计算高度和当前高度取最大高度

43
src/global/getdata.js

@ -4,6 +4,7 @@ import server from '../controllers/server';
import formula from './formula';
import editor from './editor';
import { dynamicArrayCompute } from './dynamicArray';
import sheetmanage from '../controllers/sheetmanage';
import Store from '../store';
//Get selection range value
@ -218,4 +219,46 @@ export function datagridgrowth(data, addr, addc, iscallback) {
}
return data;
}
//Get the formula of the cell
export function getcellFormula(r, c, i, data) {
let cell;
if(data!=null){
cell = data[r][c];
}
else{
cell = getOrigincell(r,c,i);
}
if(cell==null){
return null;
}
return cell.f;
}
export function getOrigincell(r, c, i) {
if(r==null || c==null){
return;
}
let data;
if (i == null) {
data = Store.flowdata;
}
else{
let sheet = sheetmanage.getSheetByIndex(i);
data = sheet.data;
}
if(data==null){
return;
}
return data[r][c];
}

4
src/global/method.js

@ -160,6 +160,10 @@ const method = {
$("#luckysheet-modal-dialog-mask, #luckysheetTextSizeTest, #luckysheet-icon-morebtn-div").remove();
$("#luckysheet-input-box").parent().remove();
$("#luckysheet-formula-help-c").remove();
$(".chartSetting").remove();
//document event release
$(document).off(".luckysheetEvent");
//参数重置
Store.jfredo = [];

5
src/global/refresh.js

@ -2,6 +2,7 @@ import rhchInit from './rhchInit';
import formula from './formula';
import editor from './editor';
import { setcellvalue } from './setdata';
import { getcellFormula } from './getdata';
import { computeRowlenArr } from './getRowlen';
import {
luckysheetDrawMain,
@ -363,7 +364,7 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf,
for(let i = 0; i < calc.length; i++){
let clc = calc[i];
let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = clc.func[2];
let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i);
let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, null, true);
clc.func = clc_result;
@ -567,7 +568,7 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf){
for(let i = 0; i < calc.length; i++){
let clc = calc[i];
let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = clc.func[2];
let clc_r = clc.r, clc_c = clc.c, clc_i = clc.index, clc_funcStr = getcellFormula(clc_r, clc_c, clc_i);
let clc_result = formula.execfunction(clc_funcStr, clc_r, clc_c, null, true);
clc.func = clc_result;

6
src/global/rhchInit.js

@ -69,9 +69,9 @@ export default function rhchInit(rowheight, colwidth) {
Store.visibledatacolumn.push(Store.ch_width);//列的临时长度分布
if(maxColumnlen < firstcolumnlen + 1){
maxColumnlen = firstcolumnlen + 1;
}
// if(maxColumnlen < firstcolumnlen + 1){
// maxColumnlen = firstcolumnlen + 1;
// }
}
// Store.ch_width += 120;

6
src/global/setdata.js

@ -58,6 +58,12 @@ function setcellvalue(r, c, d, v) {
cell.m = vupdate.toString().substr(1);
cell.ct = { "fa": "@", "t": "s" };
cell.v = vupdate.toString().substr(1);
cell.qp = 1;
}
else if(cell.qp == 1){
cell.m = vupdate.toString();
cell.ct = { "fa": "@", "t": "s" };
cell.v = vupdate.toString();
}
else if(vupdate.toString().toUpperCase() === "TRUE"){
cell.m = "TRUE";

44
src/index.html

@ -33,11 +33,51 @@
luckysheet.create({
container: 'luckysheet',
lang: 'zh',
lang: 'en',
allowEdit:true,
forceCalculation:false,
plugins: ['chart'],
data: [sheetCell,sheetFormula,sheetConditionFormat,sheetTable,sheetSparkline,sheetComment,sheetPivotTableData,sheetPivotTable,sheetChart]
data: [{"name":"Sheet1","config":{"columnlen":{"0":241},"rowlen":{"0":81}},"index":"1","status":"1","order":"0","luckysheet_select_save":[{"row":[0,0],"column":[4,4],"sheetIndex":1}],"zoomRatio":1,"showGridLines":"1","defaultColWidth":72,"defaultRowHeight":18,"celldata":[
{"r":0,"c":0,
"v":{
"ct":{
"fa":"General",
"t":"inlineStr",
"sharedStrings":[
{
"ff":"等线", //font family
"fc":"#fff000",//font color
"fs":12,//font size
"cl":1,//strike
"un":0,//underline
"bl":0,//blod
"it":1,//italic
v:"我在"
},
{
"t":1,//换行符
},
{
"ff":"等线", //font family
"fc":"#ff0000",//font color
"fs":14,//font size
"cl":"1",//strike
"un":"0",//underline
"bl":"1",//blod
"it":"0",//italic
v:"马路边"
},
]
},
"fs":11,
"ff":"等线",
"vt":0,
"tb":2,
"v":"",
"qp":1,
}
}
],"calcChain":[]}]
})
})

4
src/store/index.js

@ -26,6 +26,7 @@ const Store = {
sheetBarHeight: 27,
statisticBarHeight: 23,
luckysheetTableContentHW: [0, 0],
defaultcollen: 73,
defaultrowlen: 19,
@ -121,6 +122,9 @@ const Store = {
visibledatacolumn_unique:null,
visibledatarow_unique:null,
showGridLines:true,
}
export default Store;
Loading…
Cancel
Save