diff --git a/README-zh.md b/README-zh.md index ebc83e7..2531f3e 100644 --- a/README-zh.md +++ b/README-zh.md @@ -171,7 +171,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) ## 版权信息 diff --git a/README.md b/README.md index 8bcf504..2fc6d0a 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Create a table }) ``` -## Join the co-construction +## 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. @@ -169,7 +169,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 diff --git a/docs/guide/FAQ.md b/docs/guide/FAQ.md index 6712b0c..56c6ad0 100644 --- a/docs/guide/FAQ.md +++ b/docs/guide/FAQ.md @@ -42,8 +42,32 @@ luckysheet.buildGridData(luckysheetfile) ------------ -## **Q** How to understand the `index` and `order` of each worksheet? +## **Q** What is the difference between `index` and `order` for each sheet page? -**A**: Each worksheet has a unique id, which is `index`, which can be incremented by numbers or a random string. And `order` is the order of all worksheets, starting from 0. +**A**: Each sheet page has a unique id, which is `index`, which can be incremented by numbers or a random string. And `order` is the sorting situation of all sheets, starting from 0, can only be numbers `0,1,2...`. ------------ + +## **Q** Why can’t I run the project directly under the dist folder? + +**A**: Need to start the local server + +- [Node build a local server](https://github.com/JacksonTian/anywhere) +- [Python build local server](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server) + +------------ + +## **Q** How to import and export excel? + +**A**: You can refer to the following cases at this stage +- Luckysheet import: https://www.cnblogs.com/DuShuSir/p/13179483.html +- Luckysheet export: https://www.cnblogs.com/recode-hyh/p/13168226.html + +Later, we will open another import and export library for adaptation, so stay tuned! + +------------ + +## **Q** How to merge cells during initialization? + +**A**: Refer to the following case +- Luckysheet initializes data with merged cells: https://www.cnblogs.com/DuShuSir/p/13272397.html \ No newline at end of file diff --git a/docs/zh/guide/FAQ.md b/docs/zh/guide/FAQ.md index 4591e9c..164fb98 100644 --- a/docs/zh/guide/FAQ.md +++ b/docs/zh/guide/FAQ.md @@ -42,8 +42,32 @@ luckysheet.buildGridData(luckysheetfile) ------------ -## **Q** 如何理解每个sheet页的`index`和`order`? +## **Q** 每个sheet页的`index`和`order`有什么区别? -**A** : 每个sheet页都有一个唯一id,就是`index`,可以用数字递增,也可以使用随机字符串,而`order`是所有的sheet的排序情况,从0开始,即为索引。 +**A** : 每个sheet页都有一个唯一id,就是`index`,可以用数字递增,也可以使用随机字符串,而`order`是所有的sheet的排序情况,从0开始,只能为数字`0,1,2...`。 ------------- \ No newline at end of file +------------ + +## **Q** dist文件夹下为什么不能直接运行项目? + +**A** :需要启动本地服务器 + +- [Node搭建本地服务器](https://github.com/JacksonTian/anywhere) +- [Python搭建本地服务器](https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/set_up_a_local_testing_server) + +------------ + +## **Q** excel导入导出怎么做? + +**A** :现阶段可以参考以下案例 +- Luckysheet导入: https://www.cnblogs.com/DuShuSir/p/13179483.html +- Luckysheet导出 : https://www.cnblogs.com/recode-hyh/p/13168226.html + +后期会另外开源一个导入导出库做适配,敬请期待! + +------------ + +## **Q** 初始化时合并单元格怎么做? + +**A** :参考以下案例 +- Luckysheet初始化含合并单元格的数据: https://www.cnblogs.com/DuShuSir/p/13272397.html diff --git a/docs/zh/guide/api.md b/docs/zh/guide/api.md index ac5aaef..f7e209e 100644 --- a/docs/zh/guide/api.md +++ b/docs/zh/guide/api.md @@ -2010,6 +2010,14 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ +### toJson() + +- **说明**: + + 导出的json字符串可以直接当作`luckysheet.create(options)`初始化工作簿时的参数`options`使用,使用场景在用户自己操作表格后想要手动保存全部的参数,再去别处初始化这个表格使用,类似一个luckysheet专有格式的导入导出。 + +------------ + ## 旧版API ::: warning diff --git a/docs/zh/guide/cell.md b/docs/zh/guide/cell.md index b048210..3751860 100644 --- a/docs/zh/guide/cell.md +++ b/docs/zh/guide/cell.md @@ -147,6 +147,15 @@ + + ae + allowEdit + 是否允许编辑 + + 0: 只读,不可编辑 1:可以编辑,默认为 1 + + + 一个规范的单元格对象如下: diff --git a/docs/zh/guide/config.md b/docs/zh/guide/config.md index a20a4ac..4fb5ccf 100644 --- a/docs/zh/guide/config.md +++ b/docs/zh/guide/config.md @@ -22,44 +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) -- [showinfobar](#showinfobar) -- [showsheetbar](#showsheetbar) -- [showstatisticBar](#showstatisticBar) -- [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) +- 容器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 @@ -70,7 +85,7 @@ luckysheet.create(options) ### title - 类型:String - 默认值:"Luckysheet Demo" -- 作用:表格的名称 +- 作用:工作簿名称 ------------ ### lang @@ -162,6 +177,48 @@ luckysheet.create(options) - 默认值:true - 作用:是否第二列显示工具栏 +------------ +### showtoolbarConfig +- 类型:Object +- 默认值:{} +- 作用:自定义配置工具栏 +- 格式: + ```json + { + undoRedo: false, //撤销重做 + paintFormat: false, //格式刷 + currencyFormat: false, //货币格式 + percentageFormat: false, //百分比格式 + numberDecrease: false, // '减少小数位数' + numberIncrease: false, // '增加小数位数 + moreFormats: false, // '更多格式' + font: false, // '字体' + fontSize: false, // '字号大小' + bold: false, // '粗体 (Ctrl+B)' + italic: false, // '斜体 (Ctrl+I)' + strikethrough: false, // '删除线 (Alt+Shift+5)' + textColor: false, // '文本颜色' + fillColor: false, // '单元格颜色' + border: false, // '边框' + mergeCell: false, // '合并单元格' + horizontalAlignMode: false, // '水平对齐方式' + verticalAlignMode: false, // '垂直对齐方式' + textWrapMode: false, // '换行方式' + textRotateMode: false, // '文本旋转方式' + frozenMode: false, // '冻结方式' + sort: false, // '排序' + filter: false, // '筛选' + findAndReplace: false, // '查找替换' + function: false, // '公式' + conditionalFormat: false, // '条件格式' + postil: false, //'批注' + pivotTable: false, //'数据透视表' + chart: false, // '图表'(图标隐藏,但是如果配置了chart插件,右击仍然可以新建图表) + screenshot: false, // '截图' + splitColumn: false, // '分列' + } + ``` + ------------ ### showinfobar - 类型:Boolean @@ -172,7 +229,21 @@ luckysheet.create(options) ### showsheetbar - 类型:Boolean - 默认值:true -- 作用:是否显示底部表格名称区域 +- 作用:是否显示底部sheet页按钮 + +------------ +### showsheetbarConfig +- 类型:Object +- 默认值:{} +- 作用:自定义配置底部sheet页按钮 +- 格式: + ```json + { + add: false, //新增sheet + menu: false, //sheet管理菜单 + sheet: false //sheet页显示 + } + ``` ------------ ### showstatisticBar @@ -180,6 +251,30 @@ luckysheet.create(options) - 默认值:true - 作用:是否显示底部计数栏 +------------ +### showstatisticBarConfig +- 类型:Object +- 默认值:{} +- 作用:自定义配置底部计数栏 +- 格式: + ```json + { + count: false, // 计数栏 + zoom: false // 缩放 + } + +------------ +### sheetBottomConfig +- 类型:Object +- 默认值:{} +- 作用:sheet页下方的添加行按钮和回到顶部按钮配置 +- 格式: + ```json + { + addRow: false, // 添加行按钮 + backTop: false // 回到顶部 + } + ------------ ### allowEdit - 类型:Boolean @@ -246,18 +341,6 @@ luckysheet.create(options) - 默认值:true - 作用:是否全屏模式。非全屏模式下,标记框不会强制选中 ------------- -### beforeCreateDom -- 类型:Function -- 默认值:null -- 作用:表格创建之前自定义方法 - ------------- -### fireMousedown -- 类型:Function -- 默认值:null -- 作用:单元格数据下钻自定义方法 - ------------ ### forceCalculation - 类型:Boolean @@ -270,4 +353,134 @@ luckysheet.create(options) ⚠️提醒,公式较多时会有性能问题,慎用! +------------ +### 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 // '图表生成' + } + +------------ +### sheetRightClickConfig +- 类型:Object +- 默认值:{} +- 作用:自定义配置sheet页右击菜单 +- 格式: + ```json + { + delete: false, // '删除' + copy: false, // '复制' + rename: false, //重命名 + color: false, //更改颜色 + hide: false, //隐藏 + show: false, //取消隐藏 + left: false, //向左移 + right: false //向右移 + } + +------------ + +## 钩子函数 + +钩子函数应用于二次开发时,会在各个常用鼠标或者键盘操作时植入钩子,调用开发者传入的函数,起到扩展Luckysheet功能的作用。 + +钩子函数统一配置在`options.hook`下,可以分别针对单元格、sheet页、表格创建配置hook。 + +------------ +### cellHover +- 类型:Function +- 默认值:null +- 作用:鼠标移过单元格时(hover)触发 +- 参数: + - {Number} [r]: 单元格所在行数 + - {Number} [c]: 单元格所在列数 + - {Object} [v]: 单元格对象 + +------------ +### cellClickBefore +- 类型:Function +- 默认值:null +- 作用:点击单元格前触发,即在点击单元格的时候,最先触发这个方法 + +------------ +### cellClicked +- 类型:Function +- 默认值:null +- 作用:点击单元格后触发,即在点击单元格的时候,最后触发这个方法 + +------------ +### cellEditBefore +- 类型:Function +- 默认值:null +- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最先触发这个方法 + +------------ +### cellEdited +- 类型:Function +- 默认值:null +- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最后触发这个方法 + +------------ +### sheetClickBefore +- 类型:Function +- 默认值:null +- 作用:点击sheet页前触发 + +------------ +### sheetClicked +- 类型:Function +- 默认值:null +- 作用:点击sheet页后触发 + +------------ +### workbookCreateBefore +- 类型:Function +- 默认值:null +- 作用:表格创建之前触发。旧的钩子函数叫做`beforeCreateDom` + +------------ +### workbookCreated +- 类型:Function +- 默认值:null +- 作用:表格创建之后触发 + +------------ +### workbookUpdated +- 类型:Function +- 默认值:null +- 作用:表格创建之后触发 + +------------ +### workbookDestroyBefore +- 类型:Function +- 默认值:null +- 作用:表格创建之后触发 + +------------ +### workbookDestroyed +- 类型:Function +- 默认值:null +- 作用:表格创建之后触发 + +------------ +### fireMousedown +- 类型:Function +- 默认值:null +- 作用:单元格数据下钻自定义方法 + ------------ \ No newline at end of file diff --git a/docs/zh/guide/sheet.md b/docs/zh/guide/sheet.md index b831b31..90560e7 100644 --- a/docs/zh/guide/sheet.md +++ b/docs/zh/guide/sheet.md @@ -37,8 +37,9 @@ options.data示例如下: "luckysheet_alternateformat_save": [], //交替颜色 "luckysheet_alternateformat_save_modelCustom": [], //自定义交替颜色 "luckysheet_conditionformat_save": {},//条件格式 - "frozen": {}, //冻结行列 + "frozen": {}, //冻结行列配置 "chart": [], //图表配置 + "allowEdit": true, //是否允许编辑 }, { "name": "Sheet2", @@ -148,6 +149,8 @@ options.data示例如下: - 默认值:{} - 作用:表格行高、列宽、合并单元格、边框、隐藏行等设置 + 注意,config如果为空,必须为空对象`{}`,不能为字符串或者null + #### config.merge - 类型:Object - 默认值:{} @@ -721,6 +724,12 @@ options.data示例如下: - 默认值:[] - 作用: 图表配置 +------------ +### allowEdit +- 类型:Boolean +- 默认值:true +- 作用: 此sheet页是否允许编辑 + ------------ ## 调试信息 @@ -763,7 +772,8 @@ Luckysheet在初始化完成之后进行的一系列操作,会将更多本地 "luckysheet_alternateformat_save": [], //交替颜色 "luckysheet_alternateformat_save_modelCustom": [], //自定义交替颜色 "luckysheet_conditionformat_save": {},//条件格式 - "freezen": {}, //冻结行列 + "frozen": {}, //冻结行列配置 + "freezen": {}, //冻结行列的渲染数据存储 "chart": [], //图表配置 "visibledatarow": [], //所有行的位置 diff --git a/src/controllers/handler.js b/src/controllers/handler.js index 559070e..c0b93b1 100644 --- a/src/controllers/handler.js +++ b/src/controllers/handler.js @@ -109,7 +109,7 @@ export default function luckysheetHandler() { const _locale = locale(); const locale_drag = _locale.drag; const locale_info = _locale.info; - let prev + let prev, mousewheelArrayUniqueTimeout; $("#luckysheet-grid-window-1").mousewheel(function (event, delta) { let scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft(), scrollTop = $("#luckysheet-scrollbar-y").scrollTop(); @@ -124,8 +124,26 @@ export default function luckysheetHandler() { visibledatacolumn_c = luckysheetFreezen.freezenverticaldata[3]; } - visibledatacolumn_c = ArrayUnique(visibledatacolumn_c); - visibledatarow_c = ArrayUnique(visibledatarow_c); + clearTimeout(mousewheelArrayUniqueTimeout); + + if(Store.visibledatacolumn_unique!=null){ + visibledatacolumn_c = Store.visibledatacolumn_unique; + } + else{ + visibledatacolumn_c = ArrayUnique(visibledatacolumn_c); + Store.visibledatacolumn_unique = visibledatacolumn_c; + } + + if(Store.visibledatarow_unique!=null){ + visibledatarow_c = Store.visibledatarow_unique; + } + else{ + visibledatarow_c = ArrayUnique(visibledatarow_c); + Store.visibledatarow_unique = visibledatarow_c; + } + + // visibledatacolumn_c = ArrayUnique(visibledatacolumn_c); + // visibledatarow_c = ArrayUnique(visibledatarow_c); let col_st = luckysheet_searcharray(visibledatacolumn_c, scrollLeft); let row_st = luckysheet_searcharray(visibledatarow_c, scrollTop); @@ -180,6 +198,11 @@ export default function luckysheetHandler() { $("#luckysheet-scrollbar-x").scrollLeft(scrollLeft); } + + mousewheelArrayUniqueTimeout = setTimeout(() => { + Store.visibledatacolumn_unique = null; + Store.visibledatarow_unique = null; + }, 200); }); $("#luckysheet-scrollbar-x").scroll(function(){ diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js index 1afc7d2..d618271 100644 --- a/src/controllers/sheetmanage.js +++ b/src/controllers/sheetmanage.js @@ -694,6 +694,7 @@ const sheetmanage = { } let execF = function(){ + _this.mergeCalculation(file["index"]); _this.storeSheetParam(); _this.restoreselect(); _this.CacheNotLoadControll = []; @@ -903,6 +904,48 @@ const sheetmanage = { Store.luckysheetfile[index]["data"] = Store.flowdata; Store.luckysheetfile[index]["config"] = $.extend(true, {}, Store.config); }, + mergeCalculationSheet:{}, + mergeCalculation:function(index){ + let file = Store.luckysheetfile[this.getSheetIndex(index)]; + let config = file.config, data = file.data, mergeConfig = config.merge; + if(mergeConfig==null || index in this.mergeCalculationSheet || file["autoCalculationMerge"]===false){ + return; + } + + this.mergeCalculationSheet[index] = 1; + + for(let x in mergeConfig){ + let r = parseInt(x.substr(0, x.indexOf('_'))); + let c = parseInt(x.substr(x.indexOf('_') + 1)); + let mcInfo = mergeConfig[x]; + if(data[r][c]==null){ + data[r][c] = {}; + } + + data[r][c]["mc"] = { + r:r, + c:c, + rs:mcInfo.rs, + cs:mcInfo.cs, + } + + for(let ir=r;ir 0) { for (let i = 0; i < dataArr.length; i++) { - if (arr.indexOf(dataArr[i]) == -1) { - arr.push(dataArr[i]); + let item = dataArr[i]; + if (!obj[item]) { + result.push(item); + obj[item] = 1; } } } - - return arr; + return result } //获取字体配置