├── .gitignore ├── README.md ├── luckysheet_obj ├── Luckysheet-master │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README-zh.md │ ├── README.md │ ├── commitlint.config.js │ ├── deploy.bat │ ├── gulpfile.js │ ├── package.json │ ├── src │ │ ├── assets │ │ │ └── iconfont │ │ │ │ ├── Anton-Regular.ttf │ │ │ │ ├── HanaleiFill-Regular.ttf │ │ │ │ ├── Pacifico-Regular.ttf │ │ │ │ ├── demo.css │ │ │ │ ├── demo_index.html │ │ │ │ ├── iconfont.css │ │ │ │ ├── iconfont.eot │ │ │ │ ├── iconfont.js │ │ │ │ ├── iconfont.json │ │ │ │ ├── iconfont.svg │ │ │ │ ├── iconfont.ttf │ │ │ │ ├── iconfont.woff │ │ │ │ └── iconfont.woff2 │ │ ├── config.js │ │ ├── controllers │ │ │ ├── alternateformat.js │ │ │ ├── cellDatePickerCtrl.js │ │ │ ├── cellFormat.js │ │ │ ├── conditionformat.js │ │ │ ├── constant.js │ │ │ ├── controlHistory.js │ │ │ ├── dataVerificationCtrl.js │ │ │ ├── dropCell.js │ │ │ ├── expendPlugins.js │ │ │ ├── filter.js │ │ │ ├── formulaBar.js │ │ │ ├── freezen.js │ │ │ ├── handler.js │ │ │ ├── hyperlinkCtrl.js │ │ │ ├── ifFormulaGenerator.js │ │ │ ├── imageCtrl.js │ │ │ ├── imageUpdateCtrl.js │ │ │ ├── inlineString.js │ │ │ ├── insertFormula.js │ │ │ ├── keyboard.js │ │ │ ├── listener.js │ │ │ ├── locationCell.js │ │ │ ├── luckysheetConfigsetting.js │ │ │ ├── matrixOperation.js │ │ │ ├── menuButton.js │ │ │ ├── mobile.js │ │ │ ├── moreFormat.js │ │ │ ├── orderBy.js │ │ │ ├── pivotTable.js │ │ │ ├── postil.js │ │ │ ├── print.js │ │ │ ├── protection.js │ │ │ ├── resize.js │ │ │ ├── rowColumnOperation.js │ │ │ ├── searchReplace.js │ │ │ ├── select.js │ │ │ ├── selection.js │ │ │ ├── server.js │ │ │ ├── sheetBar.js │ │ │ ├── sheetMove.js │ │ │ ├── sheetSearch.js │ │ │ ├── sheetmanage.js │ │ │ ├── sparkline.js │ │ │ ├── splitColumn.js │ │ │ ├── updateCell.js │ │ │ └── zoom.js │ │ ├── core.js │ │ ├── css │ │ │ ├── EwaAntH.gif │ │ │ ├── EwaAntV.gif │ │ │ ├── arrow-down.png │ │ │ ├── iconCustom.css │ │ │ ├── loading.gif │ │ │ ├── luckysheet-cellFormat.css │ │ │ ├── luckysheet-core.css │ │ │ ├── luckysheet-print.css │ │ │ ├── luckysheet-protection.css │ │ │ ├── luckysheet-zoom.css │ │ │ ├── menuSprite.svg │ │ │ ├── paint_16px.ico │ │ │ ├── paint_24px.ico │ │ │ ├── paint_32px.ico │ │ │ ├── sprite38.svg │ │ │ └── waffle_sprite.png │ │ ├── data │ │ │ └── chartJson.js │ │ ├── demoData │ │ │ ├── demoFeature.js │ │ │ ├── sheetCell.js │ │ │ ├── sheetChart.js │ │ │ ├── sheetComment.js │ │ │ ├── sheetConditionFormat.js │ │ │ ├── sheetDataVerification.js │ │ │ ├── sheetFormula.js │ │ │ ├── sheetPicture.js │ │ │ ├── sheetPivotTable.js │ │ │ ├── sheetPivotTableData.js │ │ │ ├── sheetSparkline.js │ │ │ └── sheetTable.js │ │ ├── expendPlugins │ │ │ ├── chart │ │ │ │ ├── chartmix.css │ │ │ │ ├── chartmix.umd.min.js │ │ │ │ └── plugin.js │ │ │ └── print │ │ │ │ └── plugin.js │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ ├── function │ │ │ ├── func.js │ │ │ ├── functionImplementation.js │ │ │ ├── functionlist.js │ │ │ ├── luckysheet_function.js │ │ │ └── matrix_methods.js │ │ ├── global │ │ │ ├── analysis.js │ │ │ ├── api.js │ │ │ ├── array.js │ │ │ ├── border.js │ │ │ ├── browser.js │ │ │ ├── cleargridelement.js │ │ │ ├── count.js │ │ │ ├── createdom.js │ │ │ ├── createsheet.js │ │ │ ├── cursorPos.js │ │ │ ├── datecontroll.js │ │ │ ├── draw.js │ │ │ ├── dynamicArray.js │ │ │ ├── editor.js │ │ │ ├── extend.js │ │ │ ├── format.js │ │ │ ├── formula.js │ │ │ ├── func_methods.js │ │ │ ├── getRowlen.js │ │ │ ├── getdata.js │ │ │ ├── json.js │ │ │ ├── loading.js │ │ │ ├── location.js │ │ │ ├── method.js │ │ │ ├── refresh.js │ │ │ ├── rhchInit.js │ │ │ ├── scroll.js │ │ │ ├── setdata.js │ │ │ ├── sort.js │ │ │ ├── tooltip.js │ │ │ └── validate.js │ │ ├── index.html │ │ ├── index.js │ │ ├── locale │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── locale.js │ │ │ ├── zh.js │ │ │ └── zh_tw.js │ │ ├── methods │ │ │ ├── get.js │ │ │ └── set.js │ │ ├── plugins │ │ │ ├── css │ │ │ │ ├── font_934335_2exjneyzm5y.css │ │ │ │ └── spectrum.min.css │ │ │ ├── font-awesome.min.css │ │ │ ├── images │ │ │ │ ├── CFcolorGradation.png │ │ │ │ ├── CFdataBar.png │ │ │ │ ├── CFicons.png │ │ │ │ ├── icon_dropCell.png │ │ │ │ ├── js.png │ │ │ │ ├── ui-icons_444444_256x240.png │ │ │ │ ├── ui-icons_555555_256x240.png │ │ │ │ ├── ui-icons_777620_256x240.png │ │ │ │ ├── ui-icons_777777_256x240.png │ │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ ├── jquery-ui.min.css │ │ │ ├── jquery-ui.theme.min.css │ │ │ ├── jquery.sPage.css │ │ │ └── js │ │ │ │ ├── clipboard.min.js │ │ │ │ ├── crypto-api.min.js │ │ │ │ ├── html2canvas.min.js │ │ │ │ ├── jquery-ui.min.js │ │ │ │ ├── jquery.mousewheel.min.js │ │ │ │ ├── jquery.sPage.min.js │ │ │ │ ├── jstat.min.js │ │ │ │ ├── localforage.min.js │ │ │ │ ├── lodash.min.js │ │ │ │ └── spectrum.min.js │ │ ├── store │ │ │ └── index.js │ │ └── utils │ │ │ ├── chartUtil.js │ │ │ ├── math.js │ │ │ ├── polyfill.js │ │ │ └── util.js │ └── yarn.lock ├── apps │ ├── __init__.py │ └── lucky_sheet │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── init_sheet.py │ │ ├── java-utils.jar │ │ ├── jvm_tool.py │ │ ├── log.py │ │ ├── luckysheet_update.py │ │ ├── migrations │ │ └── __init__.py │ │ ├── models.py │ │ ├── static │ │ └── dist │ │ │ ├── assets │ │ │ └── iconfont │ │ │ │ ├── Anton-Regular.ttf │ │ │ │ ├── HanaleiFill-Regular.ttf │ │ │ │ ├── Pacifico-Regular.ttf │ │ │ │ ├── demo.css │ │ │ │ ├── demo_index.html │ │ │ │ ├── iconfont.css │ │ │ │ ├── iconfont.eot │ │ │ │ ├── iconfont.js │ │ │ │ ├── iconfont.json │ │ │ │ ├── iconfont.svg │ │ │ │ ├── iconfont.ttf │ │ │ │ ├── iconfont.woff │ │ │ │ └── iconfont.woff2 │ │ │ ├── css │ │ │ ├── EwaAntH.gif │ │ │ ├── EwaAntV.gif │ │ │ ├── arrow-down.png │ │ │ ├── loading.gif │ │ │ ├── luckysheet.css │ │ │ ├── menuSprite.svg │ │ │ ├── paint_16px.ico │ │ │ ├── paint_24px.ico │ │ │ ├── paint_32px.ico │ │ │ ├── sprite38.svg │ │ │ └── waffle_sprite.png │ │ │ ├── demoData │ │ │ ├── demoFeature.js │ │ │ ├── sheetCell.js │ │ │ ├── sheetChart.js │ │ │ ├── sheetComment.js │ │ │ ├── sheetConditionFormat.js │ │ │ ├── sheetDataVerification.js │ │ │ ├── sheetFormula.js │ │ │ ├── sheetPicture.js │ │ │ ├── sheetPivotTable.js │ │ │ ├── sheetPivotTableData.js │ │ │ ├── sheetSparkline.js │ │ │ └── sheetTable.js │ │ │ ├── expendPlugins │ │ │ └── chart │ │ │ │ ├── chartmix.css │ │ │ │ └── chartmix.umd.min.js │ │ │ ├── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ │ │ ├── index.html │ │ │ ├── luckysheet.esm.js │ │ │ ├── luckysheet.esm.js.map │ │ │ ├── luckysheet.umd.js │ │ │ ├── luckysheet.umd.js.map │ │ │ └── plugins │ │ │ ├── css │ │ │ └── pluginsCss.css │ │ │ ├── images │ │ │ ├── CFcolorGradation.png │ │ │ ├── CFdataBar.png │ │ │ ├── CFicons.png │ │ │ ├── icon_dropCell.png │ │ │ ├── js.png │ │ │ ├── ui-icons_444444_256x240.png │ │ │ ├── ui-icons_555555_256x240.png │ │ │ ├── ui-icons_777620_256x240.png │ │ │ ├── ui-icons_777777_256x240.png │ │ │ ├── ui-icons_cc0000_256x240.png │ │ │ └── ui-icons_ffffff_256x240.png │ │ │ ├── js │ │ │ └── plugin.js │ │ │ └── plugins.css │ │ ├── static_bk │ │ ├── css │ │ │ ├── iconfont.css │ │ │ ├── luckysheet.css │ │ │ ├── plugins.css │ │ │ └── pluginsCss.css │ │ └── js │ │ │ ├── demoFeature.js │ │ │ ├── ecsheet-main.zip │ │ │ ├── luckysheet.umd.js │ │ │ └── plugin.js │ │ ├── templates │ │ ├── index.html │ │ ├── luckysheet.html │ │ └── luckysheet_bk.html │ │ ├── tests.py │ │ ├── tools │ │ └── db.py │ │ ├── urls.py │ │ ├── views.py │ │ └── websocket_server.py ├── db.sqlite3 ├── luckysheet_obj │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── newip.sh └── static │ └── css │ ├── EwaAntH.gif │ ├── EwaAntV.gif │ ├── arrow-down.png │ ├── loading.gif │ ├── luckysheet.css │ ├── menuSprite.svg │ ├── paint_16px.ico │ ├── paint_24px.ico │ ├── paint_32px.ico │ ├── sprite38.svg │ └── waffle_sprite.png ├── readmeImages ├── config自定义图片配置.png ├── core自定义图片配置.png ├── 微信截图_20210302010044.png ├── 微信截图_20210302010418.png └── 自定义图片发送方式.png ├── requirements.txt └── sheet_data_demo.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.idea 3 | pako-master 4 | ecsheet-main 5 | docs 6 | .vs 7 | .github 8 | /luckysheet_obj/Luckysheet-master/docs/ 9 | /luckysheet_obj/Luckysheet-master/.github/ 10 | /luckysheet_obj/Luckysheet-master/.vs/ 11 | dump.rdb 12 | srartRedis.bat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # luckysheet_django 2 | luckysheet + django实现多人在线协同操作excel 3 | 4 | [演示地址](http://49.234.35.155:8080/luckysheetindex/) http://49.234.35.155:8080/luckysheetindex/ 5 | 6 | QQ交流群: 697107880 7 | 8 | ## 一、安装 9 | ### 1. 安装必要依赖 10 | 1. 安装python3.7。(版本不可过高,python3.10中会有bug:[AttributeError: module 'collections' has no attribute 'MutableMapping'](https://blog.csdn.net/lishuaigell/article/details/125221750)) 11 | 2. 安装jdk。建议jdk8,因为我使用的就是该版本,因为当前py3的解压有bug (https://bugs.python.org/issue24301) 12 | 3. pip install django==2.2.8 (版本不可过高,django3.0废弃了本项目中使用的dwebsocket。否则会遇到报错:TypeError: WebSocketMiddleware() takes no arguments) 13 | 4. pip安装requirements.txt中的包。 14 | 5. pip install django_redis 15 | 6. 本地安装redis服务器。 16 | 7. 先安装node.js,之后进入项目目录安装。 17 | ``` 18 | cd luckysheet_django/luckysheet_obj/Luckysheet-master 19 | npm install 20 | npm install gulp -g 21 | //开发 22 | npm run dev 23 | //打包 24 | npm run build 25 | ``` 26 | 27 | ### 2. 启动 28 | 1. [改IP] 进入到luckysheet_django/luckysheet_obj目录,执行./new.ip [IP],更改当前ip设置。注意,第一次使用new.ip后,要手动将luckysheet_django/luckysheet_obj/luckysheet_obj/settings.py中的ALLOWED_HOSTS中的第一个逗号删除;之后就不需要了。 29 | ``` 30 | cd luckysheet_django/luckysheet_obj/ 31 | ./new.ip xxx.xxx.xxx.xxx 32 | vim ./luckysheet_obj/settings.py #去除ALLOWED_HOSTS中第一个逗号。 33 | ``` 34 | 2. [启动后端] 35 | ``` 36 | cd luckysheet_django/luckysheet_obj/ 37 | python manage.py runserver xxx.xxx.xxx.xxx:8080 38 | ``` 39 | 3. [启动前端] 会在3000端口打开前端服务器。 40 | ``` 41 | cd luckysheet_django/luckysheet_obj/Luckysheet-master 42 | npm run dev 43 | ``` 44 | 4. [启动Redis] 45 | ``` 46 | redis-server [指定config文件位置] 47 | ``` 48 | 5. [启动Redis-cli]:可选,便于查看 49 | ``` 50 | redis-cli -h 127.0.0.1 -p 6379 51 | ``` 52 | 53 | 54 | ### 3. 目录介绍 55 | 1. luckysheet_django/luckysheet_obj/:django项目位置。 56 | 2. luckysheet_django/luckysheet_obj/Luckysheet-master:前端Luckysheet的目录,浏览器读取luckysheet的js等内容位置。 57 | 3. luckysheet_django/luckysheet_obj/luckysheet_obj/:该django项目的urls、settings等django相关内容。 58 | 4. luckysheet_django/luckysheet_obj/apps/lucky_sheet/:该django项目主app实现,实际后端的内容。 59 | 5. luckysheet_django/luckysheet_obj/apps/lucky_sheet/tools/:里面为后端抽象提供redis接口的实现。 60 | 6. luckysheet_django/luckysheet_obj/apps/lucky_sheet/templates/:django后端,给前端提供的页面。 61 | 62 | 63 | 64 | ## 二、开发细节 65 | ### 1. 解决大图片无法通过wss传输的方法: 66 | ``` 67 | 源码 https://github.com/mengshukeji/Luckysheet 68 | 解决方案: 69 | 1.首先config里面添加自定义图片的发送配置 70 | 2.把该配置添加到core.js里面 71 | 3.添加一个自定义js文件,把发送图片函数写进去 72 | 4.server.js里面修改原来的wss发送配置 73 | ``` 74 | 详细修改如下: 75 | ######1、 config里面添加自定义图片的发送配置, [点击查看config.js](./luckysheet_obj/Luckysheet-master/src/core.js) 76 | ```angular2html 77 | bigImageUpdateMethod:{"method":"POST", "url":"http://127.0.0.1:8000/luckysheetupdateurl"}, //自定义前端大图片大发送方式 78 | ``` 79 | ![config配置](./readmeImages/config自定义图片配置.png) 80 | ######2、 把该配置添加到core.js里面, [点击查看core.js](./luckysheet_obj/Luckysheet-master/src/core.js) 81 | ```angular2html 82 | luckysheetConfigsetting.bigImageSendMethod = extendsetting.bigImageUpdateMethod; 83 | ``` 84 | ![core自定义图片配置](./readmeImages/core自定义图片配置.png) 85 | ######3、 src/controllers/里面添加一个自定义js文件,把发送图片函数写进去 86 | 代码块较多,详细请查看 [src/controllers/imageUpdateCtrl.js](luckysheet_obj/Luckysheet-master/src/controllers/imageUpdateCtrl.js) 87 | 88 | ![自定义图片发送方式](./readmeImages/自定义图片发送方式.png) 89 | 90 | ######4、 src/controllers/server.js 里面修改原来的wss发送配置 91 | 4.1 顶部导入所需变量、函数 92 | ``` 93 | import luckysheetConfigsetting from './luckysheetConfigsetting'; 94 | import {customBigImageUpdate} from './bigImageUpdate' 95 | ``` 96 | 4.2 修改wss发送方式,代码较多,详细参考 [src/controllers/server.js](./luckysheet_obj/Luckysheet-master/src/controllers/server.js) 97 | 98 | ![自定义图片发送方式](./readmeImages/微信截图_20210302010044.png) 99 | ![自定义图片发送方式](./readmeImages/微信截图_20210302010418.png) 100 | 101 | ### 2. 初始化加载excel的效果图加载失败 102 | 1、 src\controllers\constant.js 里面将加载图片的路径改为 image://static/css/loading.gif 103 | 104 | ### 后台数据是如何保存的 105 | ```angular2html 106 | 1、 通过新页面上传,通过toJson的aip获取到数据,发送给后台,后台一边保存mysql一边放至redis 107 | 2、 如果是新进来的excel则全部放到redis里面,如果是已经有的,则更新已有的值 108 | 3、 定时从redis里面把每一个excel记录固化到mysql数据库中 109 | 4、 重新进入excel编辑的时候,通过gridekey从redis/mysql 获取最新的excel内容 110 | 键值更新方法:先获取sheet索引,然后再获取到具体的一个小格子位置,如果有则更新,没有则新增 111 | ``` 112 | 113 | ### 3. 当前问题 114 | 1、新建一个sheet页的时候,如果别的客户端不点击这个新页面一下电话,那新建一方在新sheet页面的修改就不会被同步到其他客户端。因此别的客户端必须点击 115 | 一下新的sheet页,才能把新sheet页的修改同步过来。--2021/02/01 116 | 117 | 2、筛选功能,当前只能把添加筛选功能同步到其他客户端,无法把去除筛选功能同步到其他客户端。--2021/02/01 118 | 119 | 3、当前由于py3的gzip的bug冲突,所以暂时解压数据得使用java包了,[gzip的bug](https://bugs.python.org/issue24301) --2021/02/01 120 | 121 | ### 4. 已解决问题 122 | 1、多人协同的时候,无法做到同步,卡在了返回值的这一步,返回格式未能对齐,单双引号导致的 --2021/02/01-问题已解决 -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | dist 5 | docs/.vuepress/dist 6 | ./docs 7 | ./.vs 8 | ./.github -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020-present, Mengshukeji 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'] 3 | } 4 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/deploy.bat: -------------------------------------------------------------------------------- 1 | # deploy Demo 2 | npm run build 3 | cd dist 4 | git init 5 | git remote add origin https://github.com/mengshukeji/LuckysheetDemo.git 6 | git config --local user.email "1414556676@qq.com" 7 | git config --local user.name "Dushusir" 8 | git add . 9 | git commit -m 'deploy Luckysheet demo' 10 | git push -f origin master:gh-pages 11 | 12 | # =============================================== 13 | 14 | # deploy Docs 15 | npm run docs:build 16 | cd docs/.vuepress/dist 17 | git init 18 | git remote add origin https://github.com/mengshukeji/LuckysheetDocs.git 19 | git add . 20 | git commit -m 'deploy Luckysheet docs' 21 | git push -f origin master:gh-pages 22 | 23 | # =============================================== 24 | 25 | # add a tags 26 | git tag -a doc -m "doc" 27 | 28 | 29 | # replease 30 | npm run build 31 | npm run release -- --release-as patch 32 | git push --follow-tags origin master 33 | npm publish 34 | 35 | # only publish 36 | npm run build 37 | git add . 38 | npm run commit 39 | npm version patch 40 | git push -u origin master 41 | npm publish 42 | 43 | 44 | # ============================================== 45 | 46 | # test feature branch 47 | git checkout -b fea origin/feature 48 | git pull 49 | 50 | ## After some test, create PR merge feature to master branch 51 | 52 | git checkout master 53 | git branch -d fea 54 | 55 | # =============================================== 56 | 57 | # test pull request: https://docs.github.com/cn/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally 58 | 59 | # 139 is ID, dev is branch name 60 | git fetch origin pull/139/head:test-139 61 | git checkout test-139 62 | # test code 63 | git push origin test-139 64 | # create new PR ,merge test-139 to master 65 | 66 | # list all remote and local branchs 67 | git branch -a 68 | # delete remote branch 69 | git push origin --delete dev 70 | git checkout master 71 | # delete local branch 72 | git branch -d dev 73 | 74 | # pr 75 | ## 1. fork 到自己的仓库 76 | 77 | ## 2. git clone 到本地 78 | 79 | ## 3. 上游建立连接 80 | git remote add upstream https://github.com/mengshukeji/Luckysheet.git 81 | 82 | ## 4. 创建开发分支 83 | git checkout -b dev 84 | 85 | ## 5. 修改提交代码 86 | git add . 87 | git commit -m "add" 88 | git push origin dev 89 | 90 | ## 6. 同步代码,将最新代码同步到本地 91 | git fetch upstream 92 | git rebase upstream/master 93 | 94 | ## 7. 如果有冲突(没有可以略过) 95 | git status # 查看冲突文件,并修改冲突 96 | git add . 97 | git rebase --continue 98 | 99 | ## 8.提交分支代码 100 | git push origin dev 101 | 102 | ## 7. 提交pr 103 | 去自己github仓库对应fork的项目下new pull request -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "luckysheet", 3 | "version": "2.1.13", 4 | "main": "dist/luckysheet.cjs.js", 5 | "module": "dist/luckysheet.esm.js", 6 | "browser": "dist/luckysheet.umd.js", 7 | "devDependencies": { 8 | "@babel/core": "^7.12.3", 9 | "@babel/preset-env": "^7.12.1", 10 | "@babel/runtime-corejs3": "^7.12.1", 11 | "@commitlint/cli": "^9.1.1", 12 | "@commitlint/config-conventional": "^9.1.1", 13 | "@rollup/plugin-babel": "^5.2.1", 14 | "@rollup/plugin-commonjs": "^13.0.0", 15 | "@rollup/plugin-node-resolve": "^8.0.1", 16 | "browser-sync": "^2.26.7", 17 | "commitizen": "^4.1.2", 18 | "cross-env": "^7.0.2", 19 | "delete": "^1.1.0", 20 | "gulp": "^4.0.2", 21 | "gulp-babel": "^8.0.0", 22 | "gulp-clean-css": "^4.3.0", 23 | "gulp-concat": "^2.6.1", 24 | "gulp-if": "^3.0.0", 25 | "gulp-uglify": "^3.0.2", 26 | "gulp-useref": "^4.0.1", 27 | "http-proxy-middleware": "^1.0.6", 28 | "rollup": "^2.32.1", 29 | "rollup-plugin-terser": "^6.1.0", 30 | "standard-version": "^8.0.2", 31 | "uuid": "^8.3.2", 32 | "vuepress": "^1.5.0", 33 | "vuepress-plugin-baidu-autopush": "^1.0.1", 34 | "vuepress-plugin-code-copy": "^1.0.6", 35 | "vuepress-plugin-seo": "^0.1.4", 36 | "vuepress-plugin-sitemap": "^2.3.1" 37 | }, 38 | "dependencies": { 39 | "@babel/runtime": "^7.12.1", 40 | "dayjs": "^1.9.6", 41 | "flatpickr": "^4.6.6", 42 | "jquery": "^2.2.4", 43 | "numeral": "^2.0.6", 44 | "pako": "^1.0.11" 45 | }, 46 | "scripts": { 47 | "build": "cross-env NODE_ENV=production gulp build", 48 | "dev": "cross-env NODE_ENV=development gulp dev", 49 | "docs:dev": "vuepress dev docs", 50 | "docs:build": "vuepress build docs", 51 | "commit": "git-cz", 52 | "release": "standard-version" 53 | }, 54 | "files": [ 55 | "dist" 56 | ], 57 | "config": { 58 | "commitizen": { 59 | "path": "./node_modules/cz-conventional-changelog" 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/Anton-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/Anton-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/HanaleiFill-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/HanaleiFill-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/Pacifico-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/Pacifico-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.eot -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.woff -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/assets/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The default luckysheet config object. 3 | */ 4 | export default { 5 | container: "luckysheet", //容器的ID 6 | loading:{}, //自定义loading 7 | column: 60, //空表格默认的列数量 8 | row: 84, //空表格默认的行数据量 9 | allowCopy: true, //是否允许拷贝 10 | showtoolbar: true, //是否第二列显示工具栏 11 | showinfobar: true, //是否显示顶部名称栏 12 | showsheetbar: true, //是否显示底部表格名称区域 13 | showstatisticBar: true, //是否显示底部计数栏 14 | pointEdit: false, //是否是编辑器插入表格模式 15 | pointEditUpdate: null, //编辑器表格更新函数 16 | pointEditZoom: 1, //编辑器表格编辑时缩放比例 17 | // menu: "undo|redo|freezenrow|freezencolumn|download|share|chart|pivot", 18 | data: [{ "name": "Sheet1", color: "", "status": "1", "order": "0", "data": [], "config": {}, "index":0 }, { "name": "Sheet2", color: "", "status": "0", "order": "1", "data": [], "config": {}, "index":1 }, { "name": "Sheet3", color: "", "status": "0", "order": "2", "data": [], "config": {}, "index":2 }], //客户端sheet数据[shee1, sheet2, sheet3] 19 | title: "Luckysheet Demo", //表格的名称 20 | userInfo:false,// 右上角的用户信息展示样式,支持 1. boolean类型:false:不展示,ture:展示默认 ' rabbit' ,2. HTML模板字符串或者普通字符串,如:' Lucky'或者'用户名', 3. 对象格式,设置 userImage:用户头像地址 和 userName:用户名 4. 不设置或者设置undefined同设置false 21 | userMenuItem: [{url:"www.baidu.com", "icon":'', "name":"我的表格"}, {url:"www.baidu.com", "icon":'', "name":"退出登陆"}], //点击右上角的用户信息弹出的菜单 22 | myFolderUrl: "www.baidu.com", //左上角<返回按钮的链接 23 | config: {}, //表格行高、列宽、合并单元格、公式等设置 24 | fullscreenmode: true, //是否全屏模式,非全屏模式下,标记框不会强制选中。 25 | devicePixelRatio: window.devicePixelRatio, //设备比例,比例越大表格分标率越高 26 | allowEdit: true, //是否允许前台编辑 27 | loadUrl: "", // 配置loadUrl的地址,luckysheet会通过ajax请求表格数据,默认载入status为1的sheet数据中的所有data,其余的sheet载入除data字段外的所有字段 28 | loadSheetUrl: "", //配置loadSheetUrl的地址,参数为gridKey(表格主键) 和 index(sheet主键合集,格式为[1,2,3]),返回的数据为sheet的data字段数据集合 29 | gridKey: "", // 表格唯一标识符 30 | updateUrl: "", //表格数据的更新地址 31 | updateImageUrl: "", //缩略图的更新地址 32 | allowUpdate: false, //是否允许编辑后的后台更新 33 | functionButton: "", //右上角功能按钮,例如' ' 34 | showConfigWindowResize: true, //图表和数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进 35 | enableAddRow: true,//允许添加行 36 | enableAddBackTop: true,//允许回到顶部 37 | // enablePage: false,//允许加载下一页 38 | autoFormatw: false, //自动格式化超过4位数的数字为 亿万格式 例:true or "true" or "TRUE" 39 | accuracy: undefined, //设置传输来的数值的精确位数,小数点后n位 传参数为数字或数字字符串,例: "0" 或 0 40 | pageInfo:{ 41 | 'queryExps':'', 42 | 'reportId':'', 43 | 'fields':'', 44 | 'mobile':'', 45 | 'frezon':'', 46 | 'currentPage':'', 47 | "totalPage":10, 48 | "pageUrl":"", 49 | }, 50 | editMode: false, //是否为编辑模式 51 | beforeCreateDom: null,//表格创建之前的方法 52 | fireMousedown: null, //单元格数据下钻 53 | lang: 'zh', //language 54 | plugins: [], //plugins, e.g. ['chart'] 55 | forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用 56 | rowHeaderWidth: 46, 57 | columnHeaderHeight: 20, 58 | defaultColWidth:73, 59 | defaultRowHeight:19, 60 | defaultFontSize:10, 61 | limitSheetNameLength:true, //是否限制工作表名的长度 62 | defaultSheetNameMaxLength:31, //默认工作表名称的最大长度 63 | sheetFormulaBar:true, //是否显示公式栏 64 | showtoolbarConfig:{}, //自定义工具栏 65 | showsheetbarConfig:{}, //自定义底部sheet页 66 | showstatisticBarConfig:{}, //自定义计数栏 67 | cellRightClickConfig:{}, //自定义单元格右键菜单 68 | sheetRightClickConfig:{}, //自定义底部sheet页右击菜单 69 | imageUpdateMethodConfig:{"method":"POST", "url":"http://127.0.0.1:8000/luckysheetupdateurl"}, //自定义图片同步方式 70 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/cellDatePickerCtrl.js: -------------------------------------------------------------------------------- 1 | import menuButton from './menuButton'; 2 | import formula from '../global/formula'; 3 | import Store from '../store'; 4 | import flatpickr from 'flatpickr' 5 | import dayjs from "dayjs"; 6 | import { update, datenum_local } from '../global/format'; 7 | import { setCellValue, setCellFormat } from '../global/api'; 8 | 9 | const fitFormat = (formatStr) => { 10 | let dateFormat = formatStr.replace(/y/g, 'Y'); 11 | dateFormat = dateFormat.replace(/d/g, 'D'); 12 | dateFormat = dateFormat.replace(/h/g, 'H'); 13 | 14 | dateFormat = dateFormat.replace(/上午\/下午/g, 'A'); 15 | dateFormat = dateFormat.replace(/上午/g, 'A'); 16 | dateFormat = dateFormat.replace(/下午/g, 'A'); 17 | 18 | dateFormat = dateFormat.replace(/AM\/PM/g, 'A'); 19 | dateFormat = dateFormat.replace(/AM/g, 'A'); 20 | dateFormat = dateFormat.replace(/PM/g, 'A'); 21 | dateFormat = dateFormat.replace(/\"/g, ''); 22 | 23 | if (dateFormat.includes('A')) { 24 | dateFormat = dateFormat.replace(/H/g, 'h'); 25 | } 26 | return dateFormat 27 | } 28 | 29 | const cellDatePickerCtrl = { 30 | cellFocus: function (r, c, cell) { 31 | let row = Store.visibledatarow[r], 32 | row_pre = r == 0 ? 0 : Store.visibledatarow[r - 1]; 33 | let col = Store.visibledatacolumn[c], 34 | col_pre = c == 0 ? 0 : Store.visibledatacolumn[c - 1]; 35 | 36 | let margeset = menuButton.mergeborer(Store.flowdata, r, c); 37 | let type = cell.ct.fa || 'YYYY-MM-DD'; 38 | let defaultDate = update('yyyy-MM-dd hh:mm:ss', cell.v); 39 | let dateFormat = fitFormat(type); 40 | let enableTime = false; 41 | let noCalendar = false; 42 | let enableSeconds = false; 43 | let time_24hr = true; 44 | let hasChineseTime = false; 45 | 46 | 47 | if (!!margeset) { 48 | row = margeset.row[1]; 49 | row_pre = margeset.row[0]; 50 | 51 | col = margeset.column[1]; 52 | col_pre = margeset.column[0]; 53 | } 54 | 55 | $(".cell-date-picker").show().css({ 56 | width: col - col_pre + 1, 57 | height: row - row_pre + 1, 58 | left: col_pre, 59 | top: row_pre 60 | }) 61 | 62 | if (/[上午下午]/.test(type)) { 63 | hasChineseTime = true 64 | } 65 | if (/[Hhms]/.test(dateFormat)) { 66 | enableTime = true; 67 | } 68 | if (!/[YMD]/.test(dateFormat)) { 69 | noCalendar = true; 70 | } 71 | if (/s/.test(dateFormat)) { 72 | enableSeconds = true; 73 | } 74 | if (/A/.test(dateFormat)) { 75 | time_24hr = false; 76 | } 77 | 78 | const fp = flatpickr('#luckysheet-input-box', { 79 | allowInput: false, 80 | noCalendar, 81 | enableSeconds, 82 | enableTime, 83 | dateFormat, 84 | time_24hr, 85 | defaultDate, 86 | onClose() { 87 | setTimeout(() => { 88 | fp.destroy() 89 | }, 0); 90 | }, 91 | parseDate: (datestr, format) => { 92 | return dayjs(datestr).toDate(); 93 | }, 94 | formatDate: (date, format, locale) => { 95 | if (hasChineseTime) { 96 | return dayjs(date).format(format).replace('AM', '上午').replace('PM', '下午') 97 | } 98 | return dayjs(date).format(format); 99 | }, 100 | onChange: function (selectedDates, dateStr) { 101 | let currentVal = datenum_local(new Date(selectedDates)) 102 | $("#luckysheet-rich-text-editor").html(dateStr); 103 | setCellValue(r, c, currentVal, { isRefresh: false }) 104 | setCellFormat(r, c, 'ct', cell.ct) 105 | if (!enableTime) { 106 | formula.updatecell(Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[1]); 107 | } 108 | } 109 | }); 110 | 111 | $("#luckysheet-input-box").click(); 112 | }, 113 | } 114 | 115 | export default cellDatePickerCtrl; 116 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/expendPlugins.js: -------------------------------------------------------------------------------- 1 | import { chart } from '../expendPlugins/chart/plugin' 2 | import { print } from '../expendPlugins/print/plugin' 3 | 4 | const pluginsObj = { 5 | 'chart':chart, 6 | 'print':print 7 | } 8 | 9 | const isDemo = true 10 | 11 | /** 12 | * Register plugins 13 | */ 14 | function initPlugins(plugins , data){ 15 | if(plugins.length){ 16 | plugins.forEach(plugin => { 17 | pluginsObj[plugin](data , isDemo) 18 | }); 19 | } 20 | } 21 | 22 | export { 23 | initPlugins 24 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/imageUpdateCtrl.js: -------------------------------------------------------------------------------- 1 | // 自定义图片的更新方法例如: customImageUpdate("POST", "http://127.0.0.1:8000/luckysheetimageprocess/", d) 2 | function customImageUpdate(method, url, obj) { 3 | return new Promise((resolve, reject) => { 4 | const xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP"); 5 | xhr.open(method, url); 6 | xhr.send(JSON.stringify(obj)); // 发送 POST/GET 数据 7 | xhr.onreadystatechange = function () { 8 | if (xhr.readyState == 4) { 9 | if (xhr.status == 200) { 10 | resolve(xhr.responseText); 11 | } else { 12 | reject("error"); 13 | } 14 | } 15 | }; 16 | }); 17 | } 18 | 19 | export { 20 | customImageUpdate 21 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/listener.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Monitor special variables 3 | */ 4 | import {createProxy} from '../utils/util'; 5 | import Store from '../store/index'; 6 | import method from '../global/method'; 7 | import { getluckysheetfile } from '../methods/get' 8 | import { toJson } from '../global/api'; 9 | 10 | const initListener = function(){ 11 | // createProxy(Store,['jfredo']); 12 | createProxy(Store, 'jfredo',(target, property, val, receiver)=>{ 13 | if (property !== 'length') { 14 | // 钩子函数 15 | method.createHookFunction('updated',val) 16 | } 17 | } ); 18 | 19 | createProxy(Store, 'asyncLoad', (target, property, val, receiver)=>{ 20 | if(property === 'length' && val === 0){ 21 | method.createHookFunction('workbookCreateAfter', toJson()) 22 | } 23 | }) 24 | } 25 | 26 | export { 27 | initListener 28 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/luckysheetConfigsetting.js: -------------------------------------------------------------------------------- 1 | const luckysheetConfigsetting = { 2 | autoFormatw: false, 3 | accuracy: undefined, 4 | total: 0, 5 | 6 | allowCopy: true, 7 | showtoolbar: true, 8 | showinfobar: true, 9 | showsheetbar: true, 10 | showstatisticBar: true, 11 | pointEdit: false, 12 | pointEditUpdate: null, 13 | pointEditZoom: 1, 14 | 15 | userInfo: false, 16 | userMenuItem: [], 17 | myFolderUrl: null, 18 | functionButton: null, 19 | 20 | showConfigWindowResize: true, 21 | enableAddRow: true, 22 | enableAddBackTop: true, 23 | enablePage: true, 24 | pageInfo: null, 25 | 26 | 27 | editMode: false, 28 | beforeCreateDom: null, 29 | workbookCreateBefore: null, 30 | workbookCreateAfter: null, 31 | fireMousedown: null, 32 | plugins:[], 33 | forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用 34 | 35 | defaultColWidth:73, 36 | defaultRowHeight:19, 37 | 38 | defaultTextColor: '#000', 39 | defaultCellColor: '#fff', 40 | } 41 | 42 | export default luckysheetConfigsetting; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/print.js: -------------------------------------------------------------------------------- 1 | import luckysheetConfigsetting from './luckysheetConfigsetting'; 2 | import {zoomChange} from './zoom'; 3 | import sheetmanage from './sheetmanage'; 4 | import server from './server'; 5 | import {rowLocationByIndex, colLocationByIndex,mouseposition,rowLocation,colLocation} from '../global/location'; 6 | import Store from '../store'; 7 | 8 | let ExcelPlaceholder = { 9 | "[tabName]":"&A", 10 | "[CurrentDate]":"&D", 11 | "[fileName]":"&F", 12 | "[background]":"&G", 13 | "[Shadow]":"&H", 14 | "[TotalPages]":"&N", 15 | "[pageNumber]":"&P", 16 | "[CurrentTime]":"&T", 17 | "[filePath]":"&Z", 18 | } 19 | 20 | // Get the pixel value per millimeter 21 | function getOneMmsPx (){ 22 | let div = document.createElement("div"); 23 | div.style.width = "1mm"; 24 | document.querySelector("body").appendChild(div); 25 | let mm1 = div.getBoundingClientRect(); 26 | let w = mm1.width; 27 | $(div).remove(); 28 | return mm1.width; 29 | } 30 | 31 | export function viewChange(curType, preType){ 32 | let currentSheet = sheetmanage.getSheetByIndex(); 33 | 34 | if(currentSheet.config==null){ 35 | currentSheet.config = {}; 36 | } 37 | 38 | if(currentSheet.config.sheetViewZoom==null){ 39 | currentSheet.config.sheetViewZoom = {}; 40 | } 41 | 42 | let defaultZoom = 1, type="zoomScaleNormal"; 43 | printLineAndNumberDelete(currentSheet); 44 | if(curType=="viewNormal"){ 45 | type = "viewNormalZoomScale"; 46 | } 47 | else if(curType=="viewLayout"){ 48 | type = "viewLayoutZoomScale"; 49 | } 50 | else if(curType=="viewPage"){ 51 | type = "viewPageZoomScale"; 52 | defaultZoom = 0.6; 53 | printLineAndNumberCreate(currentSheet); 54 | } 55 | 56 | 57 | 58 | let curZoom = currentSheet.config.sheetViewZoom[type]; 59 | if(curZoom==null){ 60 | curZoom = defaultZoom; 61 | } 62 | 63 | currentSheet.config.curentsheetView = curType; 64 | 65 | if (Store.clearjfundo) { 66 | Store.jfredo.push({ 67 | "type": "viewChange", 68 | "curType": curType, 69 | "preType": preType, 70 | "sheetIndex": Store.currentSheetIndex, 71 | }); 72 | } 73 | 74 | // Store.zoomRatio = curZoom; 75 | // server.saveParam("all", Store.currentSheetIndex, curZoom, { "k": "zoomRatio" }); 76 | server.saveParam("cg", Store.currentSheetIndex, curType, { "k": "curentsheetView" }); 77 | 78 | Store.currentSheetView = curType; 79 | 80 | zoomChange(curZoom); 81 | } 82 | 83 | 84 | function printLineAndNumberDelete(sheet){ 85 | 86 | } 87 | 88 | function printLineAndNumberCreate(sheet){ 89 | 90 | } 91 | 92 | function switchViewBtn($t){ 93 | let $viewList = $t.parent(), preType=$viewList.find("luckysheet-print-viewBtn-active").attr("type"); 94 | if($t.attr("type") == preType){ 95 | return; 96 | } 97 | 98 | let curType = $t.attr("type"); 99 | if(curType!=null){ 100 | viewChange(curType, preType); 101 | } 102 | else{ 103 | return; 104 | } 105 | 106 | $t.parent().find(".luckysheet-print-viewBtn").removeClass("luckysheet-print-viewBtn-active"); 107 | $t.addClass("luckysheet-print-viewBtn-active"); 108 | } 109 | 110 | export function printInitial(){ 111 | let container = luckysheetConfigsetting.container; 112 | let _this = this; 113 | $("#"+container).find(".luckysheet-print-viewBtn").click(function(){ 114 | switchViewBtn($(this)); 115 | }); 116 | 117 | } 118 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/sheetSearch.js: -------------------------------------------------------------------------------- 1 | function luckysheetbinary_search(arr, key) { 2 | let low = 0, high = arr.length - 1; 3 | 4 | while (low <= high) { 5 | let mid = parseInt((high + low) / 2); 6 | 7 | if (key < arr[mid] && (mid == 0 || key >= arr[mid - 1])) { 8 | return mid; 9 | } 10 | else if (key >= arr[mid]) { 11 | low = mid + 1; 12 | } 13 | else if (key < arr[mid]) { 14 | high = mid - 1; 15 | } 16 | else { 17 | return -1; 18 | } 19 | } 20 | } 21 | 22 | function luckysheetorder_search(arr, y) { 23 | let i = 0, 24 | row = 0, 25 | row_pre = 0, 26 | row_index = -1, 27 | i_ed = arr.length - 1; 28 | 29 | while (i < arr.length && i_ed >= 0 && i_ed >= i) { 30 | row = arr[i_ed]; 31 | 32 | if (i_ed == 0) { 33 | row_pre = 0; 34 | } 35 | else { 36 | row_pre = arr[i_ed - 1]; 37 | } 38 | 39 | if (y >= row_pre && y < row) { 40 | row_index = i_ed; 41 | break; 42 | } 43 | 44 | row = arr[i]; 45 | 46 | if (i == 0) { 47 | row_pre = 0; 48 | } 49 | else { 50 | row_pre = arr[i - 1]; 51 | } 52 | 53 | if (y >= row_pre && y < row) { 54 | row_index = i; 55 | break; 56 | } 57 | 58 | i++; 59 | i_ed--; 60 | } 61 | 62 | return row_index; 63 | } 64 | 65 | function luckysheet_searcharray(arr, y) { 66 | let index = arr.length - 1; 67 | 68 | if (arr.length < 40 || y <= arr[20] || y >= arr[index - 20]) { 69 | index = luckysheetorder_search(arr, y); 70 | } 71 | else { 72 | index = luckysheetbinary_search(arr, y); 73 | } 74 | 75 | return index; 76 | } 77 | 78 | export { 79 | luckysheet_searcharray, 80 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/controllers/zoom.js: -------------------------------------------------------------------------------- 1 | import Store from '../store'; 2 | import locale from '../locale/locale'; 3 | import { replaceHtml } from '../utils/util'; 4 | import sheetmanage from './sheetmanage'; 5 | import {changeSheetContainerSize} from './resize'; 6 | import { jfrefreshgrid_rhcw } from '../global/refresh'; 7 | import server from './server'; 8 | import luckysheetPostil from './postil'; 9 | import imageCtrl from './imageCtrl'; 10 | 11 | 12 | 13 | let luckysheetZoomTimeout = null; 14 | 15 | export function zoomChange(ratio){ 16 | if(Store.flowdata==null || Store.flowdata.length==0){ 17 | return; 18 | } 19 | 20 | clearTimeout(luckysheetZoomTimeout); 21 | luckysheetZoomTimeout = setTimeout(() => { 22 | if (Store.clearjfundo) { 23 | Store.jfredo.push({ 24 | "type": "zoomChange", 25 | "zoomRatio": Store.zoomRatio, 26 | "curZoomRatio": ratio, 27 | "sheetIndex": Store.currentSheetIndex, 28 | }); 29 | } 30 | 31 | Store.zoomRatio = ratio; 32 | 33 | let currentSheet = sheetmanage.getSheetByIndex(); 34 | 35 | //批注 36 | luckysheetPostil.buildAllPs(currentSheet.data); 37 | 38 | //图片 39 | imageCtrl.images = currentSheet.images; 40 | imageCtrl.allImagesShow(); 41 | imageCtrl.init(); 42 | 43 | if(currentSheet.config==null){ 44 | currentSheet.config = {}; 45 | } 46 | 47 | if(currentSheet.config.sheetViewZoom==null){ 48 | currentSheet.config.sheetViewZoom = {}; 49 | } 50 | 51 | let type = currentSheet.config.curentsheetView; 52 | if(type==null){ 53 | type = "viewNormal"; 54 | } 55 | currentSheet.config.sheetViewZoom[type+"ZoomScale"] = ratio; 56 | 57 | server.saveParam("all", Store.currentSheetIndex, Store.zoomRatio, { "k": "zoomRatio" }); 58 | server.saveParam("cg", Store.currentSheetIndex, currentSheet.config["sheetViewZoom"], { "k": "sheetViewZoom" }); 59 | 60 | zoomRefreshView(); 61 | }, 100); 62 | 63 | } 64 | 65 | export function zoomRefreshView(){ 66 | // let $scrollLeft = $("#luckysheet-scrollbar-x"), $scrollTop = $("#luckysheet-scrollbar-y"); 67 | // let sl = $scrollLeft.scrollLeft(), st = $scrollTop.scrollTop(); 68 | 69 | // let wp = $scrollLeft.find("div").width(), hp = $scrollTop.find("div").height(); 70 | 71 | jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length); 72 | changeSheetContainerSize(); 73 | 74 | // let wc = $scrollLeft.find("div").width(), hc = $scrollTop.find("div").height(); 75 | 76 | // $scrollLeft.scrollLeft(sl+wc-wp); 77 | // $scrollTop.scrollTop(st+hc-hp); 78 | } 79 | 80 | 81 | export function zoomInitial(){ 82 | 83 | $("#luckysheet-zoom-minus").click(function(){ 84 | let currentRatio; 85 | if(Store.zoomRatio==null){ 86 | currentRatio = Store.zoomRatio = 1; 87 | } 88 | else{ 89 | currentRatio = Math.ceil(Store.zoomRatio*10)/10; 90 | } 91 | 92 | currentRatio = currentRatio-0.1; 93 | 94 | if(currentRatio==Store.zoomRatio){ 95 | currentRatio = currentRatio-0.1; 96 | } 97 | 98 | if(currentRatio<=0.1){ 99 | currentRatio = 0.1; 100 | } 101 | 102 | // Store.zoomRatio = currentRatio; 103 | zoomChange(currentRatio); 104 | zoomNumberDomBind(currentRatio); 105 | }); 106 | 107 | $("#luckysheet-zoom-plus").click(function(){ 108 | let currentRatio; 109 | if(Store.zoomRatio==null){ 110 | currentRatio = Store.zoomRatio = 1; 111 | } 112 | else{ 113 | currentRatio = Math.floor(Store.zoomRatio*10)/10; 114 | } 115 | 116 | currentRatio = currentRatio+0.1; 117 | 118 | if(currentRatio==Store.zoomRatio){ 119 | currentRatio = currentRatio+0.1; 120 | } 121 | 122 | if(currentRatio>=4){ 123 | currentRatio = 4; 124 | } 125 | 126 | // Store.zoomRatio = currentRatio; 127 | zoomChange(currentRatio); 128 | zoomNumberDomBind(currentRatio); 129 | }); 130 | 131 | $("#luckysheet-zoom-slider").mousedown(function(e){ 132 | let xoffset = $(this).offset().left, pageX = e.pageX; 133 | 134 | let currentRatio = positionToRatio(pageX-xoffset); 135 | // Store.zoomRatio = currentRatio; 136 | zoomChange(currentRatio); 137 | zoomNumberDomBind(currentRatio); 138 | }); 139 | 140 | $("#luckysheet-zoom-cursor").mousedown(function(e){ 141 | let curentX = e.pageX,cursorLeft = parseFloat($("#luckysheet-zoom-cursor").css("left")); 142 | $("#luckysheet-zoom-cursor").css("transition","none"); 143 | $(document).off("mousemove.zoomCursor").on("mousemove.zoomCursor",function(event){ 144 | let moveX = event.pageX; 145 | let offsetX = moveX - curentX; 146 | // console.log(moveX, curentX, offsetX); 147 | // curentX = moveX; 148 | // let left = parseFloat($("#luckysheet-zoom-cursor").css("left")); 149 | let pos = cursorLeft + offsetX; 150 | let currentRatio = positionToRatio(pos); 151 | 152 | if(currentRatio>4){ 153 | currentRatio =4; 154 | pos = 100; 155 | } 156 | 157 | if(currentRatio<0.1){ 158 | currentRatio =0.1; 159 | pos = 0; 160 | } 161 | 162 | // Store.zoomRatio = currentRatio; 163 | zoomChange(currentRatio); 164 | let r = Math.round(currentRatio*100) + "%"; 165 | $("#luckysheet-zoom-ratioText").html(r); 166 | $("#luckysheet-zoom-cursor").css("left", pos-4); 167 | }); 168 | 169 | $(document).off("mouseup.zoomCursor").on("mouseup.zoomCursor",function(event){ 170 | $(document).off(".zoomCursor"); 171 | $("#luckysheet-zoom-cursor").css("transition","all 0.3s"); 172 | }); 173 | 174 | e.stopPropagation(); 175 | }).click(function(e){ 176 | e.stopPropagation(); 177 | }); 178 | 179 | $("#luckysheet-zoom-ratioText").click(function(){ 180 | // Store.zoomRatio = 1; 181 | zoomChange(1); 182 | zoomNumberDomBind(1); 183 | }); 184 | 185 | zoomNumberDomBind(Store.zoomRatio); 186 | } 187 | 188 | 189 | function zoomSlierDown(){ 190 | 191 | } 192 | 193 | function positionToRatio(pos){ 194 | let ratio = 1; 195 | if(pos<50){ 196 | ratio = Math.round((pos*1.8/100 + 0.1)*100)/100; 197 | } 198 | else if(pos>50){ 199 | ratio = Math.round(((pos-50)*6/100 + 1)*100)/100; 200 | } 201 | 202 | return ratio; 203 | } 204 | 205 | function zoomSlierDomBind(ratio){ 206 | let domPos = 50; 207 | if(ratio<1){ 208 | domPos = Math.round((ratio - 0.1)*100 / 0.18)/10; 209 | } 210 | else if(ratio>1){ 211 | domPos = Math.round((ratio - 1)*100 / 0.6)/10+50; 212 | } 213 | $("#luckysheet-zoom-cursor").css("left", domPos-4); 214 | } 215 | 216 | export function zoomNumberDomBind(ratio){ 217 | let r = Math.round(ratio*100) + "%"; 218 | $("#luckysheet-zoom-ratioText").html(r); 219 | zoomSlierDomBind(ratio); 220 | } 221 | 222 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/EwaAntH.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/EwaAntH.gif -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/EwaAntV.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/EwaAntV.gif -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/arrow-down.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/iconCustom.css: -------------------------------------------------------------------------------- 1 | .luckysheet-icon-img-container.iconfont, 2 | .luckysheet-submenu-arrow .iconfont 3 | { 4 | font-size: 24px; 5 | } 6 | 7 | .luckysheet-toolbar-menu-button .luckysheet-iconfont-xiayige, 8 | .luckysheet-toolbar-combo-button .luckysheet-iconfont-xiayige 9 | { 10 | font-size: 12px; 11 | top: -8px; 12 | left: -3px; 13 | } 14 | 15 | .luckysheet-toolbar-select .luckysheet-iconfont-xiayige{ 16 | margin-right: 4px; 17 | } 18 | 19 | #luckysheet-icon-morebtn{ 20 | position: absolute; 21 | right: 15px; 22 | transform: translate(0,-50%); 23 | top: 50%; 24 | } 25 | 26 | 27 | .toolbar .luckysheet-icon-text-color, 28 | .toolbar .luckysheet-icon-cell-color, 29 | .toolbar .luckysheet-icon-border-all, 30 | .toolbar .luckysheet-icon-valign, 31 | .toolbar .luckysheet-icon-textwrap 32 | { 33 | margin-right: -3px; 34 | } 35 | 36 | .toolbar .luckysheet-icon-merge-button, 37 | .toolbar .luckysheet-icon-align, 38 | .toolbar .luckysheet-icon-rotation, 39 | .toolbar .luckysheet-icon-function, 40 | .toolbar .luckysheet-freezen-btn-horizontal 41 | { 42 | margin-right: -4px; 43 | } 44 | 45 | #luckysheet-icon-morebtn{ 46 | padding: 2px 13px 0 5px; 47 | } 48 | #luckysheet-icon-morebtn .iconfont{ 49 | top:-9px; 50 | } 51 | 52 | 53 | /* custom common style */ 54 | 55 | .lucky-button-custom{ 56 | cursor: pointer; 57 | display: flex; 58 | align-items: center; 59 | justify-content: center; 60 | } 61 | .lucky-button-custom:hover{ 62 | background-color: #E1E4E8; 63 | } 64 | 65 | /* more button border */ 66 | #luckysheet-icon-morebtn-div{ 67 | border: 1px solid rgb(212, 212, 212); 68 | } 69 | 70 | /* sheet bar add/menu button */ 71 | /* #luckysheet-sheets-add, #luckysheet-sheets-m{ 72 | padding: 1px 3px; 73 | } */ 74 | .luckysheet-sheets-add .iconfont, .luckysheet-sheets-m .iconfont{ 75 | font-size: 21px; 76 | } 77 | 78 | /* sheet bar left/right scroll */ 79 | #luckysheet-sheets-leftscroll , #luckysheet-sheets-rightscroll{ 80 | padding:6px 10px; 81 | } 82 | 83 | input.luckysheet-mousedown-cancel{ 84 | border:1px solid #A1A1A1; 85 | } 86 | input.luckysheet-mousedown-cancel:focus{ 87 | border: 1px solid rgb(1, 136, 251); 88 | outline: none; 89 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/loading.gif -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/luckysheet-cellFormat.css: -------------------------------------------------------------------------------- 1 | .luckysheet-cellFormat-config{ 2 | display: none; 3 | } 4 | 5 | .luckysheet-cellFormat-config .luckysheet-modal-dialog-content{ 6 | position: relative; 7 | height: 550px; 8 | width: 600px; 9 | } 10 | 11 | .luckysheet-cellFormat-menu-c{ 12 | position: absolute; 13 | width: 100%; 14 | height: 30px; 15 | border-right: 1px solid #fff; 16 | border-bottom: 1px solid #d4d4d4; 17 | font-size: 12px; 18 | } 19 | 20 | .luckysheet-cellFormat-menu{ 21 | position: relative; 22 | display: inline-block; 23 | height: 30px; 24 | width: 80px; 25 | text-align: center; 26 | line-height: 30px; 27 | border: 1px solid #d4d4d4; 28 | border-bottom: none; 29 | background: #F0F0F0; 30 | cursor: pointer; 31 | } 32 | 33 | .luckysheet-cellFormat-menu:hover{ 34 | background: #e7e7e7; 35 | } 36 | 37 | 38 | .luckysheet-cellFormat-menu-active{ 39 | background: #fff; 40 | cursor: default; 41 | } 42 | 43 | .luckysheet-cellFormat-menu-active:hover{ 44 | background: #fff; 45 | } 46 | 47 | 48 | .luckysheet-cellFormat-content{ 49 | position: absolute; 50 | top:30px; 51 | bottom: 0px; 52 | width: 100%; 53 | border: 1px solid #d4d4d4; 54 | border-top: none; 55 | } 56 | 57 | .luckysheet-cellFormat-protection{ 58 | position: relative; 59 | margin-top: 30px; 60 | margin-left: 40px; 61 | } 62 | 63 | .luckysheet-cellFormat-protection span{ 64 | font-size: 12px; 65 | color:#ff2929; 66 | padding-left: 12px; 67 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/luckysheet-print.css: -------------------------------------------------------------------------------- 1 | .luckysheet-print-viewList{ 2 | position: relative; 3 | float: right; 4 | width:126px; 5 | /* right: 222px; */ 6 | height: 22px; 7 | line-height: 22px; 8 | text-align: center; 9 | white-space: nowrap; 10 | overflow: hidden; 11 | display: flex; 12 | align-items: center; 13 | user-select: none; 14 | } 15 | 16 | .luckysheet-print-viewBtn { 17 | position: absolute; 18 | top: 0; 19 | left: 0px; 20 | width: 42px; 21 | height:22px; 22 | align-items: center; 23 | justify-content: center; 24 | cursor: pointer; 25 | } 26 | 27 | .luckysheet-print-viewBtn .iconfont{ 28 | font-size: 22px; 29 | } 30 | 31 | .luckysheet-print-viewBtn:hover{ 32 | background: #E1E4E8; 33 | } 34 | 35 | .luckysheet-print-viewBtn-active{ 36 | background: #dcdcdc; 37 | cursor: default; 38 | } 39 | 40 | .luckysheet-print-viewBtn-active:hover{ 41 | background: #dcdcdc; 42 | } 43 | 44 | .luckysheet-print-viewNormal{ 45 | left: 0px; 46 | } 47 | 48 | .luckysheet-print-viewLayout{ 49 | left: 42px; 50 | } 51 | 52 | .luckysheet-print-viewPage{ 53 | left: 84px; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/luckysheet-protection.css: -------------------------------------------------------------------------------- 1 | 2 | #luckysheet-modal-dialog-slider-protection .luckysheet-modal-dialog-slider-content{ 3 | background: #fff; 4 | } 5 | 6 | .luckysheet-slider-protection-config{ 7 | position: absolute; 8 | width: 100%; 9 | } 10 | 11 | .luckysheet-slider-protection-row{ 12 | position: relative; 13 | width: 98%; 14 | height: 35px; 15 | left: 1%; 16 | } 17 | 18 | .luckysheet-slider-protection-column{ 19 | position: absolute; 20 | height: 100%; 21 | } 22 | 23 | 24 | .luckysheet-slider-protection-config input, .luckysheet-slider-protection-config textarea, .luckysheet-protection-rangeItem-dialog input, .luckysheet-protection-rangeItem-dialog textarea, .luckysheet-protection-sheet-validation input{ 25 | border: 1px solid #d4d4d4; 26 | outline: none; 27 | } 28 | 29 | .luckysheet-slider-protection-config input:focus, .luckysheet-slider-protection-config textarea:focus, .luckysheet-protection-rangeItem-dialog input:focus, .luckysheet-protection-rangeItem-dialog textarea:focus,.luckysheet-protection-sheet-validation input:focus{ 30 | border: 1px solid #0389FB; 31 | outline: none; 32 | } 33 | 34 | .luckysheet-protection-input{ 35 | width: 100%; 36 | height: 19px; 37 | position: relative; 38 | } 39 | 40 | .luckysheet-protection-textarea{ 41 | width: 100%; 42 | height: 47px; 43 | position: relative; 44 | resize:none; 45 | } 46 | 47 | .luckysheet-protection-column-2x{ 48 | width: 20%; 49 | } 50 | 51 | .luckysheet-protection-column-3x{ 52 | width: 30%; 53 | } 54 | 55 | .luckysheet-protection-column-4x{ 56 | width: 40%; 57 | } 58 | 59 | .luckysheet-protection-column-5x{ 60 | width: 50%; 61 | } 62 | 63 | .luckysheet-protection-column-6x{ 64 | width: 60%; 65 | } 66 | 67 | .luckysheet-protection-column-7x{ 68 | width: 70%; 69 | } 70 | 71 | .luckysheet-protection-column-8x{ 72 | width: 80%; 73 | } 74 | 75 | .luckysheet-protection-column-9x{ 76 | width: 90%; 77 | } 78 | 79 | .luckysheet-protection-column-10x{ 80 | width: 100%; 81 | } 82 | 83 | .luckysheet-protection-column-left{ 84 | text-align: left; 85 | } 86 | 87 | .luckysheet-protection-column-center{ 88 | text-align: center; 89 | } 90 | 91 | .luckysheet-protection-column-right{ 92 | text-align: right; 93 | } 94 | 95 | .luckysheet-slider-protection-ok{ 96 | position: absolute; 97 | width: 100%; 98 | height: 100%; 99 | background: #0188fb; 100 | color: #fff; 101 | text-align: center; 102 | line-height: 45px; 103 | font-size: 16px; 104 | cursor: pointer; 105 | } 106 | 107 | .luckysheet-slider-protection-ok:hover{ 108 | background: #0181EE; 109 | } 110 | 111 | .luckysheet-slider-protection-ok:active{ 112 | background: #0074da; 113 | } 114 | 115 | .luckysheet-slider-protection-cancel{ 116 | position: absolute; 117 | width: 100%; 118 | height: 100%; 119 | background: #e6e6e6; 120 | color: #353535; 121 | text-align: center; 122 | line-height: 45px; 123 | font-size: 16px; 124 | cursor: pointer; 125 | } 126 | 127 | .luckysheet-slider-protection-cancel:hover{ 128 | background: #d6d6d6; 129 | } 130 | 131 | .luckysheet-slider-protection-cancel:active{ 132 | background: #c7c7c7; 133 | } 134 | 135 | .luckysheet-slider-protection-addRange{ 136 | line-height: 23px; 137 | font-size: 12px; 138 | top: 2px; 139 | height: 23px; 140 | } 141 | 142 | 143 | .luckysheet-protection-rangeItem{ 144 | position: relative; 145 | width: 100%; 146 | height: 30px; 147 | line-height: 30px; 148 | font-size: 12px; 149 | overflow: hidden; 150 | } 151 | 152 | .luckysheet-protection-rangeItem:hover{ 153 | background: #D5D5D5; 154 | } 155 | 156 | .luckysheet-protection-rangeItem > div{ 157 | position: absolute; 158 | height: 100%; 159 | text-align: center; 160 | overflow: hidden; 161 | } 162 | 163 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-del{ 164 | left: 5px; 165 | top:5px; 166 | height: 20px; 167 | width: 20px; 168 | font-size: 14px; 169 | line-height: 20px; 170 | cursor: pointer; 171 | } 172 | 173 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-name{ 174 | left: 30px; 175 | width: 80px; 176 | text-align: left; 177 | } 178 | 179 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-range{ 180 | left: 110px; 181 | width: 120px; 182 | } 183 | 184 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-update{ 185 | left: 230px; 186 | width: 30px; 187 | font-size: 14px; 188 | top: 5px; 189 | height: 20px; 190 | width: 20px; 191 | line-height: 20px; 192 | cursor: pointer; 193 | } 194 | 195 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-del:hover, .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-update:hover{ 196 | background: #0181EE; 197 | color: #fff; 198 | } 199 | 200 | .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-del:active, .luckysheet-protection-rangeItem .luckysheet-protection-rangeItem-update:active{ 201 | background: #0074da; 202 | color: #fff; 203 | } 204 | 205 | 206 | .luckysheet-protection-rangeItem-content{ 207 | position: relative; 208 | width: 350px; 209 | height: 270px; 210 | } 211 | 212 | 213 | #luckysheet-protection-rangeItem-dialog .luckysheet-slider-protection-column .range { 214 | width: 100%; 215 | height: 30px; 216 | border: 1px solid #d4d4d4; 217 | } 218 | 219 | #luckysheet-protection-rangeItem-dialog .luckysheet-slider-protection-column .range input { 220 | width: calc(100% - 30px); 221 | height: 30px; 222 | padding: 0 10px; 223 | float: left; 224 | border: none; 225 | outline-style: none; 226 | box-sizing: border-box; 227 | } 228 | 229 | #luckysheet-protection-rangeItem-dialog .luckysheet-slider-protection-column .range i.fa-table { 230 | float: right; 231 | margin-top: 9px; 232 | margin-right: 5px; 233 | cursor: pointer; 234 | color: #6598F3; 235 | } 236 | 237 | .luckysheet-protection-rangeItemTextarea{ 238 | width: 100%; 239 | height: 120px; 240 | position: relative; 241 | resize:none; 242 | } 243 | 244 | .luckysheet-protection-rangeItemiInput{ 245 | width: 100%; 246 | height: 23px; 247 | position: relative; 248 | } 249 | 250 | 251 | .luckysheet-protection-sheet-validation{ 252 | width: 390px; 253 | height: 180px; 254 | display: none; 255 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/luckysheet-zoom.css: -------------------------------------------------------------------------------- 1 | .luckysheet-zoom-content{ 2 | position: relative; 3 | float: right; 4 | width:210px; 5 | /* right: 0px; */ 6 | height: 22px; 7 | line-height: 22px; 8 | text-align: right; 9 | padding-right: 10px; 10 | white-space: nowrap; 11 | overflow: hidden; 12 | display: flex; 13 | align-items: center; 14 | user-select: none; 15 | } 16 | 17 | .luckysheet-zoom-content .luckysheet-zoom-minus{ 18 | position: absolute; 19 | top: 0; 20 | left: 0px; 21 | width: 20px; 22 | height:20px; 23 | cursor: pointer; 24 | display: flex; 25 | align-items: center; 26 | justify-content: center; 27 | } 28 | 29 | .luckysheet-zoom-content .luckysheet-zoom-minus-icon{ 30 | background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTRweCIgaGVpZ2h0PSIycHgiIHZpZXdCb3g9IjAgMCAxNCAyIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA2MyAoOTI0NDUpIC0gaHR0cHM6Ly9za2V0Y2guY29tIC0tPgogICAgPHRpdGxlPnJpcWlxdWppYW7lpIfku70gNDU8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZyBpZD0iMjAyMC8wOC8xNCIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IueUu+adv+Wkh+S7vS0yIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTcwNC4wMDAwMDAsIC0xMDY0LjAwMDAwMCkiIGZpbGw9IiM0NDRENUEiPgogICAgICAgICAgICA8ZyBpZD0icmlxaXF1amlhbuWkh+S7vS0xMjYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2OTkuMDAwMDAwLCAxMDUzLjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPGcgaWQ9Iue8lue7hCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNS4wMDAwMDAsIDExLjAwMDAwMCkiPgogICAgICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaIiIHg9IjAiIHk9IjAiIHdpZHRoPSIxNCIgaGVpZ2h0PSIyIj48L3JlY3Q+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg=='); 31 | width: 14px; 32 | height: 2px; 33 | } 34 | 35 | .luckysheet-zoom-content .luckysheet-zoom-minus:hover{ 36 | background-color: #E1E4E8; 37 | } 38 | 39 | .luckysheet-zoom-content .luckysheet-zoom-slider{ 40 | position: absolute; 41 | top: 0; 42 | left: 25px; 43 | width: 100px; 44 | height: 100%; 45 | display: flex; 46 | align-items: center; 47 | } 48 | 49 | 50 | .luckysheet-zoom-content .luckysheet-zoom-slider .luckysheet-zoom-line{ 51 | position: absolute; 52 | top: 10px; 53 | width: 100px; 54 | height: 2px; 55 | background: #E1E4E8; 56 | } 57 | 58 | .luckysheet-zoom-content .luckysheet-zoom-slider .luckysheet-zoom-cursor{ 59 | position: absolute; 60 | top: 7px; 61 | width: 8px; 62 | height: 8px; 63 | border-radius: 8px; 64 | background: #B5BDB8; 65 | cursor: pointer; 66 | z-index: 2; 67 | transition: all 0.3s; 68 | } 69 | 70 | .luckysheet-zoom-content .luckysheet-zoom-slider .luckysheet-zoom-cursor:hover{ 71 | transform: scale(1.2); 72 | transform-origin: center center; 73 | background: rgb(160, 160, 160); 74 | } 75 | 76 | .luckysheet-zoom-content .luckysheet-zoom-slider .luckysheet-zoom-hundred{ 77 | position: absolute; 78 | top: 9px; 79 | width: 2px; 80 | height: 4px; 81 | left: 49px; 82 | background: #1E1E1F; 83 | } 84 | 85 | 86 | .luckysheet-zoom-content .luckysheet-zoom-plus{ 87 | position: absolute; 88 | top: 0; 89 | left: 130px; 90 | width: 20px; 91 | height:20px; 92 | cursor: pointer; 93 | display: flex; 94 | align-items: center; 95 | justify-content: center; 96 | } 97 | 98 | .luckysheet-zoom-content .luckysheet-zoom-plus .luckysheet-zoom-plus-icon{ 99 | background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTRweCIgaGVpZ2h0PSIxNHB4IiB2aWV3Qm94PSIwIDAgMTQgMTQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDYzICg5MjQ0NSkgLSBodHRwczovL3NrZXRjaC5jb20gLS0+CiAgICA8dGl0bGU+cmlxaXF1amlhbuWkh+S7vSA0NjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxnIGlkPSIyMDIwLzA4LzE0IiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0i55S75p2/5aSH5Lu9LTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xODQ4LjAwMDAwMCwgLTEwNTguMDAwMDAwKSIgZmlsbD0iIzQ0NEQ1QSI+CiAgICAgICAgICAgIDxnIGlkPSJyaXFpcXVqaWFu5aSH5Lu9LTExOSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTg0My4wMDAwMDAsIDEwNTMuMDAwMDAwKSI+CiAgICAgICAgICAgICAgICA8ZyBpZD0i57yW57uEIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1LjAwMDAwMCwgNS4wMDAwMDApIj4KICAgICAgICAgICAgICAgICAgICA8cmVjdCBpZD0i55+p5b2iIiB4PSIwIiB5PSI2IiB3aWR0aD0iMTQiIGhlaWdodD0iMiI+PC9yZWN0PgogICAgICAgICAgICAgICAgICAgIDxyZWN0IGlkPSLnn6nlvaLlpIfku70iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDcuMDAwMDAwLCA3LjAwMDAwMCkgcm90YXRlKC0yNzAuMDAwMDAwKSB0cmFuc2xhdGUoLTcuMDAwMDAwLCAtNy4wMDAwMDApICIgeD0iMCIgeT0iNiIgd2lkdGg9IjE0IiBoZWlnaHQ9IjIiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'); 100 | width: 14px; 101 | height: 14px; 102 | } 103 | 104 | .luckysheet-zoom-content .luckysheet-zoom-plus:hover{ 105 | background-color: #E1E4E8; 106 | } 107 | 108 | .luckysheet-zoom-content .luckysheet-zoom-ratioText{ 109 | position: absolute; 110 | top: 0; 111 | left: 155px; 112 | width: 60px; 113 | color: #1E1E1F; 114 | font-size: 12px; 115 | text-align: left; 116 | cursor: pointer; 117 | } 118 | 119 | .luckysheet-zoom-content .luckysheet-zoom-ratioText:hover{ 120 | background-color: #E1E4E8; 121 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/paint_16px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/paint_16px.ico -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/paint_24px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/paint_24px.ico -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/paint_32px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/paint_32px.ico -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/css/waffle_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/css/waffle_sprite.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/demoData/demoFeature.js: -------------------------------------------------------------------------------- 1 | 2 | // Features specially written for demo 3 | 4 | (function() { 5 | 6 | // language 7 | function language(params) { 8 | 9 | var lang = navigator.language||navigator.userLanguage;//常规浏览器语言和IE浏览器 10 | lang = lang.substr(0, 2);//截取lang前2位字符 11 | 12 | return lang; 13 | 14 | } 15 | // Tencent Forum Link Button 16 | function supportButton() { 17 | const text = language() === 'zh' ? '反馈' : 'Forum'; 18 | const link = language() === 'zh' ? 'https://support.qq.com/product/288322' : 'https://groups.google.com/g/luckysheet'; 19 | 20 | document.querySelector("body").insertAdjacentHTML('beforeend', ''+ text +''); 21 | } 22 | 23 | supportButton() 24 | 25 | /** 26 | * Get url parameters 27 | */ 28 | function getRequest() { 29 | var vars = {}; 30 | var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, 31 | function(m,key,value) { 32 | vars[key] = value; 33 | }); 34 | return vars; 35 | } 36 | 37 | window.luckysheetDemoUtil = { 38 | language:language, 39 | getRequest:getRequest 40 | } 41 | 42 | })() -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/demoData/sheetComment.js: -------------------------------------------------------------------------------- 1 | window.sheetComment = { 2 | "name": "Comment", 3 | "color": "", 4 | "config": { 5 | "columnlen": { 6 | "2": 102 7 | } 8 | }, 9 | "index": "5", 10 | "chart": [], 11 | "status": 0, 12 | "order": "5", 13 | "column": 18, 14 | "row": 36, 15 | "celldata": [{ 16 | "r": 2, 17 | "c": 2, 18 | "v": { 19 | "m": "HoverShown", 20 | "ct": { 21 | "fa": "General", 22 | "t": "g" 23 | }, 24 | "v": "HoverShown", 25 | "bl": 1, 26 | "ps": { 27 | "left": null, 28 | "top": null, 29 | "width": null, 30 | "height": null, 31 | "value": "Hello world!", 32 | "isshow": false 33 | } 34 | } 35 | }, { 36 | "r": 7, 37 | "c": 2, 38 | "v": { 39 | "m": "Size", 40 | "ct": { 41 | "fa": "General", 42 | "t": "g" 43 | }, 44 | "v": "Size", 45 | "bl": 1, 46 | "ps": { 47 | "left": null, 48 | "top": null, 49 | "width": null, 50 | "height": null, 51 | "value": "Hello,world!", 52 | "isshow": true 53 | } 54 | } 55 | }], 56 | "ch_width": 4748, 57 | "rh_height": 1790, 58 | "luckysheet_select_save": [{ 59 | "row": [0, 0], 60 | "column": [0, 0] 61 | }], 62 | "luckysheet_selection_range": [], 63 | "scrollLeft": 0, 64 | "scrollTop": 0 65 | } 66 | 67 | // export default sheetComment; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/demoData/sheetPivotTable.js: -------------------------------------------------------------------------------- 1 | window.sheetPivotTable = { 2 | "name": "PivotTable", 3 | "color": "", 4 | "config": {}, 5 | "index": "7", 6 | "chart": [], 7 | "status": 0, 8 | "order": "7", 9 | "column": 18, 10 | "row": 36, 11 | "celldata": [{ 12 | "r": 0, 13 | "c": 0, 14 | "v": "count:score" 15 | }, { 16 | "r": 0, 17 | "c": 1, 18 | "v": "science" 19 | }, { 20 | "r": 0, 21 | "c": 2, 22 | "v": "mathematics" 23 | }, { 24 | "r": 0, 25 | "c": 3, 26 | "v": "foreign language" 27 | }, { 28 | "r": 0, 29 | "c": 4, 30 | "v": "English" 31 | }, { 32 | "r": 0, 33 | "c": 5, 34 | "v": "total" 35 | }, { 36 | "r": 1, 37 | "c": 0, 38 | "v": "Alex" 39 | }, { 40 | "r": 1, 41 | "c": 1, 42 | "v": 1 43 | }, { 44 | "r": 1, 45 | "c": 2, 46 | "v": 1 47 | }, { 48 | "r": 1, 49 | "c": 3, 50 | "v": 1 51 | }, { 52 | "r": 1, 53 | "c": 4, 54 | "v": 1 55 | }, { 56 | "r": 1, 57 | "c": 5, 58 | "v": 4 59 | }, { 60 | "r": 2, 61 | "c": 0, 62 | "v": "Joy" 63 | }, { 64 | "r": 2, 65 | "c": 1, 66 | "v": 1 67 | }, { 68 | "r": 2, 69 | "c": 2, 70 | "v": 1 71 | }, { 72 | "r": 2, 73 | "c": 3, 74 | "v": 1 75 | }, { 76 | "r": 2, 77 | "c": 4, 78 | "v": 1 79 | }, { 80 | "r": 2, 81 | "c": 5, 82 | "v": 4 83 | }, { 84 | "r": 3, 85 | "c": 0, 86 | "v": "Tim" 87 | }, { 88 | "r": 3, 89 | "c": 1, 90 | "v": 1 91 | }, { 92 | "r": 3, 93 | "c": 2, 94 | "v": 1 95 | }, { 96 | "r": 3, 97 | "c": 3, 98 | "v": 1 99 | }, { 100 | "r": 3, 101 | "c": 4, 102 | "v": 1 103 | }, { 104 | "r": 3, 105 | "c": 5, 106 | "v": 4 107 | }, { 108 | "r": 4, 109 | "c": 0, 110 | "v": "total" 111 | }, { 112 | "r": 4, 113 | "c": 1, 114 | "v": 3 115 | }, { 116 | "r": 4, 117 | "c": 2, 118 | "v": 3 119 | }, { 120 | "r": 4, 121 | "c": 3, 122 | "v": 3 123 | }, { 124 | "r": 4, 125 | "c": 4, 126 | "v": 3 127 | }, { 128 | "r": 4, 129 | "c": 5, 130 | "v": 12 131 | }], 132 | "ch_width": 4748, 133 | "rh_height": 1790, 134 | "luckysheet_select_save": [{ 135 | "row": [0, 0], 136 | "column": [0, 0] 137 | }], 138 | "luckysheet_selection_range": [], 139 | "scrollLeft": 0, 140 | "scrollTop": 0, 141 | "isPivotTable": true, 142 | "pivotTable": { 143 | "pivot_select_save": { 144 | "left": 0, 145 | "width": 73, 146 | "top": 0, 147 | "height": 19, 148 | "left_move": 0, 149 | "width_move": 369, 150 | "top_move": 0, 151 | "height_move": 259, 152 | "row": [0, 12], 153 | "column": [0, 4], 154 | "row_focus": 0, 155 | "column_focus": 0 156 | }, 157 | "pivotDataSheetIndex": 6, //The sheet index where the source data is located 158 | "column": [{ 159 | "index": 3, 160 | "name": "subject", 161 | "fullname": "subject" 162 | }], 163 | "row": [{ 164 | "index": 1, 165 | "name": "student", 166 | "fullname": "student" 167 | }], 168 | "filter": [], 169 | "values": [{ 170 | "index": 4, 171 | "name": "score", 172 | "fullname": "count:score", 173 | "sumtype": "COUNTA", 174 | "nameindex": 0 175 | }], 176 | "showType": "column", 177 | "pivotDatas": [ 178 | ["count:score", "science", "mathematics", "foreign language", "English", "total"], 179 | ["Alex", 1, 1, 1, 1, 4], 180 | ["Joy", 1, 1, 1, 1, 4], 181 | ["Tim", 1, 1, 1, 1, 4], 182 | ["total", 3, 3, 3, 3, 12] 183 | ], 184 | "drawPivotTable": false, 185 | "pivotTableBoundary": [5, 6] 186 | } 187 | } 188 | 189 | // export default sheetPivotTable; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/expendPlugins/chart/chartmix.css: -------------------------------------------------------------------------------- 1 | .luckysheet-datavisual-quick-menu{width:120px;overflow:auto;margin-top:15px}.luckysheet-datavisual-quick-menu::-webkit-scrollbar{display:none}.luckysheet-datavisual-quick-menu>div{text-align:left;padding:4px 4px;border-right:3px solid #fff;color:#777;cursor:pointer;line-height:1.4em;word-wrap:break-word}.luckysheet-datavisual-quick-menu>div:hover{color:#000}.luckysheet-datavisual-quick-menu>div i{width:15px}.luckysheet-datavisual-quick-menu>div:hover i{color:#ff7e7e}.luckysheet-datavisual-quick-menu>div.luckysheet-datavisual-quick-menu-active{border-right:3px solid #ff7e7e;color:#000;font-weight:700}.luckysheet-datavisual-quick-menu>div.luckysheet-datavisual-quick-menu-active:hover i{color:#000}.luckysheet-datavisual-quick-range{padding:5px 0}.luckysheet-datavisual-range-container{background:#fff;border:1px solid #d9d9d9;border-top:1px solid silver;min-width:20px;width:100%;max-width:200px;display:inline-block}.luckysheet-datavisual-range-container-focus{border:1px solid #4d90fe;box-shadow:inset 0 1px 2px rgba(0,0,0,.3);outline:none}.luckysheet-datavisual-range-input,.luckysheet-datavisual-range-input:focus{background:transparent!important;border:none!important;box-sizing:border-box;box-shadow:none;height:25px;margin:0;outline:none!important;padding:1px 8px!important;width:100%}.luckysheet-datavisual-range-button-container{overflow:hidden;padding:0 0 0 8px;text-align:right;width:21px}.luckysheet-datavisual-range-button-container div{padding:2px 10px 0 10px;font-size:18px;cursor:pointer;color:#6598f3}.luckysheet-datavisual-range-button-container div:hover{color:#ff7e7e}.luckysheet-datavisual-quick-m{margin-top:5px;min-height:500px;top:50px;font-size:12px}.luckysheet-datavisual-quick-list{left:110px;right:0;bottom:0;top:80px;position:absolute;overflow:auto;border-top:1px solid #e5e5e5;padding:5px 3px 35px 3px}.luckysheet-datavisual-quick-list-title{padding:4px 6px;background:#e5e5e5;margin-top:10px}.luckysheet-datavisual-quick-list-ul{overflow:hidden}.luckysheet-datavisual-quick-list-item{display:inline-block;margin:5px 8px;border:1px solid #dadada;width:100px;height:80px}.luckysheet-datavisual-quick-list-item:hover{border:1px solid #ff7e7e;box-shadow:0 0 20px #ff7e7e}.luckysheet-datavisual-quick-list-item img{display:inline-block;width:100px;height:80px}.luckysheet-datavisual-quick-list-item-active{border:1px solid #6598f3;box-shadow:0 0 20px #6598f3}.chart-base-slider .el-slider__runway.show-input{margin-right:72px}.chart-base-slider .el-slider__input.el-input-number--mini{width:56px}.chart-base-slider .input_content{margin:6px 0 0 5px}.title{font-weight:700}.el-row{font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.chartSetting{width:100%;height:100%} -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/expendPlugins/print/plugin.js: -------------------------------------------------------------------------------- 1 | import { seriesLoadScripts, loadLinks, $$ } from '../../utils/util' 2 | 3 | 4 | // Dynamically load dependent scripts and styles 5 | const dependScripts = [ 6 | // 'expendPlugins/chart/chartmix.umd.min.js', 7 | 'http://localhost:3000/expendPlugins/chart/chartmix.umd.min.js', 8 | ] 9 | 10 | const dependLinks = [ 11 | // 'expendPlugins/chart/chartmix.css', 12 | 'http://localhost:3000/expendPlugins/chart/chartmix.css', 13 | ] 14 | 15 | // Initialize the chart component 16 | function print(data, isDemo) { 17 | loadLinks(dependLinks); 18 | 19 | seriesLoadScripts(dependScripts, null, function () { 20 | 21 | }); 22 | } 23 | 24 | 25 | 26 | export { print } 27 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/function/functionlist.js: -------------------------------------------------------------------------------- 1 | import functionImplementation from './functionImplementation'; 2 | import Store from '../store/index' 3 | import locale from '../locale/locale'; 4 | //{"0":"数学","1":"统计","2":"查找","3":"Luckysheet内置","4":"数据挖掘","5":"数据源","6":"日期","7":"过滤器","8":"财务","9":"工程计算","10":"逻辑","11":"运算符","12":"文本","13":"转换工具","14":"数组"} 5 | 6 | const functionlist = function(){ 7 | let _locale = locale(); 8 | // internationalization,get function list 9 | let functionListOrigin = _locale.functionlist; 10 | 11 | // add new property f 12 | for (let i = 0; i < functionListOrigin.length; i++) { 13 | let func = functionListOrigin[i]; 14 | func.f = functionImplementation[func.n]; 15 | } 16 | 17 | Store.functionlist = functionListOrigin; 18 | 19 | // get n property 20 | const luckysheet_function = {}; 21 | 22 | for (let i = 0; i < functionListOrigin.length; i++) { 23 | let func = functionListOrigin[i]; 24 | luckysheet_function[func.n] = func; 25 | } 26 | 27 | window.luckysheet_function = luckysheet_function; //Mount window for eval() calculation formula 28 | 29 | Store.luckysheet_function = luckysheet_function; 30 | } 31 | 32 | export default functionlist; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/function/luckysheet_function.js: -------------------------------------------------------------------------------- 1 | import functionlist from './functionlist'; 2 | 3 | const luckysheet_function = {}; 4 | 5 | for (let i = 0; i < functionlist.length; i++) { 6 | let func = functionlist[i]; 7 | luckysheet_function[func.n] = func; 8 | } 9 | 10 | window.luckysheet_function = luckysheet_function; //挂载window 用于 eval() 计算公式 11 | 12 | export default luckysheet_function; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/analysis.js: -------------------------------------------------------------------------------- 1 | import { numFormat } from '../utils/util'; 2 | 3 | const analysis = { 4 | "STDEVP": function (mean, array1d) { 5 | let cov = 0; 6 | for (let i = 0; i < array1d.length; i++) { 7 | let xi = array1d[i]; 8 | cov += Math.pow(xi - mean, 2); 9 | } 10 | return numFormat(Math.sqrt(cov / array1d.length)); 11 | }, 12 | "STDEV": function (mean, array1d) { 13 | let cov = 0; 14 | for (let i = 0; i < array1d.length; i++) { 15 | let xi = array1d[i]; 16 | cov += Math.pow(xi - mean, 2); 17 | } 18 | return numFormat(Math.sqrt(cov / (array1d.length - 1))); 19 | }, 20 | "VARP": function (mean, array1d) { 21 | let cov = 0; 22 | for (let i = 0; i < array1d.length; i++) { 23 | let xi = array1d[i]; 24 | cov += Math.pow(xi - mean, 2); 25 | } 26 | return numFormat(cov / array1d.length); 27 | }, 28 | "let": function (mean, array1d) { 29 | let cov = 0; 30 | for (let i = 0; i < array1d.length; i++) { 31 | let xi = array1d[i]; 32 | cov += Math.pow(xi - mean, 2); 33 | } 34 | return numFormat(cov / (array1d.length - 1)); 35 | }, 36 | }; 37 | 38 | export default analysis; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/array.js: -------------------------------------------------------------------------------- 1 | import { getcellvalue } from './getdata'; 2 | 3 | const luckysheetArray = { 4 | transpose: function (getdata, useGetcellValue=true) { 5 | let arr = []; 6 | if (getdata.length == 0) { 7 | return []; 8 | } 9 | 10 | if (getdata[0].length == 0) { 11 | return []; 12 | } 13 | 14 | for (let c = 0; c < getdata[0].length; c++) { 15 | let a = []; 16 | for (let r = 0; r < getdata.length; r++) { 17 | let value = ""; 18 | if (getdata[r] != null && getdata[r][c] != null) { 19 | if(useGetcellValue){ 20 | value = getcellvalue(r, c, getdata); 21 | } 22 | else{ 23 | value = getdata[r][c]; 24 | } 25 | } 26 | a.push(value); 27 | } 28 | arr.push(a); 29 | } 30 | 31 | return arr; 32 | }, 33 | minusClear: function(p, m){ 34 | if(m.row[0] > p.row[1] || m.row[1] < p.row[0] || m.column[0] > p.column[1] || m.column[1] < p.column[0]){ 35 | return null; 36 | } 37 | 38 | if(m.row[0] == p.row[0] && m.row[1] < p.row[1] && m.column[0] > p.column[0] && m.column[1] < p.column[1]){ 39 | return []; 40 | } 41 | 42 | let ret = [], range = {row:[], column:[]}; 43 | 44 | let row1 = null, column1 = [p.column[0], p.column[1]]; 45 | if(m.row[1] > p.row[0] && m.row[1] < p.row[1]){ 46 | row1 = [m.row[1] + 1, p.row[1]]; 47 | } 48 | else if(m.row[0] > p.row[0] && m.row[0] < p.row[1]){ 49 | row1 = [p.row[0], m.row[0] - 1]; 50 | } 51 | 52 | if(row1 != null){ 53 | ret.push({"row": row1, "column": column1}); 54 | } 55 | 56 | let row2 = [p.row[0], p.row[1]], column2 = null; 57 | if(m.column[1] > p.column[0] && m.column[1] < p.column[1]){ 58 | column2 = [m.column[1] + 1, p.column[1]]; 59 | } 60 | else if(m.column[0] > p.column[0] && m.column[0] < p.column[1]){ 61 | column2 = [p.column[0], m.column[0] - 1]; 62 | } 63 | 64 | if(column2 != null){ 65 | ret.push({"row": row2, "column": column2}); 66 | } 67 | 68 | return ret; 69 | } 70 | } 71 | 72 | export default luckysheetArray; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/cleargridelement.js: -------------------------------------------------------------------------------- 1 | import selection from '../controllers/selection'; 2 | import menuButton from '../controllers/menuButton'; 3 | 4 | export default function cleargridelement(event) { 5 | $("#luckysheet-cols-h-hover").hide(); 6 | $("#luckysheet-rightclick-menu").hide(); 7 | 8 | $("#luckysheet-cell-selected-boxs .luckysheet-cell-selected").hide(); 9 | $("#luckysheet-cols-h-selected .luckysheet-cols-h-selected").hide(); 10 | $("#luckysheet-rows-h-selected .luckysheet-rows-h-selected").hide(); 11 | 12 | $("#luckysheet-cell-selected-focus").hide(); 13 | $("#luckysheet-rows-h-hover").hide(); 14 | $("#luckysheet-selection-copy .luckysheet-selection-copy").hide(); 15 | $("#luckysheet-cols-menu-btn").hide(); 16 | $("#luckysheet-row-count-show, #luckysheet-column-count-show").hide(); 17 | if (!event) { 18 | selection.clearcopy(event); 19 | } 20 | //else{ 21 | // selection.clearcopy(); 22 | //} 23 | 24 | //选区下拉icon隐藏 25 | if($("#luckysheet-dropCell-icon").is(":visible")){ 26 | if(event){ 27 | $("#luckysheet-dropCell-icon").remove(); 28 | } 29 | } 30 | //格式刷 31 | if(menuButton.luckysheetPaintModelOn && !event){ 32 | menuButton.cancelPaintModel(); 33 | } 34 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/count.js: -------------------------------------------------------------------------------- 1 | import Store from '../store'; 2 | import { getdatabyselectionNoCopy } from './getdata'; 3 | import { isRealNull, isRealNum } from './validate'; 4 | import { update } from './format'; 5 | import locale from '../locale/locale'; 6 | 7 | //表格计数栏 8 | export function countfunc() { 9 | if(Store.luckysheet_select_save.length == 0){ 10 | return; 11 | } 12 | 13 | let min = Infinity, //最小值 14 | max = -Infinity, //最大值 15 | sum = 0, //求和 16 | count = 0, //计数(非空单元格) 17 | mean = 0; //平均值 18 | 19 | for(let s = 0; s < Store.luckysheet_select_save.length; s++){ 20 | let data = getdatabyselectionNoCopy(Store.luckysheet_select_save[s]); 21 | 22 | for (let r = 0; r < data.length; r++) { 23 | for (let c = 0; c < data[0].length; c++) { 24 | if(isRealNull(data[r][c])){ 25 | continue; 26 | } 27 | 28 | count++; 29 | 30 | if(data[r][c].ct != null && data[r][c].ct.t == "d"){ 31 | continue; 32 | } 33 | 34 | let value = data[r][c].v; 35 | 36 | if(!isRealNum(value)){ 37 | continue; 38 | } 39 | 40 | value = parseFloat(value); 41 | 42 | sum += value; 43 | 44 | if(value < min){ 45 | min = value; 46 | } 47 | 48 | if(value > max){ 49 | max = value; 50 | } 51 | } 52 | } 53 | } 54 | 55 | let locale_formula = locale().formula; 56 | 57 | let ret = ""; 58 | ret += ""+locale_formula.count+":" + count + ""; 59 | 60 | //处理成亿万格式 61 | if (isFinite(max) || isFinite(min)) { 62 | ret += ""+locale_formula.sum+":" + update("w", sum) + ""; 63 | ret += ""+locale_formula.average+":" + update("w", Math.round(sum / count * 10000) / 10000) + ""; 64 | } 65 | 66 | if (isFinite(max)) { 67 | ret += ""+locale_formula.max+":" + update("w", max) + ""; 68 | } 69 | 70 | if (isFinite(min)) { 71 | ret += ""+locale_formula.min+":" + update("w", min) + ""; 72 | } 73 | 74 | $("#luckysheet-sta-content").html(ret); 75 | } 76 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/createdom.js: -------------------------------------------------------------------------------- 1 | import { 2 | gridHTML, 3 | menuToolBar, 4 | flow, 5 | columnHeaderHTML, 6 | maskHTML, 7 | colsmenuHTML, 8 | rightclickHTML, 9 | inputHTML, 10 | filtermenuHTML, 11 | filtersubmenuHTML, 12 | sheetconfigHTML, 13 | } from '../controllers/constant'; 14 | import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting'; 15 | import luckysheetPostil from '../controllers/postil'; 16 | import { datagridgrowth } from './getdata'; 17 | import editor from './editor'; 18 | import rhchInit from './rhchInit'; 19 | import { replaceHtml } from '../utils/util'; 20 | import Store from '../store'; 21 | import locale from '../locale/locale'; 22 | 23 | export default function luckysheetcreatedom(colwidth, rowheight, data, menu, title) { 24 | // //最少30行 25 | // if(rowheight < 30){ 26 | // rowheight = 30; 27 | // } 28 | 29 | // //最少22列 30 | // if(colwidth < 22){ 31 | // colwidth = 22; 32 | // } 33 | 34 | let gh = gridHTML(); 35 | gh = replaceHtml(gh, { "logotitle": title });//设置title 36 | gh = replaceHtml(gh, { "menu": menuToolBar() });//设置需要显示的菜单 37 | 38 | // if (data.length == 0) { 39 | // Store.flowdata = datagridgrowth(data, rowheight, colwidth); 40 | // } 41 | // else if (data.length < rowheight && data[0].length < colwidth) { 42 | // Store.flowdata = datagridgrowth(data, rowheight - data.length, colwidth - data[0].length); 43 | // } 44 | // else if (data.length < rowheight) { 45 | // Store.flowdata = datagridgrowth(data, rowheight - data.length, 0); 46 | // } 47 | // else if (data[0].length < colwidth) { 48 | // Store.flowdata = datagridgrowth(data, 0, colwidth - data[0].length); 49 | // } 50 | // else { 51 | // Store.flowdata = data; 52 | // } 53 | 54 | let flowHTML = flow; 55 | if(Store.config == null){ 56 | Store.config = {}; 57 | } 58 | 59 | rhchInit(rowheight, colwidth); 60 | 61 | const _locale = locale(); 62 | const locale_info = _locale.info; 63 | 64 | let addControll = ''+ locale_info.row +'('+locale_info.addLast+')'; 65 | let backControll = ' '; 66 | // let pageControll = ' 共'+ luckysheetConfigsetting.pageInfo.totalPage +'页,当前已显示'+ (luckysheetConfigsetting.pageInfo.currentPage) +'页,每页'+ luckysheetConfigsetting.pageInfo.pageSize +'条 '; 67 | let pageInfo = replaceHtml(locale_info.pageInfo,{ 68 | total:luckysheetConfigsetting.total?luckysheetConfigsetting.total:"", 69 | totalPage:luckysheetConfigsetting.pageInfo.totalPage?luckysheetConfigsetting.pageInfo.totalPage:"", 70 | currentPage:luckysheetConfigsetting.pageInfo.currentPage?luckysheetConfigsetting.pageInfo.currentPage:"", 71 | }); 72 | let pageControll = ' '+ pageInfo +' '; 73 | let pageControll2 = ' '+pageInfo+''; 74 | 75 | let bottomControll = ""; 76 | if(luckysheetConfigsetting.enableAddRow){ 77 | bottomControll += addControll; 78 | } 79 | 80 | if(luckysheetConfigsetting.enablePage){ 81 | if(parseInt(luckysheetConfigsetting.pageInfo.totalPage) == 1){ 82 | bottomControll += pageControll2; 83 | } 84 | else{ 85 | bottomControll += pageControll; 86 | } 87 | } 88 | 89 | if(luckysheetConfigsetting.enableAddBackTop){ 90 | bottomControll += backControll; 91 | } 92 | 93 | let flowstr = replaceHtml('
'+ bottomControll +'
', { "height": Store.rh_height, "width": Store.ch_width - 1 }); 94 | 95 | let colsheader = replaceHtml(columnHeaderHTML, { "width": Store.ch_width, "index": 0, "column": "" }); 96 | 97 | flowHTML = replaceHtml(flowHTML, { "width": Store.ch_width, "flow": flowstr, "index": 0 }); 98 | 99 | gh = replaceHtml(gh, { "flow": flowHTML, "rowHeader": "
", "columnHeader": colsheader, "functionButton": luckysheetConfigsetting.functionButton });//设置需要显示的菜单 100 | 101 | $("#" + Store.container).append(gh); 102 | 103 | $("#luckysheet-scrollbar-x div").width(Store.ch_width); 104 | $("#luckysheet-scrollbar-y div").height(Store.rh_height + Store.columnHeaderHeight - Store.cellMainSrollBarSize - 3); 105 | 106 | //新建行菜单 107 | $("body").append(maskHTML); 108 | $("body").append(colsmenuHTML); 109 | $("body").append(rightclickHTML()); 110 | $("body").append(inputHTML); 111 | $("body").append(replaceHtml(filtermenuHTML(), { "menuid": "filter" })); 112 | $("body").append(replaceHtml(filtersubmenuHTML(), { "menuid": "filter" })); 113 | $("body").append(sheetconfigHTML()); 114 | 115 | $("#luckysheet-rows-h").width((Store.rowHeaderWidth-1.5)); 116 | $("#luckysheet-cols-h-c").height((Store.columnHeaderHeight-1.5)); 117 | $("#luckysheet-left-top").css({width:Store.rowHeaderWidth-1.5, height:Store.columnHeaderHeight-1.5}); 118 | 119 | // //批注 120 | // luckysheetPostil.buildAllPs(Store.flowdata); 121 | 122 | $("#luckysheet_info_detail_input").val(luckysheetConfigsetting.title); 123 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/createsheet.js: -------------------------------------------------------------------------------- 1 | import { datagridgrowth } from './getdata'; 2 | import editor from './editor'; 3 | import rhchInit from './rhchInit'; 4 | import formula from './formula'; 5 | import { luckysheetrefreshgrid } from './refresh'; 6 | import sheetmanage from '../controllers/sheetmanage'; 7 | import Store from '../store'; 8 | 9 | export default function luckysheetcreatesheet(colwidth, rowheight, data, cfg, active) { 10 | if(active == null){ 11 | active = true; 12 | } 13 | 14 | Store.visibledatarow = []; 15 | Store.visibledatacolumn = []; 16 | Store.ch_width = 0; 17 | Store.rh_height = 0; 18 | Store.zoomRatio = 1; 19 | 20 | if(cfg != null){ 21 | Store.config = cfg; 22 | } 23 | else{ 24 | Store.config = {}; 25 | } 26 | 27 | if (data.length == 0) { 28 | Store.flowdata = datagridgrowth(data, rowheight, colwidth); 29 | } 30 | else if (data.length < rowheight && data[0].length < colwidth) { 31 | Store.flowdata = datagridgrowth(data, rowheight - data.length, colwidth - data[0].length); 32 | } 33 | else if (data.length < rowheight) { 34 | Store.flowdata = datagridgrowth(data, rowheight - data.length, 0); 35 | } 36 | else if (data[0].length < colwidth) { 37 | Store.flowdata = datagridgrowth(data, 0, colwidth - data[0].length); 38 | } 39 | else { 40 | Store.flowdata = data; 41 | } 42 | 43 | editor.webWorkerFlowDataCache(Store.flowdata);//worker存数据 44 | 45 | rhchInit(rowheight, colwidth); 46 | 47 | if(active){ 48 | sheetmanage.showSheet(); 49 | 50 | setTimeout(function () { 51 | sheetmanage.restoreCache(); 52 | formula.execFunctionGroup(); 53 | sheetmanage.restoreSheetAll(Store.currentSheetIndex); 54 | luckysheetrefreshgrid(); 55 | }, 1); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/cursorPos.js: -------------------------------------------------------------------------------- 1 | import Store from '../store'; 2 | 3 | function luckysheetRangeLast(obj) { 4 | let range; 5 | 6 | if(document.createRange){ //chrome, firefox, opera, safari, ie9+ 7 | if(obj.innerHTML != obj.innerText || obj.innerHTML == ""){ 8 | obj.focus(); //解决ff不获取焦点无法定位问题 9 | range = window.getSelection();//创建range 10 | range.selectAllChildren(obj);//range 选择obj下所有子内容 11 | range.collapseToEnd();//光标移至最后 12 | } 13 | else{ 14 | let len = obj.innerText.length; 15 | 16 | range = document.createRange(); 17 | range.selectNodeContents(obj); 18 | range.setStart(obj.childNodes[0], len); 19 | range.collapse(true); 20 | 21 | let selection = window.getSelection(); 22 | selection.removeAllRanges(); 23 | selection.addRange(range); 24 | } 25 | } 26 | else if(document.selection){ //ie8 and lower 27 | range = document.body.createTextRange(); 28 | range.moveToElementText(obj); 29 | range.collapse(false); 30 | range.select(); 31 | } 32 | } 33 | 34 | function getCursortPosition(textDom){ 35 | let cursorPos = 0; 36 | 37 | if(document.selection){ 38 | textDom.focus(); 39 | let selectRange = document.selection.createRange(); 40 | selectRange.moveStart("character", -textDom.value.length); 41 | cursorPos = selectRange.text.length; 42 | } 43 | else if(textDom.selectionStart || textDom.selectionStart == "0"){ 44 | cursorPos = textDom.selectionStart; 45 | } 46 | 47 | return cursorPos; 48 | } 49 | 50 | function hideMenuByCancel(event){ 51 | 52 | // Right-click the menu in the title bar, and click on the elements whose class is luckysheet-cols-rows-shift-left and luckysheet-cols-rows-shift-right will trigger the hiding of the menu bar. It should be prohibited. Exclude these two elements. There may be more Other elements will also jump here for more testing 53 | 54 | if(event.target.classList.contains('luckysheet-cols-rows-shift-left') || event.target.classList.contains('luckysheet-cols-rows-shift-right')){ 55 | return; 56 | } 57 | 58 | if (!$(event.target).hasClass("luckysheet-mousedown-cancel") && $(event.target).filter("[class*='sp-palette']").length == 0 && $(event.target).filter("[class*='sp-thumb']").length == 0 && $(event.target).filter("[class*='sp-']").length == 0) { 59 | $("#luckysheet-rightclick-menu").hide(); 60 | $("#luckysheet-cols-h-hover").hide(); 61 | $("#luckysheet-cols-menu-btn").hide(); 62 | // $("#luckysheet-rightclick-menu").hide(); 63 | $("#luckysheet-sheet-list, #luckysheet-rightclick-sheet-menu, #luckysheet-user-menu").hide(); 64 | $("body > .luckysheet-filter-menu, body > .luckysheet-filter-submenu, body > .luckysheet-cols-menu").hide(); 65 | //$("body > luckysheet-menuButton").hide(); 66 | Store.luckysheet_cols_menu_status = false; 67 | } 68 | } 69 | 70 | function selectTextDom(ele){ 71 | if (window.getSelection) { 72 | let range = document.createRange(); 73 | range.selectNodeContents(ele); 74 | if(range.startContainer && isInPage(range.startContainer)){ 75 | window.getSelection().removeAllRanges(); 76 | window.getSelection().addRange(range); 77 | } 78 | } 79 | else if (document.selection) { 80 | let range = document.body.createTextRange(); 81 | range.moveToElementText(ele); 82 | range.select(); 83 | } 84 | } 85 | 86 | function selectTextContent(ele){ 87 | if (window.getSelection) { 88 | let range = document.createRange(); 89 | var content=ele.firstChild; 90 | range.setStart(content,0); 91 | range.setEnd(content,content.length); 92 | if(range.startContainer && isInPage(range.startContainer)){ 93 | window.getSelection().removeAllRanges(); 94 | window.getSelection().addRange(range); 95 | } 96 | } 97 | else if (document.selection) { 98 | let range = document.body.createTextRange(); 99 | range.moveToElementText(ele); 100 | range.select(); 101 | } 102 | } 103 | 104 | function selectTextContentCross(sEle, eEle){ 105 | if (window.getSelection) { 106 | let range = document.createRange(); 107 | var sContent=sEle.firstChild, eContent=eEle.firstChild; 108 | range.setStart(sContent,0); 109 | range.setEnd(eContent,eContent.length); 110 | if(range.startContainer && isInPage(range.startContainer)){ 111 | window.getSelection().removeAllRanges(); 112 | window.getSelection().addRange(range); 113 | } 114 | } 115 | } 116 | 117 | function selectTextContentCollapse(sEle, index){ 118 | if (window.getSelection) { 119 | let range = document.createRange(); 120 | var sContent=sEle.firstChild; 121 | if(index>sContent.length){ 122 | index=sContent.length; 123 | } 124 | else if(index<0){ 125 | index = 0; 126 | } 127 | range.setStart(sContent,index); 128 | range.collapse(true); 129 | if(range.startContainer && isInPage(range.startContainer)){ 130 | window.getSelection().removeAllRanges(); 131 | window.getSelection().addRange(range); 132 | } 133 | 134 | } 135 | } 136 | 137 | function isInPage(node) { 138 | return (node === document.body) ? false : document.body.contains(node); 139 | } 140 | 141 | export { 142 | luckysheetRangeLast, 143 | getCursortPosition, 144 | hideMenuByCancel, 145 | selectTextContent, 146 | selectTextDom, 147 | selectTextContentCross, 148 | selectTextContentCollapse 149 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/datecontroll.js: -------------------------------------------------------------------------------- 1 | import { hasChinaword } from './validate'; 2 | import dayjs from 'dayjs' 3 | 4 | function isdatetime(s) { 5 | if (s == null || s.toString().length < 5) { 6 | return false; 7 | } 8 | else if(checkDateTime(s)){ 9 | return true; 10 | } 11 | else { 12 | return false; 13 | } 14 | 15 | function checkDateTime(str){ 16 | var reg1 = /^(\d{4})-(\d{1,2})-(\d{1,2})(\s(\d{1,2}):(\d{1,2})(:(\d{1,2}))?)?$/; 17 | var reg2 = /^(\d{4})\/(\d{1,2})\/(\d{1,2})(\s(\d{1,2}):(\d{1,2})(:(\d{1,2}))?)?$/; 18 | 19 | if(!reg1.test(str) && !reg2.test(str)){ 20 | return false; 21 | } 22 | 23 | var year = RegExp.$1, 24 | month = RegExp.$2, 25 | day = RegExp.$3; 26 | 27 | if(year < 1900){ 28 | return false; 29 | } 30 | 31 | if(month > 12){ 32 | return false; 33 | } 34 | 35 | if(day > 31){ 36 | return false; 37 | } 38 | 39 | if(month == 2){ 40 | if(new Date(year, 1, 29).getDate() == 29 && day > 29){ 41 | return false; 42 | } 43 | else if(new Date(year, 1, 29).getDate() != 29 && day > 28){ 44 | return false; 45 | } 46 | } 47 | 48 | return true; 49 | } 50 | } 51 | 52 | function diff(now, then) { 53 | return dayjs(now).diff(dayjs(then)); 54 | } 55 | 56 | function isdatatypemulti(s) { 57 | let type = {}; 58 | 59 | if (isdatetime(s)) { 60 | type["date"] = true; 61 | } 62 | 63 | if (!isNaN(parseFloat(s)) && !hasChinaword(s)) { 64 | type["num"] = true; 65 | } 66 | 67 | return type; 68 | } 69 | 70 | function isdatatype(s) { 71 | let type = "string"; 72 | 73 | if (isdatetime(s)) { 74 | type = "date"; 75 | } 76 | else if (!isNaN(parseFloat(s)) && !hasChinaword(s)) { 77 | type = "num"; 78 | } 79 | 80 | return type; 81 | } 82 | 83 | export { 84 | isdatetime, 85 | diff, 86 | isdatatypemulti, 87 | isdatatype, 88 | } 89 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/dynamicArray.js: -------------------------------------------------------------------------------- 1 | import { getObjType } from '../utils/util'; 2 | import { getSheetIndex } from '../methods/get'; 3 | import Store from '../store'; 4 | 5 | //动态数组计算 6 | function dynamicArrayCompute(dynamicArray) { 7 | let dynamicArray_compute = {}; 8 | 9 | if(getObjType(dynamicArray) == "array"){ 10 | for(let i = 0; i < dynamicArray.length; i++){ 11 | let d_row = dynamicArray[i].r; 12 | let d_col = dynamicArray[i].c; 13 | let d_f = dynamicArray[i].f; 14 | 15 | if(Store.flowdata[d_row][d_col] != null && Store.flowdata[d_row][d_col].f != null && Store.flowdata[d_row][d_col].f == d_f){ 16 | if((d_row + "_" + d_col) in dynamicArray_compute){ 17 | dynamicArray_compute = dynamicArraySpillEditCompute(dynamicArray_compute, d_row , d_col); 18 | } 19 | 20 | let d_data = dynamicArray[i].data; 21 | let d_rowlen = d_data.length; 22 | let d_collen = 1; 23 | 24 | if(getObjType(d_data[0]) == "array"){ 25 | d_collen = d_data[0].length; 26 | } 27 | 28 | if(dynamicArrayRangeIsAllNull({ "row": [d_row, d_row + d_rowlen - 1], "column": [d_col, d_col + d_collen - 1] }, Store.flowdata)){ 29 | for(let x = 0; x < d_rowlen; x++){ 30 | for(let y = 0; y < d_collen; y++){ 31 | let rowIndex = d_row + x; 32 | let colIndex = d_col + y; 33 | 34 | if(getObjType(d_data[0]) == "array"){ 35 | dynamicArray_compute[rowIndex + "_" + colIndex] = {"v": d_data[x][y], "r": d_row, "c": d_col}; 36 | } 37 | else{ 38 | dynamicArray_compute[rowIndex + "_" + colIndex] = {"v": d_data[x], "r": d_row, "c": d_col}; 39 | } 40 | } 41 | } 42 | } 43 | else{ 44 | dynamicArray_compute[d_row + "_" + d_col] = {"v": "#SPILL!", "r": d_row, "c": d_col}; 45 | } 46 | } 47 | } 48 | } 49 | 50 | return dynamicArray_compute; 51 | } 52 | 53 | function dynamicArraySpillEditCompute(computeObj, r, c) { 54 | let rowIndex = computeObj[r + "_" + c].r; 55 | let colIndex = computeObj[r + "_" + c].c; 56 | 57 | for(let x in computeObj){ 58 | if(x == (rowIndex + "_" + colIndex)){ 59 | computeObj[x].v = "#SPILL!"; 60 | } 61 | else if(computeObj[x].r == rowIndex && computeObj[x].c == colIndex){ 62 | delete computeObj[x]; 63 | } 64 | } 65 | 66 | return computeObj; 67 | } 68 | 69 | //范围是否都是空单元格(除第一个单元格) 70 | function dynamicArrayRangeIsAllNull(range, data) { 71 | let r1 = range["row"][0], r2 = range["row"][1]; 72 | let c1 = range["column"][0], c2 = range["column"][1]; 73 | 74 | let isAllNull = true; 75 | for(let r = r1; r <= r2; r++){ 76 | for(let c = c1; c <= c2; c++){ 77 | if(!(r == r1 && c == c1) && data[r][c] != null && data[r][c].v != null && data[r][c].v.toString() != ""){ 78 | isAllNull = false; 79 | break; 80 | } 81 | } 82 | } 83 | 84 | return isAllNull; 85 | } 86 | 87 | //点击表格区域是否属于动态数组区域 88 | function dynamicArrayHightShow(r, c) { 89 | let dynamicArray = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray"] == null ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["dynamicArray"]; 90 | let dynamicArray_compute = dynamicArrayCompute(dynamicArray); 91 | 92 | if((r + "_" + c) in dynamicArray_compute && dynamicArray_compute[r + "_" + c].v != "#SPILL!"){ 93 | let d_row = dynamicArray_compute[r + "_" + c].r; 94 | let d_col = dynamicArray_compute[r + "_" + c].c; 95 | 96 | let d_f = Store.flowdata[d_row][d_col].f; 97 | 98 | let rlen, clen; 99 | for(let i = 0; i < dynamicArray.length; i++){ 100 | if(dynamicArray[i].f == d_f){ 101 | rlen = dynamicArray[i].data.length; 102 | 103 | if(getObjType(dynamicArray[i].data[0]) == "array"){ 104 | clen = dynamicArray[i].data[0].length; 105 | } 106 | else{ 107 | clen = 1; 108 | } 109 | } 110 | } 111 | 112 | let d_row_end = d_row + rlen - 1; 113 | let d_col_end = d_col + clen - 1; 114 | 115 | let row = Store.visibledatarow[d_row_end], 116 | row_pre = d_row - 1 == -1 ? 0 : Store.visibledatarow[d_row - 1]; 117 | let col = Store.visibledatacolumn[d_col_end], 118 | col_pre = d_col - 1 == -1 ? 0 : Store.visibledatacolumn[d_col - 1]; 119 | 120 | $("#luckysheet-dynamicArray-hightShow").css({ 121 | "left": col_pre, 122 | "width": col - col_pre - 1, 123 | "top": row_pre, 124 | "height": row - row_pre - 1, 125 | "display": "block" 126 | }); 127 | } 128 | else{ 129 | $("#luckysheet-dynamicArray-hightShow").hide(); 130 | } 131 | } 132 | 133 | export { 134 | dynamicArrayCompute, 135 | dynamicArraySpillEditCompute, 136 | dynamicArrayRangeIsAllNull, 137 | dynamicArrayHightShow, 138 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/editor.js: -------------------------------------------------------------------------------- 1 | import browser from './browser'; 2 | import formula from './formula'; 3 | import { datagridgrowth } from './getdata'; 4 | import { jfrefreshgrid, jfrefreshgridall, jfrefreshrange } from './refresh'; 5 | import { getSheetIndex } from '../methods/get'; 6 | import Store from '../store'; 7 | 8 | const editor = { 9 | //worker+blob实现深拷贝替换extend 10 | deepCopyFlowDataState:false, 11 | deepCopyFlowDataCache:"", 12 | deepCopyFlowDataWorker:null, 13 | deepCopyFlowData:function(flowData){ 14 | let _this = this; 15 | 16 | if(_this.deepCopyFlowDataState){ 17 | if(_this.deepCopyFlowDataWorker != null){ 18 | _this.deepCopyFlowDataWorker.terminate(); 19 | } 20 | return _this.deepCopyFlowDataCache; 21 | } 22 | else{ 23 | if(flowData == null){ 24 | flowData = Store.flowdata; 25 | } 26 | 27 | return $.extend(true, [], flowData); 28 | } 29 | }, 30 | webWorkerFlowDataCache:function(flowData){ 31 | let _this = this; 32 | 33 | try{ 34 | if(_this.deepCopyFlowDataWorker != null){//存新的webwork前先销毁以前的 35 | _this.deepCopyFlowDataWorker.terminate(); 36 | } 37 | 38 | let funcTxt = 'data:text/javascript;chartset=US-ASCII,onmessage = function (e) { postMessage(e.data); };'; 39 | _this.deepCopyFlowDataState = false; 40 | 41 | //适配IE 42 | let worker; 43 | if(browser.isIE() == 1){ 44 | let response = "self.onmessage=function(e){postMessage(e.data);}"; 45 | worker = new Worker('./plugins/Worker-helper.js'); 46 | worker.postMessage(response); 47 | } 48 | else{ 49 | worker = new Worker(funcTxt); 50 | } 51 | 52 | _this.deepCopyFlowDataWorker = worker; 53 | worker.postMessage(flowData); 54 | worker.onmessage = function(e) { 55 | _this.deepCopyFlowDataCache = e.data; 56 | _this.deepCopyFlowDataState = true; 57 | }; 58 | } 59 | catch(e){ 60 | _this.deepCopyFlowDataCache = $.extend(true, [], flowData); 61 | } 62 | }, 63 | 64 | /** 65 | * @param {Array} dataChe 66 | * @param {Object} range 是否指定选区,默认为当前选区 67 | * @since Add range parameter. Update by siwei@2020-09-10. 68 | */ 69 | controlHandler: function (dataChe, range) { 70 | let _this = this; 71 | 72 | let d = _this.deepCopyFlowData(Store.flowdata);//取数据 73 | 74 | // let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; 75 | let last = range || Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; 76 | let curR = last["row"] == null ? 0 : last["row"][0]; 77 | let curC = last["column"] == null ? 0 : last["column"][0]; 78 | let rlen = dataChe.length, clen = dataChe[0].length; 79 | 80 | let addr = curR + rlen - d.length, addc = curC + clen - d[0].length; 81 | if(addr > 0 || addc > 0){ 82 | d = datagridgrowth([].concat(d), addr, addc, true); 83 | } 84 | 85 | for (let r = 0; r < rlen; r++) { 86 | let x = [].concat(d[r + curR]); 87 | for (let c = 0; c < clen; c++) { 88 | let value = ""; 89 | if (dataChe[r] != null && dataChe[r][c] != null) { 90 | value = dataChe[r][c]; 91 | } 92 | x[c + curC] = value; 93 | } 94 | d[r + curR] = x; 95 | } 96 | 97 | if (addr > 0 || addc > 0) { 98 | jfrefreshgridall(d[0].length, d.length, d, null, Store.luckysheet_select_save, "datachangeAll"); 99 | } 100 | else { 101 | jfrefreshrange(d, Store.luckysheet_select_save); 102 | } 103 | }, 104 | clearRangeByindex: function (st_r, ed_r, st_c, ed_c, sheetIndex) { 105 | let index = getSheetIndex(sheetIndex); 106 | let d = $.extend(true, [], Store.luckysheetfile[index]["data"]); 107 | 108 | for (let r = st_r; r <= ed_r; r++) { 109 | let x = [].concat(d[r]); 110 | for (let c = st_c; c <= ed_c; c++) { 111 | formula.delFunctionGroup(r, c); 112 | formula.execFunctionGroup(r, c, ""); 113 | x[c] = null; 114 | } 115 | d[r] = x; 116 | } 117 | 118 | if(sheetIndex == Store.currentSheetIndex){ 119 | let rlen = ed_r - st_r + 1, 120 | clen = ed_c - st_c + 1; 121 | 122 | if (rlen > 5000) { 123 | jfrefreshgrid(d, [{ "row": [st_r, ed_r], "column": [st_c, ed_c] }]); 124 | } 125 | else { 126 | jfrefreshrange(d, { "row": [st_r, ed_r], "column": [st_c, ed_c] }); 127 | } 128 | } 129 | else{ 130 | Store.luckysheetfile[index]["data"] = d; 131 | } 132 | }, 133 | controlHandlerD: function (dataChe) { 134 | let _this = this; 135 | 136 | let d = _this.deepCopyFlowData(Store.flowdata);//取数据 137 | 138 | let last = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1]; 139 | let r1 = last["row"][0], r2 = last["row"][1]; 140 | let c1 = last["column"][0], c2 = last["column"][1]; 141 | let rlen = dataChe.length, clen = dataChe[0].length; 142 | 143 | let addr = r1 + rlen - d.length, addc = c1 + clen - d[0].length; 144 | if(addr >0 || addc > 0){ 145 | d = datagridgrowth([].concat(d), addr, addc, true); 146 | } 147 | 148 | for(let r = r1; r <= r2; r++){ 149 | for(let c = c1; c <= c2; c++){ 150 | d[r][c] = null; 151 | } 152 | } 153 | 154 | for(let i = 0; i < rlen; i++){ 155 | for(let j = 0; j < clen; j++){ 156 | d[r1 + i][c1 + j] = dataChe[i][j]; 157 | } 158 | } 159 | 160 | let range = [ 161 | { "row": [r1, r2], "column": [c1, c2] }, 162 | { "row": [r1, r1 + rlen - 1], "column": [c1, c1 + clen - 1] } 163 | ]; 164 | 165 | jfrefreshgrid(d, range); 166 | } 167 | }; 168 | 169 | export default editor; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/json.js: -------------------------------------------------------------------------------- 1 | import { getObjType } from '../utils/util'; 2 | 3 | const json = { 4 | parseJsonParm: function(obj){ 5 | if(obj == null){ 6 | return {}; 7 | } 8 | else if(getObjType(obj) == "string"){ 9 | try { 10 | let json = new Function("return " + obj)(); 11 | return json; 12 | } 13 | catch(e) { 14 | return {}; 15 | } 16 | } 17 | else{ 18 | return obj; 19 | } 20 | }, 21 | hasKey: function(obj){ 22 | let _this = this; 23 | let json = _this.parseJsonParm(obj); 24 | 25 | for(let item in json){ 26 | return true; 27 | } 28 | 29 | return false; 30 | } 31 | } 32 | 33 | export default json; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/loading.js: -------------------------------------------------------------------------------- 1 | export function showloading(txt) { 2 | $("#luckysheet-cell-loading").find("span").text(txt).end().show(); 3 | }; 4 | 5 | export function hideloading() { 6 | $("#luckysheet-cell-loading").hide(); 7 | }; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/location.js: -------------------------------------------------------------------------------- 1 | import { luckysheet_searcharray } from '../controllers/sheetSearch'; 2 | import Store from '../store'; 3 | 4 | function rowLocationByIndex(row_index) { 5 | let row = 0, row_pre = 0; 6 | row = Store.visibledatarow[row_index]; 7 | 8 | if (row_index == 0) { 9 | row_pre = 0; 10 | } 11 | else { 12 | row_pre = Store.visibledatarow[row_index - 1]; 13 | } 14 | 15 | return [row_pre, row, row_index]; 16 | } 17 | 18 | function rowLocation(y) { 19 | let row_index = luckysheet_searcharray(Store.visibledatarow, y); 20 | 21 | if (row_index == -1 && y > 0) { 22 | row_index = Store.visibledatarow.length - 1; 23 | } 24 | else if (row_index == -1 && y <= 0) { 25 | row_index = 0; 26 | } 27 | 28 | return rowLocationByIndex(row_index); 29 | } 30 | 31 | function colLocationByIndex(col_index){ 32 | let col = 0, col_pre = 0; 33 | col = Store.visibledatacolumn[col_index]; 34 | 35 | if (col_index == 0) { 36 | col_pre = 0; 37 | } 38 | else { 39 | col_pre = Store.visibledatacolumn[col_index - 1]; 40 | } 41 | 42 | return [col_pre, col, col_index]; 43 | } 44 | 45 | function colLocation(x) { 46 | let col_index = luckysheet_searcharray(Store.visibledatacolumn, x); 47 | 48 | if (col_index == -1 && x > 0) { 49 | col_index = Store.visibledatacolumn.length - 1; 50 | } 51 | else if (col_index == -1 && x <= 0) { 52 | col_index = 0; 53 | } 54 | 55 | return colLocationByIndex(col_index); 56 | } 57 | 58 | function mouseposition(x, y) { 59 | let container_offset = $("#" + Store.container).offset(); 60 | 61 | let newX = x - container_offset.left - Store.rowHeaderWidth, 62 | newY = y - container_offset.top - Store.infobarHeight - Store.toolbarHeight - Store.calculatebarHeight - Store.columnHeaderHeight; 63 | 64 | return [newX, newY]; 65 | } 66 | 67 | export { 68 | rowLocationByIndex, 69 | rowLocation, 70 | colLocationByIndex, 71 | colLocation, 72 | mouseposition, 73 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/rhchInit.js: -------------------------------------------------------------------------------- 1 | import Store from '../store'; 2 | import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting'; 3 | 4 | export default function rhchInit(rowheight, colwidth) { 5 | zoomSetting();//Zoom sheet on first load 6 | //行高 7 | if(rowheight != null){ 8 | Store.visibledatarow = []; 9 | Store.rh_height = 0; 10 | 11 | for (let r = 0; r < rowheight; r++) { 12 | let rowlen = Store.defaultrowlen; 13 | 14 | if (Store.config["rowlen"] != null && Store.config["rowlen"][r] != null) { 15 | rowlen = Store.config["rowlen"][r]; 16 | } 17 | 18 | if (Store.config["rowhidden"] != null && Store.config["rowhidden"][r] != null) { 19 | Store.visibledatarow.push(Store.rh_height); 20 | continue; 21 | } 22 | 23 | Store.rh_height += Math.round((rowlen + 1) * Store.zoomRatio); 24 | 25 | Store.visibledatarow.push(Store.rh_height); //行的临时长度分布 26 | } 27 | 28 | // 如果增加行和回到顶部按钮隐藏,则减少底部空白区域,但是预留足够空间给单元格下拉按钮 29 | if(!luckysheetConfigsetting.enableAddRow && !luckysheetConfigsetting.enableAddBackTop){ 30 | Store.rh_height += 29; 31 | }else{ 32 | Store.rh_height += 80; //最底部增加空白 33 | } 34 | 35 | } 36 | 37 | //列宽 38 | if(colwidth != null){ 39 | Store.visibledatacolumn = []; 40 | Store.ch_width = 0; 41 | 42 | let maxColumnlen = 120; 43 | 44 | for (let c = 0; c < colwidth; c++) { 45 | let firstcolumnlen = Store.defaultcollen; 46 | 47 | if (Store.config["columnlen"] != null && Store.config["columnlen"][c] != null) { 48 | firstcolumnlen = Store.config["columnlen"][c]; 49 | } 50 | else { 51 | if (Store.flowdata[0] != null && Store.flowdata[0][c] != null) { 52 | if (firstcolumnlen > 300) { 53 | firstcolumnlen = 300; 54 | } 55 | else if (firstcolumnlen < Store.defaultcollen) { 56 | firstcolumnlen = Store.defaultcollen; 57 | } 58 | 59 | if (firstcolumnlen != Store.defaultcollen) { 60 | if (Store.config["columnlen"] == null) { 61 | Store.config["columnlen"] = {}; 62 | } 63 | 64 | Store.config["columnlen"][c] = firstcolumnlen; 65 | } 66 | } 67 | } 68 | 69 | if(Store.config["colhidden"] != null && Store.config["colhidden"][c] != null){ 70 | Store.visibledatacolumn.push(Store.ch_width); 71 | continue; 72 | } 73 | 74 | Store.ch_width += Math.round((firstcolumnlen + 1)*Store.zoomRatio); 75 | 76 | Store.visibledatacolumn.push(Store.ch_width);//列的临时长度分布 77 | 78 | // if(maxColumnlen < firstcolumnlen + 1){ 79 | // maxColumnlen = firstcolumnlen + 1; 80 | // } 81 | } 82 | 83 | // Store.ch_width += 120; 84 | Store.ch_width += maxColumnlen; 85 | } 86 | } 87 | 88 | 89 | export function zoomSetting(){ 90 | //zoom 91 | Store.rowHeaderWidth = luckysheetConfigsetting.rowHeaderWidth * Store.zoomRatio; 92 | Store.columnHeaderHeight = luckysheetConfigsetting.columnHeaderHeight *Store.zoomRatio; 93 | $("#luckysheet-rows-h").width((Store.rowHeaderWidth-1.5)); 94 | $("#luckysheet-cols-h-c").height((Store.columnHeaderHeight-1.5)); 95 | $("#luckysheet-left-top").css({width:Store.rowHeaderWidth-1.5, height:Store.columnHeaderHeight-1.5}); 96 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/scroll.js: -------------------------------------------------------------------------------- 1 | import luckysheetFreezen from '../controllers/freezen'; 2 | import { luckysheet_searcharray } from '../controllers/sheetSearch'; 3 | import { luckysheetrefreshgrid } from '../global/refresh'; 4 | import Store from '../store'; 5 | import method from '../global/method' 6 | 7 | let scrollRequestAnimationFrameIni = true,scrollRequestAnimationFrame = false, scrollTimeOutCancel=null; 8 | 9 | function execScroll(){ 10 | let scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft(), 11 | scrollTop = $("#luckysheet-scrollbar-y").scrollTop(); 12 | luckysheetrefreshgrid(scrollLeft, scrollTop); 13 | scrollRequestAnimationFrame = window.requestAnimationFrame(execScroll); 14 | } 15 | 16 | //全局滚动事件 17 | export default function luckysheetscrollevent(isadjust) { 18 | let $t = $("#luckysheet-cell-main"); 19 | let scrollLeft = $("#luckysheet-scrollbar-x").scrollLeft(), 20 | scrollTop = $("#luckysheet-scrollbar-y").scrollTop(), 21 | canvasHeight = $("#luckysheetTableContent").height(); // canvas高度 22 | 23 | // clearTimeout(scrollTimeOutCancel); 24 | 25 | // scrollTimeOutCancel = setTimeout(() => { 26 | // scrollRequestAnimationFrameIni = true; 27 | // window.cancelAnimationFrame(scrollRequestAnimationFrame); 28 | // }, 500); 29 | 30 | // if (!!isadjust) { 31 | // let scrollHeight = $t.get(0).scrollHeight; 32 | // let windowHeight = $t.height(); 33 | // let scrollWidth = $t.get(0).scrollWidth; 34 | // let windowWidth = $t.width(); 35 | 36 | // let maxScrollLeft = scrollWidth - windowWidth; 37 | // let maxScrollTop = scrollHeight - windowHeight; 38 | 39 | // let visibledatacolumn_c = Store.visibledatacolumn, visibledatarow_c = Store.visibledatarow; 40 | 41 | // if (luckysheetFreezen.freezenhorizontaldata != null) { 42 | // visibledatarow_c = luckysheetFreezen.freezenhorizontaldata[3]; 43 | // } 44 | 45 | // if (luckysheetFreezen.freezenverticaldata != null) { 46 | // visibledatacolumn_c = luckysheetFreezen.freezenverticaldata[3]; 47 | // } 48 | 49 | // let col_ed = luckysheet_searcharray(visibledatacolumn_c, scrollLeft); 50 | // let row_ed = luckysheet_searcharray(visibledatarow_c, scrollTop); 51 | 52 | // let refreshLeft = scrollLeft , refreshTop = scrollTop; 53 | 54 | // if (col_ed <= 0) { 55 | // scrollLeft = 0; 56 | // } 57 | // else { 58 | // scrollLeft = visibledatacolumn_c[col_ed - 1]; 59 | // } 60 | 61 | // if (row_ed <= 0) { 62 | // scrollTop = 0; 63 | // } 64 | // else { 65 | // scrollTop = visibledatarow_c[row_ed - 1]; 66 | // } 67 | // } 68 | 69 | if (luckysheetFreezen.freezenhorizontaldata != null) { 70 | if (scrollTop < luckysheetFreezen.freezenhorizontaldata[2]) { 71 | scrollTop = luckysheetFreezen.freezenhorizontaldata[2]; 72 | $("#luckysheet-scrollbar-y").scrollTop(scrollTop); 73 | return; 74 | } 75 | } 76 | 77 | if (luckysheetFreezen.freezenverticaldata != null) { 78 | if (scrollLeft < luckysheetFreezen.freezenverticaldata[2]) { 79 | scrollLeft = luckysheetFreezen.freezenverticaldata[2]; 80 | $("#luckysheet-scrollbar-x").scrollLeft(scrollLeft); 81 | return; 82 | } 83 | } 84 | 85 | $("#luckysheet-cols-h-c").scrollLeft(scrollLeft);//列标题 86 | $("#luckysheet-rows-h").scrollTop(scrollTop);//行标题 87 | 88 | $t.scrollLeft(scrollLeft).scrollTop(scrollTop); 89 | 90 | $("#luckysheet-input-box-index").css({ 91 | "left": $("#luckysheet-input-box").css("left"), 92 | "top": (parseInt($("#luckysheet-input-box").css("top")) - 20) + "px", 93 | "z-index": $("#luckysheet-input-box").css("z-index") 94 | }).show(); 95 | 96 | // if(scrollRequestAnimationFrameIni && Store.scrollRefreshSwitch){ 97 | // execScroll(); 98 | // scrollRequestAnimationFrameIni = false; 99 | // } 100 | 101 | luckysheetrefreshgrid(scrollLeft, scrollTop); 102 | 103 | 104 | $("#luckysheet-bottom-controll-row").css("left", scrollLeft); 105 | 106 | //有选区且有冻结时,滚动适应 107 | if(luckysheetFreezen.freezenhorizontaldata != null || luckysheetFreezen.freezenverticaldata != null){ 108 | luckysheetFreezen.scrollAdapt(); 109 | } 110 | 111 | if(!method.createHookFunction("scroll", {scrollLeft, scrollTop, canvasHeight})){ return; } 112 | 113 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/global/validate.js: -------------------------------------------------------------------------------- 1 | import luckysheetConfigsetting from '../controllers/luckysheetConfigsetting'; 2 | import Store from '../store'; 3 | 4 | export const error = { 5 | v: "#VALUE!", //错误的参数或运算符 6 | n: "#NAME?", //公式名称错误 7 | na: "#N/A", //函数或公式中没有可用数值 8 | r: "#REF!", //删除了由其他公式引用的单元格 9 | d: "#DIV/0!", //除数是0或空单元格 10 | nm: "#NUM!", //当公式或函数中某个数字有问题时 11 | nl: "#NULL!", //交叉运算符(空格)使用不正确 12 | sp: "#SPILL!" //数组范围有其它值 13 | } 14 | 15 | //是否是空值 16 | function isRealNull(val) { 17 | if(val == null || val.toString().replace(/\s/g, "") == ""){ 18 | return true; 19 | } 20 | else{ 21 | return false; 22 | } 23 | } 24 | 25 | //是否是纯数字 26 | function isRealNum(val) { 27 | if(val == null || val.toString().replace(/\s/g, "") === ""){ 28 | return false; 29 | } 30 | 31 | if(typeof val == "boolean"){ 32 | return false; 33 | } 34 | 35 | if(!isNaN(val)){ 36 | return true; 37 | } 38 | else{ 39 | return false; 40 | } 41 | } 42 | 43 | //是否是错误类型 44 | function valueIsError(value) { 45 | let isError = false; 46 | 47 | for(let x in error){ 48 | if(value == error[x]){ 49 | isError = true; 50 | break; 51 | } 52 | } 53 | 54 | return isError; 55 | } 56 | 57 | //是否有中文 58 | function hasChinaword(s) { 59 | let patrn = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi; 60 | 61 | if (!patrn.exec(s)) { 62 | return false; 63 | } 64 | else { 65 | return true; 66 | } 67 | } 68 | 69 | //是否为非编辑模式 70 | function isEditMode() { 71 | if(luckysheetConfigsetting.editMode){ 72 | return true; 73 | } 74 | else{ 75 | return false; 76 | } 77 | } 78 | 79 | //范围是否只包含部分合并单元格 80 | function hasPartMC(cfg, r1, r2, c1, c2) { 81 | let hasPartMC = false; 82 | 83 | for(let x in Store.config["merge"]){ 84 | let mc = cfg["merge"][x]; 85 | 86 | if(r1 < mc.r){ 87 | if(r2 >= mc.r && r2 < (mc.r + mc.rs - 1)){ 88 | if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){ 89 | hasPartMC = true; 90 | break; 91 | } 92 | else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){ 93 | hasPartMC = true; 94 | break; 95 | } 96 | else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){ 97 | hasPartMC = true; 98 | break; 99 | } 100 | } 101 | else if(r2 >= mc.r && r2 == (mc.r + mc.rs - 1)){ 102 | if(c1 > mc.c && c1 < (mc.c + mc.cs - 1)){ 103 | hasPartMC = true; 104 | break; 105 | } 106 | else if(c2 > mc.c && c2 < (mc.c + mc.cs - 1)){ 107 | hasPartMC = true; 108 | break; 109 | } 110 | else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){ 111 | hasPartMC = true; 112 | break; 113 | } 114 | else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){ 115 | hasPartMC = true; 116 | break; 117 | } 118 | } 119 | else if(r2 > (mc.r + mc.rs - 1)){ 120 | if(c1 > mc.c && c1 <= (mc.c + mc.cs - 1)){ 121 | hasPartMC = true; 122 | break; 123 | } 124 | else if(c2 >= mc.c && c2 < (mc.c + mc.cs - 1)){ 125 | hasPartMC = true; 126 | break; 127 | } 128 | else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){ 129 | hasPartMC = true; 130 | break; 131 | } 132 | else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){ 133 | hasPartMC = true; 134 | break; 135 | } 136 | } 137 | } 138 | else if(r1 == mc.r){ 139 | if(r2 < (mc.r + mc.rs - 1)){ 140 | if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){ 141 | hasPartMC = true; 142 | break; 143 | } 144 | else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){ 145 | hasPartMC = true; 146 | break; 147 | } 148 | else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){ 149 | hasPartMC = true; 150 | break; 151 | } 152 | } 153 | else if(r2 >= (mc.r + mc.rs - 1)){ 154 | if(c1 > mc.c && c1 <= (mc.c + mc.cs - 1)){ 155 | hasPartMC = true; 156 | break; 157 | } 158 | else if(c2 >= mc.c && c2 < (mc.c + mc.cs - 1)){ 159 | hasPartMC = true; 160 | break; 161 | } 162 | else if(c1 == mc.c && c2 < (mc.c + mc.cs - 1)){ 163 | hasPartMC = true; 164 | break; 165 | } 166 | else if(c1 > mc.c && c2 == (mc.c + mc.cs - 1)){ 167 | hasPartMC = true; 168 | break; 169 | } 170 | } 171 | } 172 | else if(r1 <= (mc.r + mc.rs - 1)){ 173 | if(c1 >= mc.c && c1 <= (mc.c + mc.cs - 1)){ 174 | hasPartMC = true; 175 | break; 176 | } 177 | else if(c2 >= mc.c && c2 <= (mc.c + mc.cs - 1)){ 178 | hasPartMC = true; 179 | break; 180 | } 181 | else if(c1 < mc.c && c2 > (mc.c + mc.cs - 1)){ 182 | hasPartMC = true; 183 | break; 184 | } 185 | } 186 | } 187 | 188 | return hasPartMC; 189 | } 190 | 191 | //获取单个字符的字节数 192 | function checkWordByteLength(value) { 193 | return Math.ceil(value.charCodeAt().toString(2).length / 8); 194 | } 195 | 196 | 197 | export { 198 | isRealNull, 199 | isRealNum, 200 | valueIsError, 201 | hasChinaword, 202 | isEditMode, 203 | hasPartMC, 204 | checkWordByteLength 205 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/index.js: -------------------------------------------------------------------------------- 1 | import './utils/math' 2 | import { luckysheet } from './core' 3 | import __firefox from './utils/polyfill' 4 | // Prevent gulp warning: 'Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification' 5 | // window.evall = window.eval; 6 | // polyfill event in firefox 7 | if(window.addEventListener && (navigator.userAgent.indexOf("Firefox") > 0)){ 8 | __firefox(); 9 | } 10 | 11 | export default luckysheet; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/locale/locale.js: -------------------------------------------------------------------------------- 1 | import en from './en' 2 | import zh from './zh' 3 | import es from './es' 4 | import zh_tw from './zh_tw' 5 | import Store from '../store'; 6 | 7 | const localeObj = {en,zh,es,zh_tw} 8 | 9 | function locale(){ 10 | return localeObj[Store.lang]; 11 | } 12 | 13 | export default locale; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/methods/get.js: -------------------------------------------------------------------------------- 1 | import { chatatABC } from '../utils/util'; 2 | import Store from '../store'; 3 | 4 | function getSheetIndex(index) { 5 | for (let i = 0; i < Store.luckysheetfile.length; i++) { 6 | if (Store.luckysheetfile[i]["index"] == index) { 7 | return i; 8 | } 9 | } 10 | 11 | return null; 12 | } 13 | 14 | function getRangetxt(sheetIndex, range, currentIndex) { 15 | let sheettxt = ""; 16 | 17 | if (currentIndex == null) { 18 | currentIndex = Store.currentSheetIndex; 19 | } 20 | 21 | if (sheetIndex != currentIndex) { 22 | //sheet名字包含'的,引用时应该替换为'' 23 | sheettxt = Store.luckysheetfile[getSheetIndex(sheetIndex)].name.replace(/'/g,"''"); 24 | //如果包含除a-z、A-Z、0-9、下划线等以外的字符那么就用单引号包起来 25 | if(/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/.test(sheettxt)) 26 | { 27 | sheettxt = sheettxt+"!"; 28 | } 29 | else 30 | { 31 | sheettxt="'"+sheettxt+"'!"; 32 | } 33 | } 34 | 35 | let row0 = range["row"][0], row1 = range["row"][1]; 36 | let column0 = range["column"][0], column1 = range["column"][1]; 37 | 38 | if (row0 == null && row1 == null) { 39 | return sheettxt + chatatABC(column0) + ":" + chatatABC(column1); 40 | } 41 | else if (column0 == null && column1 == null) { 42 | return sheettxt + (row0 + 1) + ":" + (row1 + 1); 43 | } 44 | else { 45 | if (column0 == column1 && row0 == row1) { 46 | return sheettxt + chatatABC(column0) + (row0 + 1); 47 | } 48 | else { 49 | return sheettxt + chatatABC(column0) + (row0 + 1) + ":" + chatatABC(column1) + (row1 + 1); 50 | } 51 | } 52 | } 53 | 54 | function getluckysheet_select_save() { 55 | return Store.luckysheet_select_save; 56 | } 57 | 58 | function getluckysheet_scroll_status() { 59 | return Store.luckysheet_scroll_status; 60 | } 61 | 62 | function getluckysheetfile(plugin) { 63 | // 获取图表数据 64 | if(plugin){ 65 | Store.luckysheetfile.forEach(file => { 66 | if(!!file.chart){ 67 | file.chart.forEach((chartObj)=>{ 68 | const chartJson = Store.getChartJson(chartObj.chart_id); 69 | chartObj.chartOptions = chartJson; 70 | }) 71 | } 72 | }); 73 | } 74 | 75 | return Store.luckysheetfile; 76 | } 77 | 78 | function getconfig() { 79 | return Store.config; 80 | } 81 | 82 | function getvisibledatarow() { 83 | return Store.visibledatarow; 84 | } 85 | 86 | function getvisibledatacolumn() { 87 | return Store.visibledatacolumn; 88 | } 89 | 90 | export { 91 | getSheetIndex, 92 | getRangetxt, 93 | getluckysheet_select_save, 94 | getluckysheet_scroll_status, 95 | getluckysheetfile, 96 | getconfig, 97 | getvisibledatarow, 98 | getvisibledatacolumn, 99 | } 100 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/methods/set.js: -------------------------------------------------------------------------------- 1 | import { getSheetIndex } from '../methods/get'; 2 | import Store from '../store'; 3 | 4 | function setluckysheet_select_save(v) { 5 | Store.luckysheet_select_save = v; 6 | } 7 | 8 | function setluckysheet_scroll_status(v) { 9 | Store.luckysheet_scroll_status = v; 10 | } 11 | 12 | function setluckysheetfile(d) { 13 | Store.luckysheetfile = d; 14 | } 15 | 16 | function setconfig(v) { 17 | Store.config = v; 18 | 19 | if(Store.luckysheetfile != null){ 20 | Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config = v; 21 | } 22 | } 23 | 24 | function setvisibledatarow(v) { 25 | Store.visibledatarow = v; 26 | 27 | if(Store.luckysheetfile != null){ 28 | Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].visibledatarow = v; 29 | } 30 | } 31 | 32 | function setvisibledatacolumn(v) { 33 | Store.visibledatacolumn = v; 34 | 35 | if(Store.luckysheetfile != null){ 36 | Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].visibledatacolumn = v; 37 | } 38 | } 39 | 40 | export { 41 | setluckysheet_select_save, 42 | setluckysheet_scroll_status, 43 | setluckysheetfile, 44 | setconfig, 45 | setvisibledatarow, 46 | setvisibledatacolumn, 47 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/CFcolorGradation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/CFcolorGradation.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/CFdataBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/CFdataBar.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/CFicons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/CFicons.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/icon_dropCell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/icon_dropCell.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/js.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/Luckysheet-master/src/plugins/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/jquery.sPage.css: -------------------------------------------------------------------------------- 1 | .spage-total { 2 | display: inline-block; 3 | margin-right: 10px; 4 | line-height: 29px; 5 | color: #666; 6 | font-size: 14px 7 | } 8 | 9 | .spage-number { 10 | display: inline-block; 11 | color: #666; 12 | font-size: 14px 13 | } 14 | .selectNum { 15 | font-size: 14px; 16 | height: 27px; 17 | box-sizing: border-box; 18 | vertical-align: top; 19 | line-height: 27px; 20 | border: 1px solid #ddd; 21 | margin-left: 5px; 22 | vertical-align: middle; 23 | } 24 | .spage-number button { 25 | position: relative; 26 | box-sizing: border-box; 27 | display: inline-block; 28 | margin-left: -1px; 29 | padding: 0 10px; 30 | line-height: 27px; 31 | border: 1px solid #ddd; 32 | text-align: center; 33 | transition: all .2s; 34 | cursor: pointer; 35 | outline: none; 36 | background: 0 0; 37 | user-select: none; 38 | color: #333; 39 | background: #fff; 40 | vertical-align: middle; 41 | } 42 | .prevBtn, .nextBtn { 43 | width: 16px; 44 | height: 27px; 45 | background: url(images/js.png) no-repeat center center; 46 | background-size: 100% auto; 47 | display: block; 48 | transform: rotate(180deg); 49 | } 50 | .nextBtn { 51 | transform: rotate(0); 52 | } 53 | .spage-number button.active { 54 | background: #2d98e6; 55 | color: #fff; 56 | border-color: #2d98e6; 57 | z-index: 3 58 | } 59 | 60 | .spage-number button.active:hover { 61 | background: #2d98e6; 62 | color: #fff; 63 | border-color: #2d98e6; 64 | z-index: 3 65 | } 66 | 67 | .spage-number button:hover { 68 | background-color: #eee 69 | } 70 | 71 | .spage-number button.button-disabled { 72 | cursor: not-allowed; 73 | color: #ccc 74 | } 75 | 76 | .spage-number .spage-after, 77 | .spage-before { 78 | padding: 0; 79 | width: 40px 80 | } 81 | 82 | .spage-skip { 83 | display: inline-block; 84 | margin-left: 5px; 85 | line-height: 27px; 86 | color: #666; 87 | font-size: 14px 88 | } 89 | 90 | .spage-skip input { 91 | box-sizing: border-box; 92 | display: inline-block; 93 | width: 45px; 94 | height: 29px; 95 | text-align: center; 96 | vertical-align: top; 97 | border: 1px solid #ddd; 98 | background: 0 0; 99 | outline: none; 100 | transition: all .2s 101 | } 102 | 103 | .spage-skip input:focus { 104 | border-color: #2d98e6 105 | } 106 | 107 | .spage-skip button { 108 | display: inline-block; 109 | padding: 0 14px; 110 | line-height: 27px; 111 | vertical-align: top; 112 | color: #333; 113 | border: 1px solid #ddd; 114 | cursor: pointer; 115 | transition: all .2s; 116 | outline: none; 117 | background: 0 0; 118 | user-select: none; 119 | background-color: #fff; 120 | } 121 | 122 | .spage-skip button:hover { 123 | background: #2d98e6; 124 | color: #fff; 125 | border: 1px solid #2d98e6 126 | } 127 | 128 | 129 | -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/plugins/js/jquery.mousewheel.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Mousewheel 3.1.13 3 | * 4 | * Copyright 2015 jQuery Foundation and other contributors 5 | * Released under the MIT license. 6 | * http://jquery.org/license 7 | */ 8 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}); -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/store/index.js: -------------------------------------------------------------------------------- 1 | const Store = { 2 | container: null, 3 | loadingObj:{}, 4 | luckysheetfile: null, 5 | defaultcolumnNum: 60, 6 | defaultrowNum: 84, 7 | fullscreenmode: true, 8 | devicePixelRatio: 1, 9 | 10 | currentSheetIndex: 0, 11 | calculateSheetIndex: 0, 12 | flowdata: [], 13 | config: {}, 14 | 15 | visibledatarow: [], 16 | visibledatacolumn: [], 17 | ch_width: 0, 18 | rh_height: 0, 19 | 20 | cellmainWidth: 0, 21 | cellmainHeight: 0, 22 | toolbarHeight: 0, 23 | infobarHeight: 0, 24 | calculatebarHeight: 0, 25 | rowHeaderWidth: 46, 26 | columnHeaderHeight: 20, 27 | cellMainSrollBarSize: 12, 28 | sheetBarHeight: 31, 29 | statisticBarHeight: 23, 30 | luckysheetTableContentHW: [0, 0], 31 | 32 | defaultcollen: 73, 33 | defaultrowlen: 19, 34 | 35 | jfcountfuncTimeout: null, 36 | jfautoscrollTimeout: null, 37 | 38 | luckysheet_select_status: false, 39 | luckysheet_select_save: [{ "row": [0, 0], "column": [0, 0] }], 40 | luckysheet_selection_range: [], 41 | 42 | luckysheet_copy_save: {}, //复制粘贴 43 | luckysheet_paste_iscut: false, 44 | 45 | filterchage: true, //筛选 46 | luckysheet_filter_save: { "row": [], "column": [] }, 47 | 48 | luckysheet_sheet_move_status: false, 49 | luckysheet_sheet_move_data: [], 50 | luckysheet_scroll_status: false, 51 | 52 | luckysheetisrefreshdetail: true, 53 | luckysheetisrefreshtheme: true, 54 | luckysheetcurrentisPivotTable: false, 55 | 56 | luckysheet_rows_selected_status: false, //行列标题相关参 57 | luckysheet_cols_selected_status: false, 58 | luckysheet_rows_change_size: false, 59 | luckysheet_rows_change_size_start: [], 60 | luckysheet_cols_change_size: false, 61 | luckysheet_cols_change_size_start: [], 62 | luckysheet_cols_dbclick_timeout: null, 63 | luckysheet_cols_dbclick_times: 0, 64 | 65 | luckysheetCellUpdate: [], 66 | 67 | luckysheet_shiftpositon: null, 68 | 69 | iscopyself: true, 70 | 71 | orderbyindex: 0, //排序下标 72 | 73 | luckysheet_model_move_state: false, //模态框拖动 74 | luckysheet_model_xy: [0, 0], 75 | luckysheet_model_move_obj: null, 76 | 77 | luckysheet_cell_selected_move: false, //选区拖动替换 78 | luckysheet_cell_selected_move_index: [], 79 | 80 | luckysheet_cell_selected_extend: false, //选区下拉 81 | luckysheet_cell_selected_extend_index: [], 82 | luckysheet_cell_selected_extend_time: null, 83 | 84 | clearjfundo: true, 85 | jfundo: [], 86 | jfredo: [], 87 | lang: 'en', //language 88 | createChart: '', 89 | highlightChart: '', 90 | zIndex: 15, 91 | chartparam: { 92 | luckysheetCurrentChart: null, //current chart_id 93 | luckysheetCurrentChartActive: false, 94 | luckysheetCurrentChartMove: null, // Debounce state 95 | luckysheetCurrentChartMoveTimeout: null,//拖动图表框的节流定时器 96 | luckysheetCurrentChartMoveObj: null, //chart DOM object 97 | luckysheetCurrentChartMoveXy: null, //上一次操作结束的图表信息,x,y: chart框位置,scrollLeft1,scrollTop1: 滚动条位置 98 | luckysheetCurrentChartMoveWinH: null, //左右滚动条滑动距离 99 | luckysheetCurrentChartMoveWinW: null, //上下滚动条滑动距离 100 | luckysheetCurrentChartResize: null, 101 | luckysheetCurrentChartResizeObj: null, 102 | luckysheetCurrentChartResizeXy: null, 103 | luckysheetCurrentChartResizeWinH: null, 104 | luckysheetCurrentChartResizeWinW: null, 105 | luckysheetInsertChartTosheetChange: true, // 正在执行撤销 106 | luckysheetCurrentChartZIndexRank : 100, 107 | luckysheet_chart_redo_click:false, //撤销重做时标识 108 | luckysheetCurrentChartMaxState: false, //图表全屏状态 109 | jfrefreshchartall: '', 110 | changeChartCellData: '', 111 | renderChart: '', 112 | getChartJson: '' 113 | }, 114 | functionList:null, //function list explanation 115 | luckysheet_function:null, 116 | chart_selection: {}, 117 | currentChart: '', 118 | scrollRefreshSwitch:true, 119 | 120 | measureTextCache:{}, 121 | measureTextCellInfoCache:{}, 122 | measureTextCacheTimeOut:null, 123 | cellOverflowMapCache:{}, 124 | 125 | zoomRatio:1, 126 | 127 | visibledatacolumn_unique:null, 128 | visibledatarow_unique:null, 129 | 130 | showGridLines:true, 131 | 132 | toobarObject: {}, //toolbar constant 133 | inlineStringEditCache:null, 134 | inlineStringEditRange:null, 135 | 136 | fontList:[], 137 | defaultFontSize: 10, 138 | 139 | currentSheetView:"viewNormal", 140 | 141 | // cooperative editing 142 | cooperativeEdit:{ 143 | usernameTimeout:{ 144 | 145 | }, 146 | changeCollaborationSize:[], //改变行高或者列宽时,协同提示框需要跟随改变所需数据 147 | allDataColumnlen:[],//列宽发生过改变的列 148 | merge_range:{},//合并时单元格信息 149 | checkoutData:[],//切换表格页时所需数据 150 | }, 151 | 152 | // Resources that currently need to be loaded asynchronously, especially plugins. 'Core' marks the core rendering process. 153 | asyncLoad:['core'], 154 | // 默认单元格 155 | defaultCell: { 156 | bg: null, 157 | bl: 0, 158 | ct: {fa: "General", t: "n"}, 159 | fc: "rgb(51, 51, 51)", 160 | ff: 0, 161 | fs: 11, 162 | ht: 1, 163 | it: 0, 164 | vt: 1, 165 | m: '', 166 | v: '' 167 | } 168 | 169 | } 170 | 171 | export default Store; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/utils/chartUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 生成随机图表id 3 | */ 4 | function generateRandomKey(prefix) { 5 | if (prefix == null) { 6 | prefix = 'chart' 7 | } 8 | 9 | var userAgent = window.navigator.userAgent 10 | .replace(/[^a-zA-Z0-9]/g, '') 11 | .split('') 12 | var mid = '' 13 | for (var i = 0; i < 12; i++) { 14 | mid += userAgent[Math.round(Math.random() * (userAgent.length - 1))] 15 | } 16 | var time = new Date().getTime() 17 | 18 | return prefix + '_' + mid + '_' + time 19 | } 20 | /** 21 | * 深度克隆数据,包括对象,数组,map 22 | * @param {*} obj 对象,数组,map 23 | */ 24 | function deepCopy(obj) { 25 | if (!isObject(obj) && !isMap(obj)) { 26 | return obj; 27 | } 28 | 29 | let cloneObj; 30 | if (isMap(obj)) { 31 | cloneObj = new Map(); 32 | for (let key of obj.keys()) { 33 | let value = obj.get(key); 34 | if (isMap(value) || isObject(value) || Array.isArray(obj)) { 35 | let copyVal = deepCopy(value); 36 | cloneObj.set(key, copyVal); 37 | } else { 38 | cloneObj.set(key, value); 39 | } 40 | } 41 | } else if (typeof obj === "function") { 42 | cloneObj = obj 43 | } else { 44 | cloneObj = Array.isArray(obj) ? [] : {}; 45 | if (obj instanceof HTMLElement) { 46 | cloneObj = obj.cloneNode(true) 47 | } else { 48 | for (let key in obj) { 49 | // if (obj.hasOwnProperty(key)) { 50 | if (Object.prototype.hasOwnProperty.call(obj, key)) { 51 | cloneObj[key] = 52 | isMap(obj[key]) || isObject(obj[key]) 53 | ? deepCopy(obj[key]) 54 | : obj[key]; 55 | } 56 | } 57 | 58 | } 59 | } 60 | return cloneObj; 61 | } 62 | 63 | /** 64 | * 判断参数是否是Object类型 65 | * @param {*} o 66 | */ 67 | function isObject(o) { 68 | return ( 69 | !isMap(o) && 70 | (typeof o === 'object' || typeof o === 'function') && 71 | o !== null 72 | ); 73 | } 74 | 75 | /** 76 | * 判断参数是否是Map类型 77 | * @param {*} obj 78 | */ 79 | function isMap(obj) { 80 | if (obj instanceof Map) { 81 | return true; 82 | } else { 83 | return false; 84 | } 85 | } 86 | 87 | // 替换temp中的${xxx}为指定内容 ,temp:字符串,这里指html代码,dataarry:一个对象{"xxx":"替换的内容"} 88 | // 例:luckysheet.replaceHtml("${image}",{"image":"abc","jskdjslf":"abc"}) ==> abc 89 | function replaceHtml(temp, dataarry) { 90 | return temp.replace(/\$\{([\w]+)\}/g, function (s1, s2) { var s = dataarry[s2]; if (typeof (s) != "undefined") { return s; } else { return s1; } }); 91 | } 92 | 93 | function hasChinaword(s) { 94 | var patrn = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi; 95 | if (!patrn.exec(s)) { 96 | return false; 97 | } 98 | else { 99 | return true; 100 | } 101 | } 102 | 103 | export { 104 | isMap, 105 | isObject, 106 | deepCopy, 107 | generateRandomKey, 108 | replaceHtml 109 | } -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/utils/math.js: -------------------------------------------------------------------------------- 1 | import { isRealNum } from '../global/validate'; 2 | 3 | /* 4 | * 判断obj是否为一个整数 5 | */ 6 | function isInteger(obj) { 7 | return Math.floor(obj) === obj; 8 | } 9 | 10 | /* 11 | * 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100 12 | * @param floatNum {number} 小数 13 | * @return {object} 14 | * {times:100, num: 314} 15 | */ 16 | function toInteger(floatNum) { 17 | var ret = { times: 1, num: 0 }; 18 | 19 | if (isInteger(floatNum)) { 20 | ret.num = floatNum; 21 | return ret; 22 | } 23 | 24 | var strfi = floatNum + ''; 25 | var dotPos = strfi.indexOf('.'); 26 | var len = strfi.substr(dotPos + 1).length; 27 | var times = Math.pow(10, len); 28 | var intNum = parseInt(floatNum * times + 0.5, 10); 29 | 30 | ret.times = times; 31 | ret.num = intNum; 32 | 33 | return ret; 34 | } 35 | 36 | /* 37 | * 核心方法,实现加减乘除运算,确保不丢失精度 38 | * 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除) 39 | * 40 | * @param a {number} 运算数1 41 | * @param b {number} 运算数2 42 | * @param digits {number} 精度,保留的小数点数,比如 2, 即保留为两位小数 43 | * @param op {string} 运算类型,有加减乘除(add/subtract/multiply/divide) 44 | * 45 | */ 46 | function operation(a, b, op) { 47 | var o1 = toInteger(a); 48 | var o2 = toInteger(b); 49 | var n1 = o1.num; 50 | var n2 = o2.num; 51 | var t1 = o1.times; 52 | var t2 = o2.times; 53 | var max = t1 > t2 ? t1 : t2; 54 | var result = null; 55 | 56 | switch (op) { 57 | case 'add': 58 | if (t1 === t2) { // 两个小数位数相同 59 | result = n1 + n2; 60 | } 61 | else if (t1 > t2) { // o1 小数位 大于 o2 62 | result = n1 + n2 * (t1 / t2); 63 | } 64 | else { // o1 小数位 小于 o2 65 | result = n1 * (t2 / t1) + n2; 66 | } 67 | 68 | return result / max; 69 | case 'subtract': 70 | if (t1 === t2) { 71 | result = n1 - n2; 72 | } 73 | else if (t1 > t2) { 74 | result = n1 - n2 * (t1 / t2); 75 | } 76 | else { 77 | result = n1 * (t2 / t1) - n2; 78 | } 79 | 80 | return result / max; 81 | case 'multiply': 82 | result = (n1 * n2) / (t1 * t2); 83 | 84 | return result; 85 | case 'divide': 86 | return result = function () { 87 | var r1 = n1 / n2; 88 | var r2 = t2 / t1; 89 | return operation(r1, r2, 'multiply'); 90 | }(); 91 | } 92 | } 93 | /** 94 | * 做小数点的四舍五入计算 95 | * @param {*} num 96 | * @param {*} precision 97 | */ 98 | function fixed(num, precision) { 99 | if (!precision) { 100 | precision = 2; 101 | } 102 | if (!isRealNum(num)) return num; 103 | let s = num.toFixed(precision); 104 | let index = s.indexOf('.'); 105 | let prefix = s.substring(0, index); 106 | let suffix = s.substring(index + 1, s.length); 107 | if (suffix) { 108 | for (let i = suffix.length - 1; i != 0; i--) { 109 | //最末位不为0,直接break; 110 | if (suffix.charAt(i) != '0' && i == suffix.length - 1) { 111 | break; 112 | } else { 113 | suffix = suffix.substring(0, i); 114 | } 115 | } 116 | } 117 | return Number(prefix + '.' + suffix); 118 | } 119 | 120 | 121 | /** 122 | * Calculation +-/* Solve the problem of js accuracy 123 | */ 124 | Number.prototype.add = function (value) { 125 | let number = parseFloat(value); 126 | if (typeof number !== 'number' || Number.isNaN(number)) { 127 | throw new Error('请输入数字或者数字字符串~'); 128 | }; 129 | return operation(this, number, 'add'); 130 | }; 131 | Number.prototype.subtract = function (value) { 132 | let number = parseFloat(value); 133 | if (typeof number !== 'number' || Number.isNaN(number)) { 134 | throw new Error('请输入数字或者数字字符串~'); 135 | } 136 | return operation(this, number, 'subtract'); 137 | }; 138 | Number.prototype.multiply = function (value) { 139 | let number = parseFloat(value); 140 | if (typeof number !== 'number' || Number.isNaN(number)) { 141 | throw new Error('请输入数字或者数字字符串~'); 142 | } 143 | return operation(this, number, 'multiply'); 144 | }; 145 | Number.prototype.divide = function (value) { 146 | let number = parseFloat(value); 147 | if (typeof number !== 'number' || Number.isNaN(number)) { 148 | throw new Error('请输入数字或者数字字符串~'); 149 | } 150 | return operation(this, number, 'divide'); 151 | }; 152 | Number.prototype.tofixed = function (value) { 153 | let precision = parseFloat(value); 154 | if (typeof precision !== 'number' || Number.isNaN(precision)) { 155 | throw new Error('请输入数字或者数字字符串~'); 156 | } 157 | return fixed(this, precision); 158 | }; -------------------------------------------------------------------------------- /luckysheet_obj/Luckysheet-master/src/utils/polyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * polyfill event in firefox 3 | */ 4 | function __firefox(){ 5 | HTMLElement.prototype.__defineGetter__("runtimeStyle", __element_style); 6 | window.constructor.prototype.__defineGetter__("event", __window_event); 7 | Event.prototype.__defineGetter__("srcElement", __event_srcElement); 8 | } 9 | 10 | function __element_style(){ 11 | return this.style; 12 | } 13 | 14 | function __window_event(){ 15 | return __window_event_constructor(); 16 | } 17 | 18 | function __event_srcElement(){ 19 | return this.target; 20 | } 21 | 22 | function __window_event_constructor(){ 23 | if(document.all){ 24 | return window.event; 25 | } 26 | 27 | var _caller = __window_event_constructor.caller; 28 | 29 | while(_caller != null){ 30 | var _argument = _caller.arguments[0]; 31 | 32 | if(_argument){ 33 | var _temp = _argument.constructor; 34 | 35 | if(_temp.toString().indexOf("Event") != -1){ 36 | return _argument; 37 | } 38 | } 39 | 40 | _caller = _caller.caller; 41 | } 42 | 43 | return null; 44 | } 45 | 46 | export default __firefox; -------------------------------------------------------------------------------- /luckysheet_obj/apps/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/1/31 1:03 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: __init__.py.py 9 | @Software: PyCharm 10 | """ 11 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/__init__.py -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class LuckySheetConfig(AppConfig): 5 | name = 'apps.lucky_sheet' 6 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/init_sheet.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/1/31 2:56 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: init_sheet.py 9 | @Software: PyCharm 10 | """ 11 | 12 | # 初始化空excel的json 13 | init_sheet_json = [ 14 | { 15 | "name": "Cell", 16 | "index": "sheet_01", 17 | "order": 0, 18 | "status": 1, 19 | "celldata": [{"r": 0, "c": 0, "v": {"v": 1, "m": "1", "ct": {"fa": "General", "t": "n"}}}] 20 | }, 21 | { 22 | "name": "Data", 23 | "index": "sheet_02", 24 | "order": 1, 25 | "status": 0 26 | }, 27 | { 28 | "name": "Picture", 29 | "index": "sheet_03", 30 | "order": 2, 31 | "status": 0 32 | } 33 | ] 34 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/java-utils.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/java-utils.jar -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/jvm_tool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/1/31 10:36 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: jvm_tool.py 9 | @Software: PyCharm 10 | """ 11 | 12 | import jpype 13 | import os 14 | 15 | base_dir = os.path.dirname(os.path.abspath(__file__)) 16 | 17 | jarpath = os.path.join(base_dir, "java-utils.jar") # 第二个参数是jar包的路径 18 | jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=%s" % (jarpath)) # 启动jvm 19 | JDClass = jpype.JClass("com.demo.utils.PakoGzipUtils") 20 | jpython_obj = JDClass() # 创建类的实例,可以调用类里边的方法 21 | 22 | if __name__ == '__main__': 23 | jpype.shutdownJVM() # 最后关闭jvm 24 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/2/20 21:43 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: log.py 9 | @Software: PyCharm 10 | """ 11 | 12 | import logging 13 | from copy import deepcopy as copy 14 | from logging import Formatter 15 | 16 | MAPPING = { 17 | 'DEBUG': 37, # white 18 | 'INFO': 36, # cyan 19 | 'WARNING': 33, # yellow 20 | 'ERROR': 31, # red 21 | 'CRITICAL': 41, # white on red bg 22 | } 23 | 24 | PREFIX = '\033[' 25 | SUFFIX = '\033[0m' 26 | 27 | 28 | class ColoredFormatter(Formatter): 29 | def __init__(self, patern): 30 | Formatter.__init__(self, patern) 31 | 32 | def format(self, record): 33 | colored_record = copy(record) 34 | levelname = colored_record.levelname 35 | seq = MAPPING.get(levelname, 37) # default white 36 | colored_levelname = ('{0}{1}m{2}{3}') \ 37 | .format(PREFIX, seq, levelname, SUFFIX) 38 | colored_record.levelname = colored_levelname 39 | return Formatter.format(self, colored_record) 40 | 41 | 42 | # Create top level logger 43 | logger = logging.getLogger("root") 44 | 45 | # Add console handler using our custom ColoredFormatter 46 | ch = logging.StreamHandler() 47 | ch.setLevel(logging.DEBUG) 48 | cf = ColoredFormatter("[%(asctime)s] - [%(name)s] - [%(levelname)s] - %(message)s (%(filename)s:%(lineno)d)") 49 | ch.setFormatter(cf) 50 | logger.addHandler(ch) 51 | 52 | # Add file handler 53 | # fh = logging.FileHandler('log.log') 54 | # fh.setLevel(logging.DEBUG) 55 | # ff = logging.Formatter( 56 | # '[%(asctime)s] - [%(name)s] - [%(levelname)s] - %(message)s (%(filename)s:%(lineno)d)' 57 | # ) 58 | # fh.setFormatter(ff) 59 | # logger.addHandler(fh) 60 | 61 | # Set log level 62 | logger.setLevel(logging.DEBUG) 63 | 64 | if __name__ == '__main__': 65 | logger.debug('A debug message') 66 | logger.info('An info message') 67 | logger.warning('Something is not right.') 68 | logger.error('A Major error has happened.') 69 | logger.critical('Fatal error. Cannot ontinue') 70 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/migrations/__init__.py -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/Anton-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/Anton-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/HanaleiFill-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/HanaleiFill-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/Pacifico-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/Pacifico-Regular.ttf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.eot -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.woff -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/assets/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/EwaAntH.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/EwaAntH.gif -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/EwaAntV.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/EwaAntV.gif -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/arrow-down.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/loading.gif -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_16px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_16px.ico -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_24px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_24px.ico -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_32px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/paint_32px.ico -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/css/waffle_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/css/waffle_sprite.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/demoData/demoFeature.js: -------------------------------------------------------------------------------- 1 | 2 | // Features specially written for demo 3 | 4 | (function() { 5 | 6 | // language 7 | function language(params) { 8 | 9 | var lang = navigator.language||navigator.userLanguage;//常规浏览器语言和IE浏览器 10 | lang = lang.substr(0, 2);//截取lang前2位字符 11 | 12 | return lang; 13 | 14 | } 15 | // Tencent Forum Link Button 16 | function supportButton() { 17 | const text = language() === 'zh' ? '反馈' : 'Forum'; 18 | const link = language() === 'zh' ? 'https://support.qq.com/product/288322' : 'https://groups.google.com/g/luckysheet'; 19 | 20 | document.querySelector("body").insertAdjacentHTML('beforeend', ''+ text +''); 21 | } 22 | 23 | supportButton() 24 | 25 | /** 26 | * Get url parameters 27 | */ 28 | function getRequest() { 29 | var vars = {}; 30 | var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, 31 | function(m,key,value) { 32 | vars[key] = value; 33 | }); 34 | return vars; 35 | } 36 | 37 | window.luckysheetDemoUtil = { 38 | language:language, 39 | getRequest:getRequest 40 | } 41 | 42 | })() -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/demoData/sheetComment.js: -------------------------------------------------------------------------------- 1 | window.sheetComment = { 2 | "name": "Comment", 3 | "color": "", 4 | "config": { 5 | "columnlen": { 6 | "2": 102 7 | } 8 | }, 9 | "index": "5", 10 | "chart": [], 11 | "status": 0, 12 | "order": "5", 13 | "column": 18, 14 | "row": 36, 15 | "celldata": [{ 16 | "r": 2, 17 | "c": 2, 18 | "v": { 19 | "m": "HoverShown", 20 | "ct": { 21 | "fa": "General", 22 | "t": "g" 23 | }, 24 | "v": "HoverShown", 25 | "bl": 1, 26 | "ps": { 27 | "left": null, 28 | "top": null, 29 | "width": null, 30 | "height": null, 31 | "value": "Hello world!", 32 | "isshow": false 33 | } 34 | } 35 | }, { 36 | "r": 7, 37 | "c": 2, 38 | "v": { 39 | "m": "Size", 40 | "ct": { 41 | "fa": "General", 42 | "t": "g" 43 | }, 44 | "v": "Size", 45 | "bl": 1, 46 | "ps": { 47 | "left": null, 48 | "top": null, 49 | "width": null, 50 | "height": null, 51 | "value": "Hello,world!", 52 | "isshow": true 53 | } 54 | } 55 | }], 56 | "ch_width": 4748, 57 | "rh_height": 1790, 58 | "luckysheet_select_save": [{ 59 | "row": [0, 0], 60 | "column": [0, 0] 61 | }], 62 | "luckysheet_selection_range": [], 63 | "scrollLeft": 0, 64 | "scrollTop": 0 65 | } 66 | 67 | // export default sheetComment; -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/demoData/sheetPivotTable.js: -------------------------------------------------------------------------------- 1 | window.sheetPivotTable = { 2 | "name": "PivotTable", 3 | "color": "", 4 | "config": {}, 5 | "index": "7", 6 | "chart": [], 7 | "status": 0, 8 | "order": "7", 9 | "column": 18, 10 | "row": 36, 11 | "celldata": [{ 12 | "r": 0, 13 | "c": 0, 14 | "v": "count:score" 15 | }, { 16 | "r": 0, 17 | "c": 1, 18 | "v": "science" 19 | }, { 20 | "r": 0, 21 | "c": 2, 22 | "v": "mathematics" 23 | }, { 24 | "r": 0, 25 | "c": 3, 26 | "v": "foreign language" 27 | }, { 28 | "r": 0, 29 | "c": 4, 30 | "v": "English" 31 | }, { 32 | "r": 0, 33 | "c": 5, 34 | "v": "total" 35 | }, { 36 | "r": 1, 37 | "c": 0, 38 | "v": "Alex" 39 | }, { 40 | "r": 1, 41 | "c": 1, 42 | "v": 1 43 | }, { 44 | "r": 1, 45 | "c": 2, 46 | "v": 1 47 | }, { 48 | "r": 1, 49 | "c": 3, 50 | "v": 1 51 | }, { 52 | "r": 1, 53 | "c": 4, 54 | "v": 1 55 | }, { 56 | "r": 1, 57 | "c": 5, 58 | "v": 4 59 | }, { 60 | "r": 2, 61 | "c": 0, 62 | "v": "Joy" 63 | }, { 64 | "r": 2, 65 | "c": 1, 66 | "v": 1 67 | }, { 68 | "r": 2, 69 | "c": 2, 70 | "v": 1 71 | }, { 72 | "r": 2, 73 | "c": 3, 74 | "v": 1 75 | }, { 76 | "r": 2, 77 | "c": 4, 78 | "v": 1 79 | }, { 80 | "r": 2, 81 | "c": 5, 82 | "v": 4 83 | }, { 84 | "r": 3, 85 | "c": 0, 86 | "v": "Tim" 87 | }, { 88 | "r": 3, 89 | "c": 1, 90 | "v": 1 91 | }, { 92 | "r": 3, 93 | "c": 2, 94 | "v": 1 95 | }, { 96 | "r": 3, 97 | "c": 3, 98 | "v": 1 99 | }, { 100 | "r": 3, 101 | "c": 4, 102 | "v": 1 103 | }, { 104 | "r": 3, 105 | "c": 5, 106 | "v": 4 107 | }, { 108 | "r": 4, 109 | "c": 0, 110 | "v": "total" 111 | }, { 112 | "r": 4, 113 | "c": 1, 114 | "v": 3 115 | }, { 116 | "r": 4, 117 | "c": 2, 118 | "v": 3 119 | }, { 120 | "r": 4, 121 | "c": 3, 122 | "v": 3 123 | }, { 124 | "r": 4, 125 | "c": 4, 126 | "v": 3 127 | }, { 128 | "r": 4, 129 | "c": 5, 130 | "v": 12 131 | }], 132 | "ch_width": 4748, 133 | "rh_height": 1790, 134 | "luckysheet_select_save": [{ 135 | "row": [0, 0], 136 | "column": [0, 0] 137 | }], 138 | "luckysheet_selection_range": [], 139 | "scrollLeft": 0, 140 | "scrollTop": 0, 141 | "isPivotTable": true, 142 | "pivotTable": { 143 | "pivot_select_save": { 144 | "left": 0, 145 | "width": 73, 146 | "top": 0, 147 | "height": 19, 148 | "left_move": 0, 149 | "width_move": 369, 150 | "top_move": 0, 151 | "height_move": 259, 152 | "row": [0, 12], 153 | "column": [0, 4], 154 | "row_focus": 0, 155 | "column_focus": 0 156 | }, 157 | "pivotDataSheetIndex": 6, //The sheet index where the source data is located 158 | "column": [{ 159 | "index": 3, 160 | "name": "subject", 161 | "fullname": "subject" 162 | }], 163 | "row": [{ 164 | "index": 1, 165 | "name": "student", 166 | "fullname": "student" 167 | }], 168 | "filter": [], 169 | "values": [{ 170 | "index": 4, 171 | "name": "score", 172 | "fullname": "count:score", 173 | "sumtype": "COUNTA", 174 | "nameindex": 0 175 | }], 176 | "showType": "column", 177 | "pivotDatas": [ 178 | ["count:score", "science", "mathematics", "foreign language", "English", "total"], 179 | ["Alex", 1, 1, 1, 1, 4], 180 | ["Joy", 1, 1, 1, 1, 4], 181 | ["Tim", 1, 1, 1, 1, 4], 182 | ["total", 3, 3, 3, 3, 12] 183 | ], 184 | "drawPivotTable": false, 185 | "pivotTableBoundary": [5, 6] 186 | } 187 | } 188 | 189 | // export default sheetPivotTable; -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/expendPlugins/chart/chartmix.css: -------------------------------------------------------------------------------- 1 | .luckysheet-datavisual-quick-menu{width:120px;overflow:auto;margin-top:15px}.luckysheet-datavisual-quick-menu::-webkit-scrollbar{display:none}.luckysheet-datavisual-quick-menu>div{text-align:left;padding:4px 4px;border-right:3px solid #fff;color:#777;cursor:pointer;line-height:1.4em;word-wrap:break-word}.luckysheet-datavisual-quick-menu>div:hover{color:#000}.luckysheet-datavisual-quick-menu>div i{width:15px}.luckysheet-datavisual-quick-menu>div:hover i{color:#ff7e7e}.luckysheet-datavisual-quick-menu>div.luckysheet-datavisual-quick-menu-active{border-right:3px solid #ff7e7e;color:#000;font-weight:700}.luckysheet-datavisual-quick-menu>div.luckysheet-datavisual-quick-menu-active:hover i{color:#000}.luckysheet-datavisual-quick-range{padding:5px 0}.luckysheet-datavisual-range-container{background:#fff;border:1px solid #d9d9d9;border-top:1px solid silver;min-width:20px;width:100%;max-width:200px;display:inline-block}.luckysheet-datavisual-range-container-focus{border:1px solid #4d90fe;box-shadow:inset 0 1px 2px rgba(0,0,0,.3);outline:none}.luckysheet-datavisual-range-input,.luckysheet-datavisual-range-input:focus{background:transparent!important;border:none!important;box-sizing:border-box;box-shadow:none;height:25px;margin:0;outline:none!important;padding:1px 8px!important;width:100%}.luckysheet-datavisual-range-button-container{overflow:hidden;padding:0 0 0 8px;text-align:right;width:21px}.luckysheet-datavisual-range-button-container div{padding:2px 10px 0 10px;font-size:18px;cursor:pointer;color:#6598f3}.luckysheet-datavisual-range-button-container div:hover{color:#ff7e7e}.luckysheet-datavisual-quick-m{margin-top:5px;min-height:500px;top:50px;font-size:12px}.luckysheet-datavisual-quick-list{left:110px;right:0;bottom:0;top:80px;position:absolute;overflow:auto;border-top:1px solid #e5e5e5;padding:5px 3px 35px 3px}.luckysheet-datavisual-quick-list-title{padding:4px 6px;background:#e5e5e5;margin-top:10px}.luckysheet-datavisual-quick-list-ul{overflow:hidden}.luckysheet-datavisual-quick-list-item{display:inline-block;margin:5px 8px;border:1px solid #dadada;width:100px;height:80px}.luckysheet-datavisual-quick-list-item:hover{border:1px solid #ff7e7e;box-shadow:0 0 20px #ff7e7e}.luckysheet-datavisual-quick-list-item img{display:inline-block;width:100px;height:80px}.luckysheet-datavisual-quick-list-item-active{border:1px solid #6598f3;box-shadow:0 0 20px #6598f3}.chart-base-slider .el-slider__runway.show-input{margin-right:72px}.chart-base-slider .el-slider__input.el-input-number--mini{width:56px}.chart-base-slider .input_content{margin:6px 0 0 5px}.title{font-weight:700}.el-row{font-size:12px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.chartSetting{width:100%;height:100%} -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFcolorGradation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFcolorGradation.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFdataBar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFdataBar.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFicons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/CFicons.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/icon_dropCell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/icon_dropCell.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/js.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static/dist/plugins/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static_bk/js/demoFeature.js: -------------------------------------------------------------------------------- 1 | 2 | // Features specially written for demo 3 | 4 | (function() { 5 | 6 | // language 7 | function language(params) { 8 | 9 | var lang = navigator.language||navigator.userLanguage;//常规浏览器语言和IE浏览器 10 | lang = lang.substr(0, 2);//截取lang前2位字符 11 | 12 | return lang; 13 | 14 | } 15 | // Tencent Forum Link Button 16 | function supportButton() { 17 | const text = language() === 'zh' ? '反馈' : 'Forum'; 18 | const link = language() === 'zh' ? 'https://support.qq.com/product/288322' : 'https://groups.google.com/g/luckysheet'; 19 | 20 | document.querySelector("body").insertAdjacentHTML('beforeend', `${text}`); 21 | } 22 | 23 | supportButton() 24 | 25 | window.luckysheetDemoUtil = { 26 | language:language 27 | } 28 | 29 | })() -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/static_bk/js/ecsheet-main.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/apps/lucky_sheet/static_bk/js/ecsheet-main.zip -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/templates/index.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | Hello World! 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 30 | 31 | 32 | {% csrf_token %} 33 | 37 |

