From 1b571f98b3df1ca849e7ada1ee0a83a6e10d783e Mon Sep 17 00:00:00 2001 From: "CN\\wuwx26" Date: Wed, 30 Dec 2020 15:53:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gulpfile.js | 3 +- src/controllers/controlHistory.js | 5 +- src/controllers/protection.js | 4 +- src/controllers/selection.js | 7 +- src/controllers/sheetBar.js | 5 + src/controllers/sheetmanage.js | 50 +++---- src/core.js | 2 + src/css/luckysheet-core.css | 4 +- src/global/api.js | 39 +++++- src/global/draw.js | 5 +- src/global/getdata.js | 2 +- src/global/refresh.js | 9 +- src/global/scroll.js | 8 +- src/plugins/css/jquery.sPage.css | 132 +++++++++++++++++++ src/plugins/js/jquery.sPage.min.js | 202 +++++++++++++++++++++++++++++ 15 files changed, 440 insertions(+), 37 deletions(-) create mode 100644 src/plugins/css/jquery.sPage.css create mode 100644 src/plugins/js/jquery.sPage.min.js diff --git a/gulpfile.js b/gulpfile.js index 3a84a7f..0e3e2ff 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -96,7 +96,8 @@ const paths = { 'src/plugins/js/localforage.min.js', 'src/plugins/js/lodash.min.js', 'src/plugins/js/jstat.min.js', - 'src/plugins/js/crypto-api.min.js' + 'src/plugins/js/crypto-api.min.js', + 'src/plugins/js/jquery.sPage.min.js' ], //plugins concat diff --git a/src/controllers/controlHistory.js b/src/controllers/controlHistory.js index 67f48e4..c27d68e 100644 --- a/src/controllers/controlHistory.js +++ b/src/controllers/controlHistory.js @@ -428,8 +428,11 @@ const controlHistory = { } Store.clearjfundo = true; + // 撤销的时候curdata 跟 data 数据要调换一下 + let newCtr = {...ctr, ...{data: ctr.curdata, curdata: ctr.data}} // 钩子函数 - method.createHookFunction('updated',ctr) + method.createHookFunction('updated', newCtr) + }, undo: function () { if (Store.jfundo.length == 0) { diff --git a/src/controllers/protection.js b/src/controllers/protection.js index 358d61a..13e2940 100644 --- a/src/controllers/protection.js +++ b/src/controllers/protection.js @@ -909,7 +909,7 @@ export function checkProtectionLocked(r, c, sheetIndex){ return true; } - if(cell!=null && cell.lo!=null && cell.lo!=1){ + if(cell && !cell.lo){ return true; } @@ -1003,7 +1003,7 @@ export function checkProtectionSelectLockedOrUnLockedCells(r, c, sheetIndex){ return true; } - if(cell!=null && cell.lo!=null && cell.lo!=1){//unlocked + if(cell && !cell.lo){//unlocked if(aut.selectunLockedCells==1 || aut.selectunLockedCells==null){ return true; } diff --git a/src/controllers/selection.js b/src/controllers/selection.js index 0a04fe6..f4a6428 100644 --- a/src/controllers/selection.js +++ b/src/controllers/selection.js @@ -814,7 +814,12 @@ const selection = { let value = dataChe[r][c]; if(isRealNum(value)){ - value = parseFloat(value); + // 如果单元格设置了纯文本格式,那么就不要转成数值类型了,防止数值过大自动转成科学计数法 + if (originCell && originCell.ct && originCell.ct.fa === '@') { + value = String(value); + } else { + value = parseFloat(value); + } } let originCell = x[c + curC]; if(originCell instanceof Object){ diff --git a/src/controllers/sheetBar.js b/src/controllers/sheetBar.js index 3de909b..458ba9f 100644 --- a/src/controllers/sheetBar.js +++ b/src/controllers/sheetBar.js @@ -525,4 +525,9 @@ export function initialSheetBar(){ $("#luckysheet-input-box").removeAttr("style"); }); + // 初始化分页器 + if (luckysheetConfigsetting.pager) { + pagerInit(luckysheetConfigsetting.pager) + } + } diff --git a/src/controllers/sheetmanage.js b/src/controllers/sheetmanage.js index a9457dd..7db08fc 100644 --- a/src/controllers/sheetmanage.js +++ b/src/controllers/sheetmanage.js @@ -592,33 +592,39 @@ const sheetmanage = { return ret; }, buildGridData: function(file) { + // 如果已经存在二维数据data,那么直接返回data;如果只有celldata,那么就转化成二维数组data,再返回 let row = file.row == null ? Store.defaultrowNum : file.row, - column = file.column == null ? Store.defaultcolumnNum : file.column; - let data = datagridgrowth([], row, column); - - let celldata = file.celldata; - if(celldata != null){ - for(let i = 0; i < celldata.length; i++){ - let item = celldata[i]; - let r = item.r; - let c = item.c; - let v = item.v; - - if(r >= data.length){ - data = datagridgrowth(data, r - data.length + 1, 0); + column = file.column == null ? Store.defaultcolumnNum : file.column, + data = file.data && file.data.length > 0 ? file.data : datagridgrowth([], row, column), + celldata = file.celldata; + if (file.data && file.data.length > 0) { + for (let i = 0; i < data.length; i++) { + for (let j = 0; j < data[0].length; j++) { + setcellvalue(i, j, data, data[i][j]); } - if(c >= data[0].length){ - data = datagridgrowth(data, 0, c - data[0].length + 1); + } + } else { + if(celldata && celldata.length > 0){ + for(let i = 0; i < celldata.length; i++){ + let item = celldata[i]; + let r = item.r; + let c = item.c; + let v = item.v; + + if(r >= data.length){ + data = datagridgrowth(data, r - data.length + 1, 0); + } + if(c >= data[0].length){ + data = datagridgrowth(data, 0, c - data[0].length + 1); + } + setcellvalue(r, c, data, v); } - - setcellvalue(r, c, data, v); } } //亿万格式+精确度 恢复全局初始化 luckysheetConfigsetting.autoFormatw = false; luckysheetConfigsetting.accuracy = undefined; - return data; }, cutGridData: function(d) { @@ -1145,9 +1151,8 @@ const sheetmanage = { _this.storeSheetParamALL(); _this.setCurSheet(index); - let file = Store.luckysheetfile[_this.getSheetIndex(index)], - data = file.data, - cfg = file.config; + let file = Store.luckysheetfile[_this.getSheetIndex(index)] + if (!!file.isPivotTable) { Store.luckysheetcurrentisPivotTable = true; if (!isPivotInitial) { @@ -1162,7 +1167,8 @@ const sheetmanage = { let load = file["load"]; if (load != null) { - + let data = _this.buildGridData(file); + file.data = data; // _this.loadOtherFile(file); _this.mergeCalculation(index); diff --git a/src/core.js b/src/core.js index bee8a45..013ce6b 100644 --- a/src/core.js +++ b/src/core.js @@ -134,6 +134,8 @@ luckysheet.create = function (setting) { luckysheetConfigsetting.container = extendsetting.container; luckysheetConfigsetting.hook = extendsetting.hook; + luckysheetConfigsetting.pager = extendsetting.pager; + if (Store.lang === 'zh') flatpickr.localize(Mandarin.zh); // Store the currently used plugins for monitoring asynchronous loading diff --git a/src/css/luckysheet-core.css b/src/css/luckysheet-core.css index c995f00..e484081 100644 --- a/src/css/luckysheet-core.css +++ b/src/css/luckysheet-core.css @@ -1043,7 +1043,7 @@ div.luckysheet-sheets-m:hover { padding: 0px 0px; margin-left: 0px; position: relative; - width: 70%; + max-width: 50%; vertical-align: bottom; } @@ -7220,7 +7220,7 @@ fieldset[disabled] .btn-danger.focus { border: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); position: absolute; - z-index: 1000; + z-index: 10000; box-sizing: border-box; } #luckysheet-dataVerification-dropdown-List .dropdown-List-item{ diff --git a/src/global/api.js b/src/global/api.js index 8b8e5b6..2d19c17 100644 --- a/src/global/api.js +++ b/src/global/api.js @@ -6459,4 +6459,41 @@ export function getTxtByRange(range=Store.luckysheet_select_save){ range = [range]; } return conditionformat.getTxtByRange(range); -} \ No newline at end of file +} + + +/** + * 根据范围字符串转换为range数组 + * @param {Object} config 分页器配置 + */ +export function pagerInit (config) { + $('#luckysheet-bottom-pager').remove() + $('#luckysheet-sheet-area').append('
') + $("#luckysheet-bottom-pager").sPage({ + page: config.pageIndex, //当前页码,必填 + total: config.total, //数据总条数,必填 + selectOption: config.selectOption, // 选择每页的行数, + pageSize: config.pageSize, //每页显示多少条数据,默认10条 + showTotal: true, // 是否显示总数 + showSkip: config.showSkip || true, //是否显示跳页,默认关闭:false + showPN: config.showPN || true, //是否显示上下翻页,默认开启:true + backFun: function (page) { + page.pageIndex = page.page + if(!method.createHookFunction("onTogglePager", page)){ return; } + } + }); +} + +/** + * 根据范围字符串转换为range数组 + * @param {Function} success 回调函数 + */ +export function refreshFormula (success) { + formula.execFunctionGroupForce(true); + luckysheetrefreshgrid() + setTimeout(() => { + if (success && typeof success === 'function') { + success(); + } + }) +} diff --git a/src/global/draw.js b/src/global/draw.js index e36a9cf..fc6a7e8 100644 --- a/src/global/draw.js +++ b/src/global/draw.js @@ -2141,7 +2141,10 @@ function cellTextRender(textInfo, ctx, option){ ctx.font = word.style; } - ctx.fillText(word.content, (pos_x + word.left)/Store.zoomRatio, (pos_y+word.top)/Store.zoomRatio); + // 暂时未排查到word.content第一次会是object,先做下判断来渲染,后续找到问题再复原 + let txt = typeof word.content === 'object' ? word.content.m : word.content + ctx.fillText(txt, (pos_x + word.left)/Store.zoomRatio, (pos_y+word.top)/Store.zoomRatio); + if(word.cancelLine!=null){ let c = word.cancelLine; diff --git a/src/global/getdata.js b/src/global/getdata.js index 3e35867..239de14 100644 --- a/src/global/getdata.js +++ b/src/global/getdata.js @@ -260,7 +260,7 @@ export function getOrigincell(r, c, i) { data = sheet.data; } - if(data==null){ + if(!data || !data[r] || !data[r][c]){ return; } diff --git a/src/global/refresh.js b/src/global/refresh.js index 5cfb754..3dd5db0 100644 --- a/src/global/refresh.js +++ b/src/global/refresh.js @@ -111,7 +111,8 @@ function jfrefreshgrid(data, range, allParam, isRunExecFunction = true, isRefres "dataVerification": $.extend(true, [], file["dataVerification"]), "curDataVerification": curDataVerification, "dynamicArray": $.extend(true, [], file["dynamicArray"]), - "curDynamicArray": curDynamicArray + "curDynamicArray": curDynamicArray, + "dataRange": [...file.luckysheet_select_save] }); } @@ -449,7 +450,8 @@ function jfrefreshgrid_adRC(data, cfg, ctrlType, ctrlValue, calc, filterObj, cf, "dataVerification": $.extend(true, {}, file.dataVerification), "curDataVerification": dataVerification, "hyperlink": $.extend(true, {}, file.hyperlink), - "curHyperlink": hyperlink + "curHyperlink": hyperlink, + "dataRange": [...file.luckysheet_select_save] }); } @@ -684,7 +686,8 @@ function jfrefreshgrid_deleteCell(data, cfg, ctrl, calc, filterObj, cf, dataVeri "dataVerification": $.extend(true, {}, file.dataVerification), "curDataVerification": dataVerification, "hyperlink": $.extend(true, {}, file.hyperlink), - "curHyperlink": hyperlink + "curHyperlink": hyperlink, + "dataRange": [...file.luckysheet_select_save] }); } diff --git a/src/global/scroll.js b/src/global/scroll.js index f2a5d1e..a3fb589 100644 --- a/src/global/scroll.js +++ b/src/global/scroll.js @@ -2,7 +2,7 @@ import luckysheetFreezen from '../controllers/freezen'; import { luckysheet_searcharray } from '../controllers/sheetSearch'; import { luckysheetrefreshgrid } from '../global/refresh'; import Store from '../store'; - +import method from '../global/method' let scrollRequestAnimationFrameIni = true,scrollRequestAnimationFrame = false, scrollTimeOutCancel=null; @@ -17,7 +17,8 @@ function execScroll(){ export default function luckysheetscrollevent(isadjust) { let $t = $("#luckysheet-cell-main"); let scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft(), - scrollTop = $("#luckysheet-scrollbar-y").scrollTop(); + scrollTop = $("#luckysheet-scrollbar-y").scrollTop(), + canvasHeight = $("#luckysheetTableContent").height(); // canvas高度 // clearTimeout(scrollTimeOutCancel); @@ -106,4 +107,7 @@ export default function luckysheetscrollevent(isadjust) { if(luckysheetFreezen.freezenhorizontaldata != null || luckysheetFreezen.freezenverticaldata != null){ luckysheetFreezen.scrollAdapt(); } + + if(!method.createHookFunction("scroll", {scrollLeft, scrollTop, canvasHeight})){ return; } + } \ No newline at end of file diff --git a/src/plugins/css/jquery.sPage.css b/src/plugins/css/jquery.sPage.css new file mode 100644 index 0000000..236c190 --- /dev/null +++ b/src/plugins/css/jquery.sPage.css @@ -0,0 +1,132 @@ +#luckysheet-bottom-pager { + margin-right: 10px; + float: right; +} +.spage-total { + display: inline-block; + margin-right: 10px; + line-height: 29px; + color: #666; + font-size: 14px +} + +.spage-number { + display: inline-block; + color: #666; + font-size: 14px +} +.selectNum { + font-size: 14px; + height: 27px; + box-sizing: border-box; + vertical-align: top; + line-height: 27px; + border: 1px solid #ddd; + margin-left: 5px; + vertical-align: middle; +} +.spage-number button { + position: relative; + box-sizing: border-box; + display: inline-block; + margin-left: -1px; + padding: 0 10px; + line-height: 27px; + border: 1px solid #ddd; + text-align: center; + transition: all .2s; + cursor: pointer; + outline: none; + background: 0 0; + user-select: none; + color: #333; + background: #fff; + vertical-align: middle; +} +.prevBtn, .nextBtn { + width: 16px; + height: 27px; + background: url(../images/js.png) no-repeat center center; + background-size: 100% auto; + display: block; + transform: rotate(180deg); +} +.nextBtn { + transform: rotate(0); +} +.spage-number button.active { + background: #2d98e6; + color: #fff; + border-color: #2d98e6; + z-index: 3 +} + +.spage-number button.active:hover { + background: #2d98e6; + color: #fff; + border-color: #2d98e6; + z-index: 3 +} + +.spage-number button:hover { + background-color: #eee +} + +.spage-number button.button-disabled { + cursor: not-allowed; + color: #ccc +} + +.spage-number .spage-after, +.spage-before { + padding: 0; + width: 40px +} + +.spage-skip { + display: inline-block; + margin-left: 5px; + line-height: 27px; + color: #666; + font-size: 14px +} + +.spage-skip input { + box-sizing: border-box; + display: inline-block; + width: 45px; + height: 29px; + text-align: center; + vertical-align: top; + border: 1px solid #ddd; + background: 0 0; + outline: none; + transition: all .2s +} + +.spage-skip input:focus { + border-color: #2d98e6 +} + +.spage-skip button { + display: inline-block; + padding: 0 14px; + line-height: 27px; + vertical-align: top; + color: #333; + border: 1px solid #ddd; + cursor: pointer; + transition: all .2s; + outline: none; + background: 0 0; + user-select: none; + background-color: #fff; +} + +.spage-skip button:hover { + background: #2d98e6; + color: #fff; + border: 1px solid #2d98e6 +} + + diff --git a/src/plugins/js/jquery.sPage.min.js b/src/plugins/js/jquery.sPage.min.js new file mode 100644 index 0000000..fffd2e9 --- /dev/null +++ b/src/plugins/js/jquery.sPage.min.js @@ -0,0 +1,202 @@ +/* jQuery分页插件sPage version:1.2.2 github:https://github.com/jvbei/sPage */ +(function (p, t, e, a) { + "use strict"; + var s = { + page: 1, + pageSize: 200, + total: 0, + showTotal: false, + totalTxt: "共{total}条", + noData: false, + showSkip: false, + showPN: true, + prevPage: "上一页", + nextPage: "下一页", + fastForward: 0, + selectOption: [], + backFun: function (t) {} + }; + var img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAUlEQVQ4T5WTsUrEQBCG//FYxC7BlxDfZ9t0O8EivY0YBEGbqwTJbBauUA8tfIqzsBH18BXyDKkSiUQIRza32XJ2/2+/2WUIIytJkmOl1Ilz7m1sf1gj3wFmPgOwFZHNFMQL6ELMfA5gMwWZBHQQY8wtEb2KyPuYyV5AD1kS0fMYJAgAgIwxd0TkROQj6BF3dfM8P6iq6h5AMYSEGvzxtNaLOI5d0zTLsiy/u9osADMrACsANyKynQXowm3bPgG4ttZ+/rcYZOALBxlkWXZY1/XD7s1BBn34BcDlUDvoG/vwGsCVL+xtQWt9FEXRI4ALa+3P7GFK0/QUgCqK4mvfOP8CEjZjEfl6lvkAAAAASUVORK5CYII=' + function i(t, e) { + this.element = p(t); + this.settings = p.extend({}, s, e); + this.pageNum = 1, this.pageList = [], this.pageTatol = 0; + this.init() + } + p.extend(i.prototype, { + init: function () { + this.element.empty(); + this.viewHtml() + this.clickBtn() + }, + creatHtml: function (t) { + t == this.settings.page ? this.pageList.push('') : this.pageList.push('') + } + if (e <= 6) { + for (var s = 1; s < e + 1; s++) { + this.creatHtml(s) + } + } else { + if (t.page < 3) { + for (var s = 1; s <= 3; s++) { + this.creatHtml(s) + } + this.pageList.push(''); + for (var s = e - 3; s <= e; s++) { + this.creatHtml(s) + } + } else { + this.pageList.push(''); + if (t.page > 3) { this.pageList.push('') } + for (var s = t.page - 1; s <= Number(t.page) + 1; s++) { + this.creatHtml(s) + } + if (t.page <= e - 3) { this.pageList.push('') } + this.pageList.push('') : this.pageList.push('') + } + + + + a.push(this.pageList.join("")); + a.push(""); + + + if (t.selectOption.length > 0) { + var str = '' + a.push(str); + } + if (t.showSkip) { + a.push('
跳至  页  
') + } + + this.element.html(a.join("")); + + + + }, + clickBtn: function () { + var a = this; + var s = this.settings; + var i = this.element; + var n = this.pageTatol; + this.element.on('change', 'select', function (e) { + var value = parseInt(document.getElementById('selectNum').value) + s.pageSize = value + s.page = 1 + a.element.empty(); + a.viewHtml() + s.backFun(s) + }) + this.element.off("click", "button"); + this.element.on("click", "button", function () { + var t = p(this).data("page"); + switch (t) { + case "prev": + s.page = s.page - 1 >= 1 ? s.page - 1 : 1; + t = s.page; + break; + case "next": + s.page = Number(s.page) + 1 <= n ? Number(s.page) + 1 : n; + t = s.page; + break; + case "before": + s.page = s.page - s.fastForward >= 1 ? s.page - s.fastForward : 1; + t = s.page; + break; + case "after": + s.page = Number(s.page) + Number(s.fastForward) <= n ? Number(s.page) + Number(s.fastForward) : n; + t = s.page; + break; + case "go": + var e = parseInt(i.find("input").val()); + if (/^[0-9]*$/.test(e) && e >= 1 && e <= n) { + s.page = e; + t = e + } else { + return + } + break; + default: + s.page = t + } + if (t == a.pageNum) { + return + } + a.pageNum = s.page; + a.viewHtml(); + s.backFun(s) + }); + this.element.off("keyup", "input"); + this.element.on("keyup", "input", function (t) { + if (t.keyCode == 13) { + var e = parseInt(i.find("input").val()); + if (/^[0-9]*$/.test(e) && e >= 1 && e <= n && e != a.pageNum) { + s.page = e; + a.pageNum = e; + a.viewHtml(); + s.backFun(s) + } else { + return + } + } + }); + if (s.fastForward > 0) { + i.find(".spage-after").hover(function () { + p(this).html("»") + }, function () { + p(this).html("...") + }); + i.find(".spage-before").hover(function () { + p(this).html("«") + }, function () { + p(this).html("...") + }) + } + } + }); + p.fn.sPage = function (t) { + return this.each(function () { + new i(this, t) + }) + } +})(jQuery, window, document); \ No newline at end of file