38 | 当前k: 39 | 41 | 43 | 44 | 45 |

46 |
47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 118 | 119 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/templates/luckysheet.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | Luckysheet 14 | 15 | 16 | {# #} 17 | {# #} 18 | {# #} 19 | {# #} 20 | {# #} 21 | {# #} 22 | 23 | {# #} 24 | {# #} 25 | {# #} 26 | {# #} 27 | {# #} 28 | {# #} 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | {% csrf_token %} 41 |
43 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/tools/db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/3/14 12:09 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: redis.py 9 | @Software: PyCharm 10 | """ 11 | # https://gitee.com/mengshukeji/LuckysheetServer/blob/main/luckysheet/src/main/java/com/xc/luckysheet/db/server/JfGridUpdateService.java 12 | # import os 13 | # import sys 14 | # from pathlib import Path 15 | # BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent 16 | # setting_path = os.path.join(BASE_DIR, "luckysheet_obj") 17 | # sys.path.insert(0, setting_path) 18 | # print(sys.path) 19 | # from luckysheet_obj.luckysheet_obj import settings 20 | # import redis 21 | # 22 | # redis_db = settings.MY_CACHES 23 | # redis_host, redis_port = redis_db.get("LOCATION").split("//")[1].split(":") 24 | # redis_max_connections = redis_db.get("OPTIONS", dict()).get("CONNECTION_POOL_KWARGS", dict()).get("max_connections") 25 | # 26 | # 27 | # class RedisDB(object): 28 | # POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=1000) 29 | # _*_coding:utf-8_*_ 30 | import redis 31 | import io 32 | import os 33 | import traceback 34 | from lucky_sheet.log import logger 35 | 36 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luckysheet_obj.settings') 37 | 38 | 39 | class RedisDB(object): 40 | def __init__(self, django_settings): 41 | self.pool = redis.ConnectionPool(host=django_settings.REDIS_CONN['HOST'], 42 | port=django_settings.REDIS_CONN['PORT'], 43 | db=django_settings.REDIS_CONN['DB']) 44 | self.redis = redis.Redis(connection_pool=self.pool) 45 | self.ok = 0 46 | self.err = -1 47 | 48 | # string插入 49 | def insert_string(self, key, value): 50 | try: 51 | self.redis.set(key, value) 52 | return self.ok 53 | except Exception as e: 54 | logger.error("insert the gridkey:%s to redis error !!!" % key) 55 | print(traceback.format_exc()) 56 | return self.err 57 | 58 | # string取值 59 | def get_string(self, key): 60 | try: 61 | return self.redis.get(key) 62 | except Exception as e: 63 | logger.error("get the gridkey:%s from redis error !!!" % key) 64 | print(traceback.format_exc()) 65 | return self.err 66 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/urls.py: -------------------------------------------------------------------------------- 1 | """luckysheet_obj URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | 17 | from django.contrib import admin 18 | from django.urls import path 19 | from django.conf.urls import url, include 20 | from lucky_sheet.views import IndexView, LuckySheetIndex, LuckySheetLoadUrl, luckysheet_update_url 21 | from lucky_sheet.views import LuckySheetSaveDb, LuckySheetLoadGridKey 22 | from django.conf import settings 23 | from django.views import static 24 | from django.conf.urls.static import static as media_static 25 | 26 | urlpatterns = [ 27 | url(r'^$', IndexView, name='index_view'), # 主页,测试使用 28 | url(r'^luckysheetindex/$', LuckySheetIndex.as_view(), name="lucky_sheet_index"), # luckysheet主页 29 | url(r'^luckysheetloadurl/', LuckySheetLoadUrl.as_view(), name="lucky_sheet_loadurl"), # lucky_sheet_loadurl 30 | url(r'^luckysheetupdateurl', luckysheet_update_url, name="luckysheet_update_url"), # lucky_sheet_loadurl 31 | url(r'^luckysheetsavedb/', LuckySheetSaveDb.as_view(), name="luckysheet_save_db"), # luckysheet_save_db 32 | url(r'^luckysheetloadgridkey/', LuckySheetLoadGridKey.as_view(), name="luckysheet_load_gridkey"), # luckysheet_save_db 33 | url(r'^luckysheetindex/static/(?P.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'), 34 | ] 35 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.views.generic.base import View 3 | from django.http import HttpResponse, JsonResponse, HttpResponseRedirect 4 | from django.contrib import auth 5 | from django.conf import settings 6 | import os 7 | import json 8 | import uuid 9 | 10 | from lucky_sheet.log import logger 11 | from lucky_sheet import init_sheet 12 | from lucky_sheet import websocket_server 13 | from lucky_sheet.tools import db 14 | 15 | base_dir = os.path.dirname(os.path.abspath(__file__)) 16 | redis_obj = db.RedisDB(settings) 17 | 18 | 19 | # https://madewith.cn/709 20 | # Create your views here. 21 | 22 | # index主页初始化 23 | def IndexView(request): 24 | return render(request, "index.html", {}) 25 | 26 | 27 | # luckusheet的协同更新处理 28 | def luckysheet_update_url(request): 29 | if request.method == "GET": 30 | return (websocket_server.websocket_update_url(request)) 31 | elif request.method == "POST": 32 | return (websocket_server.websocket_update_image_url(request)) 33 | else: 34 | return HttpResponse("error") 35 | 36 | 37 | # demo主页 38 | class LuckySheetIndex(View): 39 | def get(self, request): 40 | return render(request, "luckysheet.html", {"gridkey": ""}) 41 | 42 | def post(self, request): 43 | return render(request, "luckysheet.html", {"gridkey": ""}) 44 | 45 | 46 | # 页面数据初始化加载 47 | class LuckySheetLoadUrl(View): 48 | def get(self, request): 49 | logger.info("get request") 50 | return HttpResponse({}) 51 | 52 | def post(self, request): 53 | logger.info("post request") 54 | gridkey = request.POST.get("gridKey", None) 55 | logger.info("gridkey: %s" % gridkey) 56 | init_json = init_sheet.init_sheet_json 57 | # 该判断是为了在用户刚开始上传excel的时候,点击保存数据库之后,从redis再加载一边数据,作为协同使用 58 | if gridkey: 59 | init_json = redis_obj.get_string(gridkey) 60 | if init_json != -1: 61 | init_json = json.loads(init_json) 62 | init_json = json.dumps(init_json.get("data")) 63 | else: 64 | init_json = dict() 65 | return HttpResponse('%s' % init_json) 66 | 67 | 68 | # 保存数据库处理 69 | class LuckySheetSaveDb(View): 70 | def get(self, request): 71 | return HttpResponse({}) 72 | 73 | def post(self, request): 74 | #gridKey = str(uuid.uuid1()) 75 | luckysheet_data = json.loads(request.POST.get("data")) 76 | gridKey = luckysheet_data.get('gridKey', str(uuid.uuid1())) 77 | luckysheet_data['allowUpdate'] = True 78 | luckysheet_data['updateUrl'] = settings.WSS_UPDATE_URL 79 | luckysheet_data['loadUrl'] = settings.WSS_LOAD_URL 80 | luckysheet_data['gridKey'] = gridKey 81 | redis_obj.insert_string(gridKey, '''%s''' % json.dumps(luckysheet_data)) 82 | return HttpResponse(json.dumps({"status": 0, "data": luckysheet_data, "gridkey": gridKey})) 83 | 84 | 85 | # 根据gridkey加载数据 86 | class LuckySheetLoadGridKey(View): 87 | def get(self, request): 88 | gridKey = request.GET.get("gridKey") 89 | luckysheet_data = redis_obj.get_string(gridKey) 90 | if luckysheet_data: 91 | luckysheet_data = json.loads(luckysheet_data) 92 | else: 93 | logger.info("the gridkey does not exists %s" % gridKey) 94 | luckysheet_data = dict() 95 | return HttpResponse(json.dumps({"status": 0, "data": luckysheet_data, "gridkey": gridKey})) 96 | 97 | def post(self, request): 98 | return HttpResponse({}) 99 | -------------------------------------------------------------------------------- /luckysheet_obj/apps/lucky_sheet/websocket_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | @time: 2021/1/31 3:03 6 | @author: LQ 7 | @email: LQ65535@163.com 8 | @File: websocket_server.py 9 | @Software: PyCharm 10 | """ 11 | 12 | from django.shortcuts import render 13 | from dwebsocket.decorators import accept_websocket, require_websocket 14 | from django.http import HttpResponse 15 | import json 16 | import uuid 17 | import time 18 | from lucky_sheet.log import logger 19 | from lucky_sheet import luckysheet_update 20 | import urllib.parse 21 | import zlib 22 | import lucky_sheet.jvm_tool as jvm_tool 23 | 24 | WEB_SOCKET_CLIENT = dict() 25 | 26 | 27 | # https://blog.csdn.net/qq_36387683/article/details/99644041 28 | 29 | 30 | # 发送websocket消息 31 | def send_websocket_message(userid, grid_key, res): 32 | luckysheet_update.update_operate(grid_key, res) 33 | # 添加多人协同编辑的时候,给其他人选区的位置标红 34 | # type: # 0:连接成功,1:发送给当前连接的用户,2:发送信息给其他用户,3:发送选区位置信息,999:用户连接断开 35 | t = res.get("t", None) 36 | if "mv" == t: 37 | __type = 3 38 | else: 39 | __type = 2 40 | new_msg = { 41 | "createTime": int(time.time() * 1000), 42 | "data": json.dumps(res), 43 | "id": "%s" % userid, 44 | "returnMessage": "success", 45 | "status": "0", 46 | "type": __type, 47 | "username": userid 48 | } 49 | for _client in list(WEB_SOCKET_CLIENT.keys()): 50 | # 把自己的操作去掉,只给别的客户端更新操作 51 | # 如果没有gridkey,则默认给所有没有gridkey的客户端同步消息,主要是首页演示使用 52 | #if _client != userid: 53 | # logger.info("sed to %s" % _client) 54 | # request = WEB_SOCKET_CLIENT.get(_client).get("userid") 55 | # print("the web socket receive message message is: ", new_msg) 56 | # request.send(json.dumps(new_msg)) # 发送消息到客户端 57 | 58 | # 如果有gridkey,则根据gridkey返回更新值,实际应用场景使用 59 | #__gridkey = WEB_SOCKET_CLIENT.get(_client).get("grid_key", "") 60 | #if not __gridkey: 61 | # request = WEB_SOCKET_CLIENT.get(_client).get("userid") 62 | # request.send(json.dumps(new_msg)) # 发送消息到客户端 63 | logger.info("user:" + _client) 64 | if _client != userid: 65 | __gridkey = WEB_SOCKET_CLIENT.get(_client).get("grid_key", "") 66 | logger.info("grid_key: %s" % __gridkey) 67 | if (not __gridkey) or (__gridkey == grid_key): 68 | logger.info("sed to %s" % _client) 69 | request = WEB_SOCKET_CLIENT.get(_client).get("userid") 70 | # print("the web socket receive message message is: ", new_msg) 71 | request.send(json.dumps(new_msg)) # 发送消息到客户端 72 | 73 | 74 | @accept_websocket 75 | def websocket_update_url(request): 76 | #userid = str(uuid.uuid1()) 77 | userid = str(request.user) + "-" + request.META.get("REMOTE_ADDR", "unknownIP") 78 | grid_key = request.GET.get("g", "") 79 | # 每个客户端请求进来的时候,只会走一次这个流程,因此在这里面设置一个uuid 80 | if request.is_websocket(): 81 | WEB_SOCKET_CLIENT[userid] = dict() 82 | WEB_SOCKET_CLIENT[userid]["userid"] = request.websocket 83 | WEB_SOCKET_CLIENT[userid]["grid_key"] = grid_key 84 | if not request.is_websocket(): # 判断是不是websocket连接 85 | print("the request is not a websocket request!!!") 86 | return HttpResponse("the request is not a websocket request!!!") 87 | else: 88 | logger.info("txt message---") 89 | for message in request.websocket: 90 | # 如果什么都没收到那就判定为客户端退出了 91 | if not message: 92 | logger.info("the userid:%s has exit!!!" % userid) 93 | WEB_SOCKET_CLIENT[userid]["userid"].close() 94 | del WEB_SOCKET_CLIENT[userid] 95 | return HttpResponse("the userid:%s has exit!!!" % userid) 96 | # 如果客户端长时间不活动,则会自动发送一个“rub”字符串到后台,因此做个过滤 97 | if "rub" in str(message): 98 | res = { 99 | "data": "rub", 100 | "returnMessage": "success", 101 | } 102 | logger.info(message) 103 | WEB_SOCKET_CLIENT[userid]["userid"].send(json.dumps(res)) 104 | else: 105 | jpy = jvm_tool.jpython_obj 106 | result = jpy.unCompressURI(message) 107 | #destr = zlib.decompress( 108 | # bytes(message, 'ISO-8859-1'), zlib.MAX_WBITS | 16) 109 | #result = urllib.parse.unquote_to_bytes(destr) 110 | res = json.loads(str(result)) 111 | logger.info(res) 112 | send_websocket_message(userid, grid_key, res) 113 | 114 | 115 | # 处理ajax接收到的图片消息 116 | def websocket_update_image_url(request): 117 | grid_key = "" 118 | logger.info("images message---") 119 | res = json.loads(request.body) 120 | userid = res.get("username", "None") 121 | send_websocket_message(userid, grid_key, res) 122 | return HttpResponse("send images success!!!") 123 | -------------------------------------------------------------------------------- /luckysheet_obj/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/db.sqlite3 -------------------------------------------------------------------------------- /luckysheet_obj/luckysheet_obj/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/luckysheet_obj/__init__.py -------------------------------------------------------------------------------- /luckysheet_obj/luckysheet_obj/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for luckysheet_obj project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luckysheet_obj.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /luckysheet_obj/luckysheet_obj/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for luckysheet_obj project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.1.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.1/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | import sys 15 | import os 16 | 17 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 18 | BASE_DIR = Path(__file__).resolve().parent.parent 19 | 20 | # 添加 apps 目录 21 | sys.path.insert(0, os.path.join(BASE_DIR, 'apps')) 22 | 23 | # Quick-start development settings - unsuitable for production 24 | # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ 25 | 26 | # SECURITY WARNING: keep the secret key used in production secret! 27 | SECRET_KEY = 'p0$ne@gyhi-t8%k4tir8jch8t86(ep9d(l%t&2qv8@y^3zh&$#' 28 | 29 | # SECURITY WARNING: don't run with debug turned on in production! 30 | DEBUG = True 31 | 32 | ALLOWED_HOSTS = [] 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = [ 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 44 | 'lucky_sheet' 45 | ] 46 | 47 | MIDDLEWARE = [ 48 | 'django.middleware.security.SecurityMiddleware', 49 | 'django.contrib.sessions.middleware.SessionMiddleware', 50 | 'django.middleware.common.CommonMiddleware', 51 | # 'django.middleware.csrf.CsrfViewMiddleware', 52 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 53 | 'django.contrib.messages.middleware.MessageMiddleware', 54 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 55 | ] 56 | 57 | ROOT_URLCONF = 'luckysheet_obj.urls' 58 | 59 | TEMPLATES = [ 60 | { 61 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 62 | 'DIRS': [os.path.join(BASE_DIR, 'templates')] 63 | , 64 | 'APP_DIRS': True, 65 | 'OPTIONS': { 66 | 'context_processors': [ 67 | 'django.template.context_processors.debug', 68 | 'django.template.context_processors.request', 69 | 'django.contrib.auth.context_processors.auth', 70 | 'django.contrib.messages.context_processors.messages', 71 | ], 72 | }, 73 | }, 74 | ] 75 | 76 | WSGI_APPLICATION = 'luckysheet_obj.wsgi.application' 77 | 78 | # Database 79 | # https://docs.djangoproject.com/en/3.1/ref/settings/#databases 80 | 81 | DATABASES = { 82 | 'default': { 83 | 'ENGINE': 'django.db.backends.sqlite3', 84 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 85 | } 86 | } 87 | 88 | # Password validation 89 | # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators 90 | 91 | AUTH_PASSWORD_VALIDATORS = [ 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 100 | }, 101 | { 102 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 103 | }, 104 | ] 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/3.1/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'zh-hans' 110 | 111 | TIME_ZONE = 'Asia/Shanghai' 112 | 113 | USE_I18N = True 114 | 115 | USE_L10N = True 116 | 117 | USE_TZ = True 118 | 119 | # Static files (CSS, JavaScript, Images) 120 | # https://docs.djangoproject.com/en/3.1/howto/static-files/ 121 | 122 | 123 | # 静态文件收集 124 | STATIC_URL = '/static/' 125 | STATIC_ROOT = os.path.join(BASE_DIR, 'static') 126 | # STATICFILES_DIRS = [ 127 | # os.path.join(BASE_DIR, "/static/") 128 | # ] 129 | 130 | # 媒体文件收集 131 | MEDIA_URL = '/media/' 132 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 133 | 134 | import dwebsocket 135 | 136 | # 为所有的URL提供websocket,如果只是单独的视图需要可以不选 137 | MIDDLEWARE_CLASSES = ['dwebsocket.middleware.WebSocketMiddleware'] 138 | # 可以允许每一个单独的视图实用websockets 139 | WEBSOCKET_ACCEPT_ALL = True 140 | 141 | DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 142 | 143 | # 配置上传附件请求的表单包含的字段大小 144 | DATA_UPLOAD_MAX_NUMBER_FIELDS = 102400 145 | 146 | # 协同加载url 147 | WSS_LOAD_URL = 'http://127.0.0.1:8000/luckysheetloadurl/' 148 | 149 | # 协同更新url 150 | WSS_UPDATE_URL = 'ws://127.0.0.1:8000/luckysheetupdateurl' 151 | 152 | # redis配置 153 | CACHES = { 154 | "default": { 155 | "BACKEND": "django_redis.cache.RedisCache", 156 | "LOCATION": "redis://127.0.0.1:6379", 157 | "OPTIONS": { 158 | "CLIENT_CLASS": "django_redis.client.DefaultClient", 159 | "CONNECTION_POOL_KWARGS": {"max_connections": 1000} 160 | # "PASSWORD": "123", 161 | } 162 | } 163 | } 164 | 165 | REDIS_CONN = { 166 | 'HOST': '127.0.0.1', 167 | 'PORT': 6379, 168 | 'DB': 0, 169 | } 170 | -------------------------------------------------------------------------------- /luckysheet_obj/luckysheet_obj/urls.py: -------------------------------------------------------------------------------- 1 | """luckysheet_obj URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | from django.conf.urls import url, include 19 | from django.conf import settings 20 | from django.views import static 21 | from django.conf.urls.static import static as media_static 22 | 23 | urlpatterns = [ 24 | path('admin/', admin.site.urls), 25 | url(r'', include('lucky_sheet.urls', )), # data_process 26 | url(r'^static/(?P.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'), 27 | ] + media_static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 28 | -------------------------------------------------------------------------------- /luckysheet_obj/luckysheet_obj/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for luckysheet_obj project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luckysheet_obj.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /luckysheet_obj/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luckysheet_obj.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /luckysheet_obj/newip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "new ip is: "$1 4 | 5 | #echo "old file:" 6 | sed -n '/http:\/\/.*:3000/p' ./apps/lucky_sheet/templates/* 7 | 8 | echo "after switch" 9 | #注意:单引号会失效。 10 | sed -i "s/http:\/\/.*:3000/http:\/\/$1:3000/g" ./apps/lucky_sheet/templates/* 11 | #sed -n '/http:\/\/.*:3000/p' ./apps/lucky_sheet/templates/* 12 | 13 | SETTING="./luckysheet_obj/settings.py" 14 | 15 | vim $SETTING << EOF 16 | :/ALLOWED_HOSTS 17 | AxA, '$1'] 18 |  19 | :wq 20 | EOF 21 | 22 | 23 | sed -i "s/http:\/\/.*:.*\/luckysheetloadurl/http:\/\/$1:8080\/luckysheetloadurl/g" $SETTING 24 | sed -i "s/ws:\/\/.*:.*\/luckysheetupdateurl/ws:\/\/$1:8080\/luckysheetupdateurl/g" $SETTING 25 | 26 | #redis可能不用切 27 | #sed -i "s/redis:\/\/.*:6379/redis:\/\/$1:6379/g" $SETTING 28 | #sed -i "s/'HOST': '.*'/'HOST': '$1'/g" $SETTING 29 | -------------------------------------------------------------------------------- /luckysheet_obj/static/css/EwaAntH.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/EwaAntH.gif -------------------------------------------------------------------------------- /luckysheet_obj/static/css/EwaAntV.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/EwaAntV.gif -------------------------------------------------------------------------------- /luckysheet_obj/static/css/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/arrow-down.png -------------------------------------------------------------------------------- /luckysheet_obj/static/css/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/loading.gif -------------------------------------------------------------------------------- /luckysheet_obj/static/css/paint_16px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/paint_16px.ico -------------------------------------------------------------------------------- /luckysheet_obj/static/css/paint_24px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/paint_24px.ico -------------------------------------------------------------------------------- /luckysheet_obj/static/css/paint_32px.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/paint_32px.ico -------------------------------------------------------------------------------- /luckysheet_obj/static/css/waffle_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/luckysheet_obj/static/css/waffle_sprite.png -------------------------------------------------------------------------------- /readmeImages/config自定义图片配置.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/readmeImages/config自定义图片配置.png -------------------------------------------------------------------------------- /readmeImages/core自定义图片配置.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/readmeImages/core自定义图片配置.png -------------------------------------------------------------------------------- /readmeImages/微信截图_20210302010044.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/readmeImages/微信截图_20210302010044.png -------------------------------------------------------------------------------- /readmeImages/微信截图_20210302010418.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/readmeImages/微信截图_20210302010418.png -------------------------------------------------------------------------------- /readmeImages/自定义图片发送方式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/readmeImages/自定义图片发送方式.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.4 2 | asgiref==3.3.1 3 | Django==2.0 4 | dwebsocket==0.5.12 5 | JPype1==1.2.0 6 | Js2Py==0.70 7 | numpy==1.16.0 8 | pako==0.3.0 9 | PyExecJS==1.5.1 10 | pyjsparser==2.7.1 11 | pytz==2020.5 12 | six==1.15.0 13 | sqlparse==0.4.1 14 | typing-extensions==3.7.4.3 15 | tzlocal==2.1 16 | -------------------------------------------------------------------------------- /sheet_data_demo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blue-FatMan/luckysheet_django/ba830255c9b7435d613f2f51dfeee881758a61f7/sheet_data_demo.txt --------------------------------------------------------------------------------