diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..85de9cf93344b897ee6b677d44c645d747f82b0c --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +src diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000000000000000000000000000000..ea3a5175d6540483a0a0063c356c6d7fc78e8fa7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # [mengshukeji] +patreon: mengshukeji +open_collective: luckysheet +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: ['https://www.paypal.me/wbfsa'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index bc6a7855f6525c990c81951e697725af077455a7..2cb46e7bd143548cc481f9e20dde5bab909e583b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,26 +7,32 @@ assignees: '' --- + + + + + + **Describe the bug** -A clear and concise description of what the bug is. + **To Reproduce** -Steps to reproduce the behavior: -1. The first step -2. The second step -3. The third step -4. See error + +1. The first step: +2. The second step: +3. The third step: +4. See error: **What is expected?** -A clear and concise description of what you expected to happen. + **Screenshots or demo** -If applicable, add screenshots or online demo to help explain your problem.We will be more accurate when we retest. + **Environment** - - OS: [e.g. Windows,Mac,Linux] - - Browser Version: [e.g. Chrome Version 84.0.4147.105 (Official Build) (64-bit), Safari,Firefox,Edge] - - Luckysheet Version: [e.g. 1.0.1,latest] + - OS: + - Browser Version: + - Luckysheet Version: **Additional context** -Add any other context about the problem here. + diff --git a/.github/ISSUE_TEMPLATE/bug_report_zh.md b/.github/ISSUE_TEMPLATE/bug_report_zh.md index f9b07b9225446161e0147c0ac373bb1843591e57..6c7fb5010291ac6e263403a1f4b4061eb6081229 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_zh.md +++ b/.github/ISSUE_TEMPLATE/bug_report_zh.md @@ -7,26 +7,32 @@ assignees: '' --- + + + + + + **描述错误** -清楚简洁地描述错误是什么。 + **重现** -重现错误的步骤: -1.第一步操作 -2.第二步操作 -3.第三步操作 -4.最后看到了什么错误 + +1. 第一步操作: +2. 第二步操作: +3. 第三步操作: +4. 最后看到了什么错误: **期望的结果** -对您期望发生的结果简洁明了的描述。 + **屏幕截图或演示** -方便的话,贴上屏幕截图或在线链接复现问题,我们复测时会更精准 + **环境:** - -操作系统:[例如 Windows,Mac,Linux] - -浏览器 版本号:[例如 Chrome 版本 84.0.4147.105(正式版本) (64 位),Safari,Firefox,Edge] - -Luckysheet版本:[例如 1.0.1,最新] + - 操作系统: + - 浏览器 版本号: + - Luckysheet版本: **备注** -其他说明 + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index e05c9226068c637a8471404c4135c8f7d5f7c895..e32412e9f18506749b3b00a20a0dd18da2f9392d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,11 +7,17 @@ assignees: '' --- + + + + + + **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. + **Describe the solution you'd like** -A clear and concise description of what you want to happen. + **Additional context** -Add any other context or screenshots about the feature request here. + diff --git a/.github/ISSUE_TEMPLATE/feature_request_zh.md b/.github/ISSUE_TEMPLATE/feature_request_zh.md index 2912cd2e3e337f5eaa47773d35e6c517c1482d3a..7f0a43831a86cf2b74494de9fd228d65d70507b4 100644 --- a/.github/ISSUE_TEMPLATE/feature_request_zh.md +++ b/.github/ISSUE_TEMPLATE/feature_request_zh.md @@ -7,11 +7,18 @@ assignees: '' --- + + + + + + **您的功能请求与问题有关吗?** -清楚简洁地说明问题。 + + **描述您想要的解决方案** -对您想要的功能效果简洁明了的描述。 + **其他内容** -其他说明 + diff --git a/.github/workflows/gitee-mirror.yml b/.github/workflows/gitee-mirror.yml index ed5bc5d3a9c36e45938ee925f4cf88dbc220900a..e1c9e223c19c23f018d8e05b4f89b14a735c1845 100644 --- a/.github/workflows/gitee-mirror.yml +++ b/.github/workflows/gitee-mirror.yml @@ -33,7 +33,7 @@ jobs: # 填写地址:https://github.com/ly525/luban-h5/settings/secrets dst_token: ${{ secrets.GITEE_TOKEN }} # 项目同步白名单,可以选择填写多个,以英文逗号分割 - static_list: "Luckyexcel,Luckysheet,LuckysheetDemo,LuckyexcelDemo,LuckysheetDocs,chartMix" + static_list: "Luckyexcel,Luckysheet,LuckysheetDemo,LuckyexcelDemo,LuckysheetDocs,chartMix,LuckysheetServer" # 是否强制同步 force_update: true # 账号类型:对 luban-h5 而言是 user,因为是个人项目;如果是企业项目,请填写 org,因为是组织下的项目 diff --git a/.github/workflows/github-demo.yml b/.github/workflows/github-demo.yml new file mode 100644 index 0000000000000000000000000000000000000000..ac01116bd374062d002dfa3644fb2b65a6df049b --- /dev/null +++ b/.github/workflows/github-demo.yml @@ -0,0 +1,35 @@ +name: Luckysheet demo github pages deploy + +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout # 检查项目 + uses: actions/checkout@v2 + + - name: Set up Node.js # Nodejs版本 + uses: actions/setup-node@master + with: + node-version: 12.13.0 + + - name: Install dependencies & Generate static files # 安装依赖打包demo和文档 + run: | + node -v + npm install + npm install gulp -g + npm run build + + - name: Deploy LuckysheetDemo to GitHub Pages # 发布demo 到github pages + if: success() + uses: crazy-max/ghaction-github-pages@v2 + with: + repo: mengshukeji/LuckysheetDemo + target_branch: gh-pages + build_dir: dist + env: + GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/github-doc.yml b/.github/workflows/github-doc.yml new file mode 100644 index 0000000000000000000000000000000000000000..6d5d7489eb8efed327ae7c489cfef37bdb9315ee --- /dev/null +++ b/.github/workflows/github-doc.yml @@ -0,0 +1,35 @@ +name: Luckysheet docs github pages deploy + +on: + push: + tags: + - 'doc*' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout # 检查项目 + uses: actions/checkout@v2 + + - name: Set up Node.js # Nodejs版本 + uses: actions/setup-node@master + with: + node-version: 12.13.0 + + - name: Install dependencies & Generate static files # 安装依赖打包demo和文档 + run: | + node -v + npm install + npm install gulp -g + npm run docs:build + + - name: Deploy LuckysheetDocs to GitHub Pages # 发布docs 到github pages + if: success() + uses: crazy-max/ghaction-github-pages@v2 + with: + repo: mengshukeji/LuckysheetDocs + target_branch: gh-pages + build_dir: docs/.vuepress/dist + env: + GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index ab4b17ff22121811076b58b4ed0fae0dcaa83a6f..eecf1ec11adbeb86a1dca8bf1b8b10336c0b0d75 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,9 @@ node_modules package-lock.json dist -docs/.vuepress/dist \ No newline at end of file +docs/.vuepress/dist + +.idea +.history +.vs +.vscode \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e5ccb206426d83601a8268a1feb5928a1e28c8..77d475d2a175d32775741a9c5cb32f6542c01b52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,201 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.1.13](https://github.com/mengshukeji/Luckysheet/compare/v2.1.12...v2.1.13) (2021-01-19) + + +### Bug Fixes + +* **bug:** bug ([025823b](https://github.com/mengshukeji/Luckysheet/commit/025823b9f386c8048aa44b62f076a739eaa980c0)), closes [#435](https://github.com/mengshukeji/Luckysheet/issues/435) +* **bug:** bug ([a8ff967](https://github.com/mengshukeji/Luckysheet/commit/a8ff967be9cdcf3bbcb0045888951a26a852500a)), closes [#398](https://github.com/mengshukeji/Luckysheet/issues/398) +* **bug:** bug ([deb3a96](https://github.com/mengshukeji/Luckysheet/commit/deb3a965b881d747f9a2171f7d9c9f967d671901)) +* **bug:** bug ([5ce1f4a](https://github.com/mengshukeji/Luckysheet/commit/5ce1f4a0b753b7a95569b5285d749389e4d8b943)), closes [#433](https://github.com/mengshukeji/Luckysheet/issues/433) +* **bug:** bug ([932e821](https://github.com/mengshukeji/Luckysheet/commit/932e8215563248f97547ad21a429ef3f8ed0682b)), closes [#423](https://github.com/mengshukeji/Luckysheet/issues/423) [#424](https://github.com/mengshukeji/Luckysheet/issues/424) +* **bug:** bug ([06636f6](https://github.com/mengshukeji/Luckysheet/commit/06636f6a3c08128fe50aa880baabc9420fce4092)), closes [#154](https://github.com/mengshukeji/Luckysheet/issues/154) [#410](https://github.com/mengshukeji/Luckysheet/issues/410) [#416](https://github.com/mengshukeji/Luckysheet/issues/416) +* **bug:** history bug ([973eec8](https://github.com/mengshukeji/Luckysheet/commit/973eec8b71ea963bb23c9fe35c985e86c85ef019)) +* **bug:** setRangeFormat history ([065148b](https://github.com/mengshukeji/Luckysheet/commit/065148b5a97e9090479f401463c548c3346757ec)) +* **bug:** setRangeShow api ([5bbc45b](https://github.com/mengshukeji/Luckysheet/commit/5bbc45b68e807a2c58c328d93fe8079f3e56fa9f)) +* bug ([7412c5b](https://github.com/mengshukeji/Luckysheet/commit/7412c5b4f5aa0afd93f3e0210d3f3fe182c67273)) +* **bug:** 文本自动换行bug ([bc926e5](https://github.com/mengshukeji/Luckysheet/commit/bc926e5c49f008c14b4b5e1fdf13713fd6e995b5)) +* 换行 ([94022a4](https://github.com/mengshukeji/Luckysheet/commit/94022a48b6407523c5924e94c86fb2ada0fab301)) +* **bug:** 渲染换行空行 ([4162b7a](https://github.com/mengshukeji/Luckysheet/commit/4162b7a049f109715a9246ce610d05882d5a5f12)) +* **hook:** cellrender ([d444980](https://github.com/mengshukeji/Luckysheet/commit/d44498086fcd3b1b2bf75e95c6a236bc79a1df13)) +* **let:** let declar ([71ade32](https://github.com/mengshukeji/Luckysheet/commit/71ade32abd3989230db609ec37f92e931a4473f0)) +* **pivottable:** fix ([7cecb12](https://github.com/mengshukeji/Luckysheet/commit/7cecb12ae3a1a0bd0d5bdce803429d4464388e31)), closes [#439](https://github.com/mengshukeji/Luckysheet/issues/439) [#447](https://github.com/mengshukeji/Luckysheet/issues/447) +* **pivottable:** init ([5b19e8b](https://github.com/mengshukeji/Luckysheet/commit/5b19e8b06bdd95c2b799d2cc1d6ae677b96617cd)) +* **pivottable:** refresh ([78330c9](https://github.com/mengshukeji/Luckysheet/commit/78330c95db2735c8139b0320c2e81ee6f438adea)) + +### [2.1.12](https://github.com/mengshukeji/Luckysheet/compare/v2.1.11...v2.1.12) (2020-12-22) + + +### Features + +* **api:** find ([ea97233](https://github.com/mengshukeji/Luckysheet/commit/ea97233a668b3a682f6f0b1ad3fec251b01c33ab)) + + +### Bug Fixes + +* **bug:** bug ([9357792](https://github.com/mengshukeji/Luckysheet/commit/9357792fd1c49737398cf86cdf87d9dbfe35df26)), closes [#359](https://github.com/mengshukeji/Luckysheet/issues/359) [#360](https://github.com/mengshukeji/Luckysheet/issues/360) [#376](https://github.com/mengshukeji/Luckysheet/issues/376) [#382](https://github.com/mengshukeji/Luckysheet/issues/382) +* **bug:** bug ([19560eb](https://github.com/mengshukeji/Luckysheet/commit/19560eba3fe36cce4ee65ba3e8ac80ab7ec8d620)), closes [#367](https://github.com/mengshukeji/Luckysheet/issues/367) [#370](https://github.com/mengshukeji/Luckysheet/issues/370) +* **bug:** bug ([0f257e8](https://github.com/mengshukeji/Luckysheet/commit/0f257e8f153bb6c0cf38fb85200c587aabac164c)), closes [#361](https://github.com/mengshukeji/Luckysheet/issues/361) [#364](https://github.com/mengshukeji/Luckysheet/issues/364) [#365](https://github.com/mengshukeji/Luckysheet/issues/365) +* **bug:** copy bug ([2bcbab9](https://github.com/mengshukeji/Luckysheet/commit/2bcbab9a9f4727fd03930962a2dbdcaec3401597)) +* **feature:** functionButton ([5983cb0](https://github.com/mengshukeji/Luckysheet/commit/5983cb015e092e2edc1d3f27dba2d585fb4db099)), closes [#336](https://github.com/mengshukeji/Luckysheet/issues/336) [#381](https://github.com/mengshukeji/Luckysheet/issues/381) +* copy ([d177cc8](https://github.com/mengshukeji/Luckysheet/commit/d177cc8f5ee01d32932d1137920883209ec24be4)) + +### [2.1.10](https://github.com/mengshukeji/Luckysheet/compare/v2.1.9...v2.1.10) (2020-12-18) + + +### Bug Fixes + +* **rowtitle:** bug ([8faeffe](https://github.com/mengshukeji/Luckysheet/commit/8faeffee08840a5e8119d9fc8ac7204248105616)) + +### [2.1.9](https://github.com/mengshukeji/Luckysheet/compare/v2.1.8...v2.1.9) (2020-12-17) + + +### Bug Fixes + +* **bug:** bug ([54ae143](https://github.com/mengshukeji/Luckysheet/commit/54ae143aa268b5ce0253752a2a92b2ab22601b42)), closes [#222](https://github.com/mengshukeji/Luckysheet/issues/222) [#355](https://github.com/mengshukeji/Luckysheet/issues/355) +* **numeral:** userInfo ([871d381](https://github.com/mengshukeji/Luckysheet/commit/871d3819f7c734b604f19da1ba81bf5ee0ea0814)), closes [#338](https://github.com/mengshukeji/Luckysheet/issues/338) + +### [2.1.8](https://github.com/mengshukeji/Luckysheet/compare/v2.1.7...v2.1.8) (2020-12-16) + + +### ⚠ BREAKING CHANGES + +* **bug:** n + +### Features + +* **api add:** image ([16131b2](https://github.com/mengshukeji/Luckysheet/commit/16131b2776cd278bb7bddae674c206aa739f3a46)), closes [#270](https://github.com/mengshukeji/Luckysheet/issues/270) +* **changlang:** changLang ([cbc81e9](https://github.com/mengshukeji/Luckysheet/commit/cbc81e9e17ca56e09f9e697e5372650f3d6a476b)), closes [#318](https://github.com/mengshukeji/Luckysheet/issues/318) +* **collaborative editing:** collaborative editing ([6fe8726](https://github.com/mengshukeji/Luckysheet/commit/6fe87260e8986cd83e7bcf655594389c01739107)), closes [#199](https://github.com/mengshukeji/Luckysheet/issues/199) [#201](https://github.com/mengshukeji/Luckysheet/issues/201) [#202](https://github.com/mengshukeji/Luckysheet/issues/202) +* **condition format:** formula condition ([6c98bde](https://github.com/mengshukeji/Luckysheet/commit/6c98bded8dcf16aab4bcc89a63a62d3878c06cd3)), closes [#186](https://github.com/mengshukeji/Luckysheet/issues/186) +* **demo:** proxy ([bc64807](https://github.com/mengshukeji/Luckysheet/commit/bc64807de9e3f8f60ddc529c6b795c95aff1884c)) +* **feature:** closeWebsocket api and ctrl ; ([9153bc7](https://github.com/mengshukeji/Luckysheet/commit/9153bc799db2aea947f2ba70a7b947daca55b844)), closes [#328](https://github.com/mengshukeji/Luckysheet/issues/328) [#326](https://github.com/mengshukeji/Luckysheet/issues/326) +* **hook:** add ([2c6b1c2](https://github.com/mengshukeji/Luckysheet/commit/2c6b1c21b3ad6535671745fd7483d9318f7e55ec)) +* **print feature:** develop ([a0921b6](https://github.com/mengshukeji/Luckysheet/commit/a0921b62d73b8b3edcaf1c72dd9e35cd43848f2f)) + + +### Bug Fixes + +* **add forcecaculation config:** add ([e96d210](https://github.com/mengshukeji/Luckysheet/commit/e96d210fe544caa8b912720a274374bccb0cef7d)) +* **bug:** bug ([95e26c3](https://github.com/mengshukeji/Luckysheet/commit/95e26c3fa07fa74c238c0c7b96b5b7ff91b79889)), closes [#330](https://github.com/mengshukeji/Luckysheet/issues/330) +* **bug:** bug ([c003f8a](https://github.com/mengshukeji/Luckysheet/commit/c003f8a4281f346c89226061851f71693208574a)), closes [#184](https://github.com/mengshukeji/Luckysheet/issues/184) [#337](https://github.com/mengshukeji/Luckysheet/issues/337) +* **bug:** bug ([4900b4a](https://github.com/mengshukeji/Luckysheet/commit/4900b4a0f2a82528e130d7281bb1f153ed3297fe)), closes [#331](https://github.com/mengshukeji/Luckysheet/issues/331) +* **bug:** bug ([b93ea6b](https://github.com/mengshukeji/Luckysheet/commit/b93ea6b66e444d387f230602dd02034b4b237369)), closes [#284](https://github.com/mengshukeji/Luckysheet/issues/284) [#296](https://github.com/mengshukeji/Luckysheet/issues/296) +* **bug:** bug ([57ff2b9](https://github.com/mengshukeji/Luckysheet/commit/57ff2b959b4be8d5cad559624d92f00e996d315f)), closes [#182](https://github.com/mengshukeji/Luckysheet/issues/182) [#220](https://github.com/mengshukeji/Luckysheet/issues/220) +* **bug:** bug ([31bdc4f](https://github.com/mengshukeji/Luckysheet/commit/31bdc4feae0037c92074b244e9e52363298b164d)), closes [#263](https://github.com/mengshukeji/Luckysheet/issues/263) +* **bug:** bug ([385bc03](https://github.com/mengshukeji/Luckysheet/commit/385bc039c91727655ea771c7a48d6f0890a275fb)), closes [#243](https://github.com/mengshukeji/Luckysheet/issues/243) [#226](https://github.com/mengshukeji/Luckysheet/issues/226) +* **bug:** bug ([88aa6c5](https://github.com/mengshukeji/Luckysheet/commit/88aa6c5b59964078c6a9cfffb41308c196a44953)), closes [#278](https://github.com/mengshukeji/Luckysheet/issues/278) [#276](https://github.com/mengshukeji/Luckysheet/issues/276) [#267](https://github.com/mengshukeji/Luckysheet/issues/267) [#215](https://github.com/mengshukeji/Luckysheet/issues/215) +* **bug:** copy to excel ([5cf72ec](https://github.com/mengshukeji/Luckysheet/commit/5cf72ec0781f0e3b2ddc77eac228812507ce66a2)), closes [#319](https://github.com/mengshukeji/Luckysheet/issues/319) +* **bug:** data verification range select ([6d60679](https://github.com/mengshukeji/Luckysheet/commit/6d606791abaa5d410ce68cfb49f8bc9c2dfaf609)) +* **cell:** render ([ba21140](https://github.com/mengshukeji/Luckysheet/commit/ba2114055ba62b0401c76075054588642fa4fbf1)) +* **demo:** websocket url ([cf77ec3](https://github.com/mengshukeji/Luckysheet/commit/cf77ec3307c0d44bc5303f606762c003d4f50b86)) +* **dynamic array refresh fix:** fix ([b7d634f](https://github.com/mengshukeji/Luckysheet/commit/b7d634f0425dd8cb337784b10094d0952edc460a)) +* **fix #209:** highlight ([ab2d8b7](https://github.com/mengshukeji/Luckysheet/commit/ab2d8b7b5467200e12c8d4c1ece014ebfc6ee7cc)), closes [#209](https://github.com/mengshukeji/Luckysheet/issues/209) +* **fix #209 ,fix #219:** highlight follow checkout keep highlight ([c547596](https://github.com/mengshukeji/Luckysheet/commit/c5475964e41eb7bb12d87b679dffba4b988abb30)), closes [#209](https://github.com/mengshukeji/Luckysheet/issues/209) [#219](https://github.com/mengshukeji/Luckysheet/issues/219) +* **fix #209 fix #219:** highlight follow checkout page ([0a5ca86](https://github.com/mengshukeji/Luckysheet/commit/0a5ca86ab808d2cb1da8cb14d93c5d787c50f540)), closes [#209](https://github.com/mengshukeji/Luckysheet/issues/209) [#219](https://github.com/mengshukeji/Luckysheet/issues/219) +* **fix #209 fix #219:** highlight follow, checkout keep highlight ([2c7b0bb](https://github.com/mengshukeji/Luckysheet/commit/2c7b0bbdf5adf1b2a6fc537e37825ab01ee3cf96)), closes [#209](https://github.com/mengshukeji/Luckysheet/issues/209) [#219](https://github.com/mengshukeji/Luckysheet/issues/219) +* **fix #290:** userinfo ([80d67e1](https://github.com/mengshukeji/Luckysheet/commit/80d67e157d010f8e59c472b2e6046c04efe9b966)), closes [#290](https://github.com/mengshukeji/Luckysheet/issues/290) +* **fix #290:** userinfo ([dddfc8f](https://github.com/mengshukeji/Luckysheet/commit/dddfc8f9418991466025682309e73950da6611cd)), closes [#290](https://github.com/mengshukeji/Luckysheet/issues/290) +* **fix #290:** userinfo ([27a770e](https://github.com/mengshukeji/Luckysheet/commit/27a770ee863356d2ef120970723bb048c510d9aa)), closes [#290](https://github.com/mengshukeji/Luckysheet/issues/290) +* **main canvas:** bottom space ([23c8a78](https://github.com/mengshukeji/Luckysheet/commit/23c8a78cb3bd387c7c609250de41b187105475b5)) +* **tojson:** bug ([1c94783](https://github.com/mengshukeji/Luckysheet/commit/1c94783677bcfe6488caf39028f18e5b2505a737)) +* setCellValue API 可设置自定义的属性,不显式设置v, v 不会丢失 ([6d45cf2](https://github.com/mengshukeji/Luckysheet/commit/6d45cf2ce63dca282f4a40ce5aaf628f94bfc8d1)) +* jfrefreshgrid 函数第二个参数应该是个数组 ([c7cf87a](https://github.com/mengshukeji/Luckysheet/commit/c7cf87a49b1b8ce64fb21249cd05950fabc0e546)) +* setCellFormat data 引用 ([ed50e47](https://github.com/mengshukeji/Luckysheet/commit/ed50e47b44e079bc76419ba3f96f04d964c70610)) +* setCellValue 刷新页面时的历史记录问题 ([a2cf969](https://github.com/mengshukeji/Luckysheet/commit/a2cf96978f97b289d603aa404bcfaf8a0d64f87b)) +* 修复alert ([94e0020](https://github.com/mengshukeji/Luckysheet/commit/94e0020acd49aed50810e6c133688c950690ab3c)) +* 修复主动关闭socket仍然alert弹窗 ([e0bdb2c](https://github.com/mengshukeji/Luckysheet/commit/e0bdb2c4015355e428c5e8d567196d607606a38e)) +* 修复主动关闭socket定时器仍运行问题 ([82a8731](https://github.com/mengshukeji/Luckysheet/commit/82a87319342c698c1a1a58972a9d59ab3b7e91cd)) +* 初始化表单状态下标调整 ([3a54312](https://github.com/mengshukeji/Luckysheet/commit/3a54312c93a6daebf575639dd612e0d01be2a296)) +* 复制选区虚线框正确显示 ([9d6a2ee](https://github.com/mengshukeji/Luckysheet/commit/9d6a2eed05ae660fb65515217e156817fc4d6443)) +* 解决单击非时间日期单元格后还会跳出日期时间弹框 ([fc9eb4e](https://github.com/mengshukeji/Luckysheet/commit/fc9eb4e7984af6991b79acae6a2a5c0bbea5254f)) +* **fix forcecaculation feature:** complete ([7568ceb](https://github.com/mengshukeji/Luckysheet/commit/7568ceb442acdfdedeb6d6e4d623bdcd2a8c4018)) +* **formula contain text bug:** add iscell method ([89358d3](https://github.com/mengshukeji/Luckysheet/commit/89358d36045baca791f2b5e9d2152349bf5903cf)) +* **formula update fix:** formula update only one level, when cell value change. Fix it ([cf6c5be](https://github.com/mengshukeji/Luckysheet/commit/cf6c5be8a45616e1002db0ff4b04b47c3ed4c38e)) + +### [2.1.7](https://github.com/mengshukeji/Luckysheet/compare/v2.1.6...v2.1.7) (2020-11-26) + + +### Features + +* **demo:** tool function ([3baf93c](https://github.com/mengshukeji/Luckysheet/commit/3baf93cdb57238ee73ace3e7b9bca142fad81584)) +* 修改日期能够正常的弹出格式框和设置对应格式的日期时间 ([2c27044](https://github.com/mengshukeji/Luckysheet/commit/2c2704473c1c5a77091acda45a46f39ebbad3592)) +* 修改日期能够正常的弹出格式框和设置对应格式的日期时间 ([67c44e7](https://github.com/mengshukeji/Luckysheet/commit/67c44e7a68d948fcb90bd499ecc15cfb2bea5127)) + + +### Bug Fixes + +* **formula:** function ([dad6e2b](https://github.com/mengshukeji/Luckysheet/commit/dad6e2b2d144a31f4cfaaf84c90588e1a02ee006)) +* **formular:** docs ([ddac582](https://github.com/mengshukeji/Luckysheet/commit/ddac582f696898a1a46fc0ce3eb5d245d20077ae)) +* **hook:** function ([fb43a56](https://github.com/mengshukeji/Luckysheet/commit/fb43a56222c3d4c77b84efa9ff37eed8e1333a1a)) +* **hook function:** cellupdate ([5e8f71f](https://github.com/mengshukeji/Luckysheet/commit/5e8f71f32e5104769dbe6e0c61de3cd26b286344)) +* ie11右下角菜单图标会出现错位 ([34fd6e7](https://github.com/mengshukeji/Luckysheet/commit/34fd6e74cb87f9563ff28979d9f5f8a192fb558a)) +* 重复create会出现很多问题 ([8f22790](https://github.com/mengshukeji/Luckysheet/commit/8f227904fe9600ea17fdc346924d73c3bc81a041)) + +### [2.1.6](https://github.com/mengshukeji/Luckysheet/compare/v2.1.5...v2.1.6) (2020-11-23) + + +### ⚠ BREAKING CHANGES + +* yes + +q + +### Features + +* **api:** hook function ([a0db530](https://github.com/mengshukeji/Luckysheet/commit/a0db530295bca24b81b02171a073f6b6f1227ce6)) +* **hook:** add hook function ([215dec2](https://github.com/mengshukeji/Luckysheet/commit/215dec27d796ee9b5be7857a425093a53db84332)) +* q ([54a42a2](https://github.com/mengshukeji/Luckysheet/commit/54a42a274a96eb3334602fd0de65e1d4b2fc492a)) +* **bottom alignment of english letters:** fix ([a596d2f](https://github.com/mengshukeji/Luckysheet/commit/a596d2fcd617cac196e3336a8dfe8ac9ba58c9f7)) +* **config:** sheetRightClickConfig ([59c7cb3](https://github.com/mengshukeji/Luckysheet/commit/59c7cb34a33450e59023fd1ae5e615f3e40ef0d9)) +* add underline button ([df56ba6](https://github.com/mengshukeji/Luckysheet/commit/df56ba6f359bb12eb765b26b973100c554601eca)) +* use npm dependencies ([e4bd439](https://github.com/mengshukeji/Luckysheet/commit/e4bd439a0e96dbec0cb3a45e01aaecb129fab2ad)) +* **row and column width:** batch change the height and width of the selected row and column ([956bd2a](https://github.com/mengshukeji/Luckysheet/commit/956bd2a01012b429c58a14b5b88d02a02350b662)) + + +### Bug Fixes + +* **bug fix:** [#26](https://github.com/mengshukeji/Luckysheet/issues/26) [#91](https://github.com/mengshukeji/Luckysheet/issues/91) ([a26ffd8](https://github.com/mengshukeji/Luckysheet/commit/a26ffd8ac388db475dfd38e4ae83098eeeee8bc8)) +* **cooperative:** bug ([9e48c72](https://github.com/mengshukeji/Luckysheet/commit/9e48c72a47022188d387558b5b5f3a6250878c65)) +* **demo:** ie11 ([e7ddc39](https://github.com/mengshukeji/Luckysheet/commit/e7ddc397c8b1e421c63f3e9f661ced99a3d81556)), closes [#234](https://github.com/mengshukeji/Luckysheet/issues/234) +* **fix #212:** cancel highlight ([289d3ef](https://github.com/mengshukeji/Luckysheet/commit/289d3ef46ebadf9662d272109a1f24d2a8b0dc1d)), closes [#212](https://github.com/mengshukeji/Luckysheet/issues/212) +* **fix #219:** checkout ([15dca04](https://github.com/mengshukeji/Luckysheet/commit/15dca040840d228f6326d4eecad917df38e15f04)), closes [#219](https://github.com/mengshukeji/Luckysheet/issues/219) +* **fix #219:** clear info ([080f027](https://github.com/mengshukeji/Luckysheet/commit/080f0275b80143026cc30e8450c901715fc51c19)), closes [#219](https://github.com/mengshukeji/Luckysheet/issues/219) +* sheet menu position ([a40f679](https://github.com/mengshukeji/Luckysheet/commit/a40f679fde6700c90cd66c66bb070afabb31fb83)) +* **iconfont:** conflict ([bf4d539](https://github.com/mengshukeji/Luckysheet/commit/bf4d539dddc4cef232f8eae602b39980ded5b208)) +* **mousemove hook error:** fix ([89b93e7](https://github.com/mengshukeji/Luckysheet/commit/89b93e71460750be8f736df0dbc13675daf5d72d)) + +### [2.1.5](https://github.com/mengshukeji/Luckysheet/compare/v2.1.4...v2.1.5) (2020-11-03) + + +### Features + +* **cell date picker:** cell date picker and bug solve ([2996ae9](https://github.com/mengshukeji/Luckysheet/commit/2996ae9cab724714903d00e0b63022abc4a1a3b6)) +* **cell hooks add:** go to document for detail ([927ff46](https://github.com/mengshukeji/Luckysheet/commit/927ff46949f688a5bcffcb3fe48dc6b4b12b61c9)) +* **config:** custom menu button config ([14eb78e](https://github.com/mengshukeji/Luckysheet/commit/14eb78e153cbce726adf9e093702f9b93af1fa03)) +* **config:** sheetbar ([3555746](https://github.com/mengshukeji/Luckysheet/commit/3555746f4cc8ef2c1fe163a34edd428f1a6377ed)) +* **date format:** date format Chinese ([8f8d0cb](https://github.com/mengshukeji/Luckysheet/commit/8f8d0cb8c5563a31afba3fe11b525e6bccd5eb56)) +* **hyperlink:** add hyperlink function ([439dff4](https://github.com/mengshukeji/Luckysheet/commit/439dff4330ab5053643331286091d44ae910fb8d)) +* **hyperlink:** perfect hyperlink function ([5adfc60](https://github.com/mengshukeji/Luckysheet/commit/5adfc6055bf4cfed7f1ff40933d292057196bc7e)) +* **statisticbar:** config docs ([c1ed417](https://github.com/mengshukeji/Luckysheet/commit/c1ed417074e89e665f9ef39ee186db9106904c4e)) +* **tojson:** api/docs ([8e410f5](https://github.com/mengshukeji/Luckysheet/commit/8e410f5d3cd61724230b3024898d6de3c6c41101)) + + +### Bug Fixes + +* **bug:** bug ([ad73f9a](https://github.com/mengshukeji/Luckysheet/commit/ad73f9a679d77721d8af0a483dffe70b90e56412)), closes [#129](https://github.com/mengshukeji/Luckysheet/issues/129) +* **bug:** bug ([801cbe5](https://github.com/mengshukeji/Luckysheet/commit/801cbe5a8040d80f2e672b3607c0b92c922281a9)) +* **bug:** bug ([f8716c1](https://github.com/mengshukeji/Luckysheet/commit/f8716c18db05c7ab8bf59d1feb0dc4c3b364c560)), closes [#67](https://github.com/mengshukeji/Luckysheet/issues/67) [#85](https://github.com/mengshukeji/Luckysheet/issues/85) +* **bug:** bug ([0909f5e](https://github.com/mengshukeji/Luckysheet/commit/0909f5e4c957e3d3248a8c86d6e092c5a5396112)), closes [#142](https://github.com/mengshukeji/Luckysheet/issues/142) [#132](https://github.com/mengshukeji/Luckysheet/issues/132) +* **bug:** dataVerification and sheet move and delete cell bug ([4815d86](https://github.com/mengshukeji/Luckysheet/commit/4815d86ce564da43aa1ced3b48d38e88afc39f77)) +* **conflict:** conflict ([b11de26](https://github.com/mengshukeji/Luckysheet/commit/b11de26c4d2dbdd7e9d4363558e95d4433f26585)) +* **conflict:** toolbar ([8cfa6ac](https://github.com/mengshukeji/Luckysheet/commit/8cfa6ac1bec8bcb156fe45e8c488aa7026b65738)) +* **fix bug with inline string rotate wrap:** add change to max, fix height error ([1988687](https://github.com/mengshukeji/Luckysheet/commit/198868719ffb19738ee5ecc1ee060a0840fa92df)) +* **hide row/column:** right click menu ([8070858](https://github.com/mengshukeji/Luckysheet/commit/8070858f6c35f11ee8cf2692d8828d0e78c46d92)), closes [#37](https://github.com/mengshukeji/Luckysheet/issues/37) +* **restore demo:** restore demo ([e799862](https://github.com/mengshukeji/Luckysheet/commit/e7998627400b82bf082bad3c984f4d26e3c9f43a)) + ### [2.1.3](https://github.com/mengshukeji/Luckysheet/compare/v2.1.2...v2.1.3) (2020-10-22) diff --git a/README-zh.md b/README-zh.md index 4ad471fd716683f876cdc05e2dde3962bad5042c..2a4deb860ab138ef6d9ba5b38c208235d0c4b201 100644 --- a/README-zh.md +++ b/README-zh.md @@ -2,152 +2,98 @@ ![logo](/docs/.vuepress/public/img/logo_text.png) - +# Luckysheet 3.x 已更名为 [Univer](https://github.com/dream-num/univer) + 简体中文 | [English](./README.md) ## 介绍 🚀Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 -> Luckysheet最近参加了“2020年度OSC中国开源项目评选”,为了支持Luckysheet更好的得到关注和发展,请大家帮忙投票: [https://www.oschina.net/p/luckysheet](https://www.oschina.net/p/luckysheet)。 ## 相关链接 | 源码 | 文档 | Demo | 插件Demo | 论坛 | | ------ | -------- | ------ | ------ | ------ | - | [Github](https://github.com/mengshukeji/Luckysheet)| [在线文档](https://mengshukeji.github.io/LuckysheetDocs/zh/) | [在线Demo](https://mengshukeji.github.io/LuckysheetDemo) | [导入Excel Demo](https://mengshukeji.github.io/LuckyexcelDemo/) | [中文论坛](https://support.qq.com/product/288322) | + | [Github](https://github.com/mengshukeji/Luckysheet)| [在线文档](https://dream-num.github.io/LuckysheetDocs/zh/) | [在线Demo](https://dream-num.github.io/LuckysheetDemo) / [协同编辑Demo](http://luckysheet.lashuju.com/demo/) | [导入Excel Demo](https://dream-num.github.io/LuckyexcelDemo/) | [中文论坛](https://support.qq.com/product/288322) | | [Gitee镜像](https://gitee.com/mengshukeji/Luckysheet)| [Gitee在线文档](https://mengshukeji.gitee.io/LuckysheetDocs/zh/) | [Gitee在线Demo](https://mengshukeji.gitee.io/luckysheetdemo/) | [Gitee导入Excel Demo](https://mengshukeji.gitee.io/luckyexceldemo/) | [Google Group](https://groups.google.com/g/luckysheet) | - ![演示](/docs/.vuepress/public/img/LuckysheetDemo.gif) ## 插件 -- excel导入导出库: [Luckyexcel](https://github.com/mengshukeji/Luckyexcel) -- 图表插件: [chartMix](https://github.com/mengshukeji/chartMix) +- [Luckyexcel](https://gitee.com/mengshukeji/Luckyexcel):excel导入导出库 +- [chartMix](https://gitee.com/mengshukeji/chartMix):图表插件 + +## 生态 + +| 工程 | 描述 | +|---------|-------------| +| [Luckysheet Vue] | 在vue cli 3项目中使用Luckysheet和Luckyexcel| +| [Luckysheet Vue3] | 在vue3, vite项目中使用Luckysheet和Luckyexcel| +| [Luckysheet React] | 在React项目中使用Luckysheet | +| [Luckyexcel Node] | 在koa2中使用Luckyexcel | +| [Luckysheet Server] | Java后台Luckysheet Server | +| [Luckysheet Server Starter] | LuckysheetServer 一键docker部署 | + +[Luckysheet Vue]: https://gitee.com/mengshukeji/luckysheet-vue +[Luckysheet Vue3]: https://gitee.com/hjwforever/luckysheet-vue3-vite.git +[Luckysheet React]: https://gitee.com/mengshukeji/luckysheet-react +[Luckyexcel Node]: https://gitee.com/mengshukeji/Luckyexcel-node +[Luckysheet Server]: https://gitee.com/mengshukeji/LuckysheetServer +[Luckysheet Server Starter]: https://gitee.com/mengshukeji/LuckysheetServerStarter ## 特性 -### 🛠️格式设置 -+ **样式** (修改字体样式,字号,颜色或者其他通用的样式) -+ **条件格式** (突出显示所关注的单元格或单元格区域;强调异常值;使用数据栏、色阶和图标集(与数据中的特定变体对应)直观地显示数据) -+ **文本对齐及旋转** -+ **支持文本的截断、溢出、自动换行** -+ **数据类型** - + **货币, 百分比, 数字, 日期** - + **Custom** (和excel保持一致,例如: `##,###0.00` , `$1,234.56$##,###0.00_);[Red]($##,###0.00)`, `_($* ##,###0.00_);_(...($* "-"_);_(@_)`, `08-05 PM 01:30MM-dd AM/PM hh:mm` ) -+ **单元格内多样式** (Alt+Enter单元格内换行、上标、下标、单元格内科定义每个文字的不同样式) - -### 🧬单元格 -+ **拖拽选取来修改单元格** (对选区进行操作,可以拖动四边来移动选区,也可以在右下角对选区进行下拉填充操作) -+ **选取下拉填充** (对于一个1,2,3,4,5的序列,将会按照间隔为1进行下拉填充,而对2,4,6,8将会以2作为间隔。支持等差数列,等比数列,日期,周,天,月,年,中文数字填充) -+ **自动填充选项** (下拉填充后,会出现填充选项的菜单,支持选择复制,序列,仅格式,只填充格式,天,月,年的选择) -+ **多选区操作** (可以按住Ctrl键进行单元格多选操作,支持多选区的复制粘贴) -+ **查找和替换** (对内容进行查找替换,支持正则表达式,整词,大小写敏感) -+ **定位** (可以根据单元格的数据类型进行自动定位并选中,选中后可以批量进行格式等操作) -+ **合并单元格** -+ **数据验证(表单功能)** (支持Checkbox, drop-down list, datePicker) - -### 🖱️行和列操作 -+ **隐藏,插入,删除行或列** -+ **冻结行或列** (支持冻结首行和首列,冻结到选区,冻结调节杆可以进行拖动操作) -+ **文本分列** (可以把文本根据不同符号进行拆分,和excel的分列功能类似) - -### 🔨操作体验 -+ **撤销/重做** -+ **复制/粘贴/剪切操作** (支持Luckysheet到excel和excel到Luckysheet带格式的互相拷贝) -+ **快捷键支持** (快捷键操作保持与excel一致,如果有不同或者缺失请反馈给我们) -+ **格式刷** (与google sheet类似) -+ **任意选区拖拽** (选择单元格,输入公式,插入图表,会与选区相关,可以通过任意拖动和放大缩小选区来改变与之关联的参数) - -### ⚙️公式和函数 -+ **内置公式** - + 数学 (SUMIFS, AVERAGEIFS, SUMIF, SUM, etc.) - + 文本 (CONCATENATE, REGEXMATCH, MID) - + 日期 (DATEVALUE, DATEDIF, NOW, WEEKDAY, etc.) - + 财务 (PV, FV, IRR, NPV, etc.) - + 逻辑 (IF, AND, OR, IFERROR, etc.) - + 查找和引用 (VLOOKUP, HLOOkUP, INDIRECT, OFFSET, etc.) - + 动态数组 (Excel2019新函数,SORT,FILTER,UNIQUE,RANDARRAY,SEQUENCE) -+ **公式支持数组** (={1,2,3,4,5,6}, Crtl+Shift+Enter) -+ **远程公式** (DM_TEXT_TFIDF, DM_TEXT_TEXTRANK,DATA_CN_STOCK_CLOSE etc. Need remote interface, can realize complex calculation) -+ **自定义公式** (根据身份证识别年龄,性别,生日,省份,城市等. AGE_BY_IDCARD, SEX_BY_IDCARD, BIRTHDAY_BY_IDCARD, PROVINCE_BY_IDCARD, CITY_BY_IDCARD, etc. 可以任意加入自己的公式哦) - -### 📐表格操作 -+ **筛选** (支持颜色、数字、字符、日期的筛选) -+ **排序** (同时加入多个字段进行排序) - -### 📈数据透视表 -+ **字段拖拽** (操作方式与excel类似,拖动字段到行、列、数值、筛选等4个区域) -+ **聚合方式** (支持汇总、计数、去重计数、平均、最大、最小、中位数、协方差、标准差、方差等计算) -+ **筛选数据** (可对字段进行筛选后再进行汇总) -+ **数据透视表下钻** (双击数据透视表中的数据,可以下钻查看到明细,操作方式与excel一致) -+ **根据数据透视表新建图表** (数据透视表产生的数据也可以进行图表的制作) - -### 📊图表 -+ **支持的图表类型** (目前折线图、柱状图、面积图、条形图、饼图可以使用,散点图、雷达图、仪表盘、漏斗图正在接入,其他图表正在陆续开发中,请大家给予建议) -+ **关于图表插件** (图表使用了一个中间插件[ChartMix](https://github.com/mengshukeji/chartMix)(MIT协议): 目前支持ECharts,正在逐步接入Highcharts、阿里G2、amCharts、googleChart、chart.js) -+ **Sparklines小图** (以公式的形式进行设置和展示,目前支持:折线图、面积图、柱状图、累积图、条形图、离散图、三态图、饼图、箱线图等) - -### ✍️分享及写作 -+ **评论** (评论的删除、添加、修改、隐藏) -+ **共享编辑** (支持多用户共享编辑,内置API) - -### 📚插入对象 -+ **插入图片** (支持JPG,PNG,SVG的插入、修改和删除,并且随表格的变动而产生变化) - -### ⚡Luckysheet专有 -+ **矩阵计算** (通过右键菜单进行支持:对选区内的数据进行转置、旋转、数值计算) -+ **截图** (把选区的内容进行截图展示) -+ **复制到其他格式** (右键菜单的"复制为", 支持复制为json、array、对角线数据、去重等) -+ **EXCEL导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出,导出正在开发) - -### ⏱️未来开发计划 -+ **打印及设置** (像excel一样进行打印设置,并导出为图片或者PDF) -+ **树形菜单** (类似excel中的分级显示(分组)) -+ **表格新功能** (类似excel中表格的筛选器和切片器) -+ **CSV,TXT导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出) -+ **插入svg形状** (支持[Pen tool](https://github.com/mengshukeji/Pentool)的插入、修改和删除,并且随表格的变动而产生变化) -+ **文档** (完善文档和API) -+ **敬请期待...** (可以提出好的建议给我们) - -## 环境 -[Node.js](https://nodejs.org/en/) Version >= 6 +- **格式设置**:样式,条件格式,文本对齐及旋转,文本截断、溢出、自动换行,多种数据类型,单元格内多样式 +- **单元格**:拖拽,下拉填充,多选区,查找和替换,定位,合并单元格,数据验证 +- **行和列操作**:隐藏、插入、删除行或列,冻结,文本分列 +- **操作体验**:撤销、重做,复制、粘贴、剪切,快捷键,格式刷,选区拖拽 +- **公式和函数**:内置公式,远程公式,自定义公式 +- **表格操作**:筛选,排序 +- **增强功能**:数据透视表,图表,评论,共享编辑,插入图片,矩阵计算,截图,复制到其他格式,EXCEL导入及导出等 -## 安装 -``` -npm install -npm install gulp -g -``` +更详细的功能列表,请查阅:[特性](https://dream-num.github.io/LuckysheetDocs/zh/guide/#%E7%89%B9%E6%80%A7) -## 开发 -开发 -``` -npm run dev -``` -打包 -``` -npm run build -``` +## 📖 学习资源 + +- 新用户优先阅读:[用户指引](https://github.com/mengshukeji/Luckysheet/wiki/User-Guide) +- 社区提供的教程、学习资料及配套解决方案请查阅:[教程与资源](https://dream-num.github.io/LuckysheetDocs/zh/guide/resource.html) + +## 📜 更新日志 + +每个版本的详细更改都记录在 [CHANGELOG.md](CHANGELOG.md) 中。 + +## ❗️ 问题反馈 + +在反馈问题之前,请确保仔细阅读 [如何提交问题](https://dream-num.github.io/LuckysheetDocs/zh/guide/contribute.html#如何提交问题)。 不符合准则的问题可能会立即被移除。 + +## ✅ 开发计划 + +通过 [GitHub Projects](https://github.com/mengshukeji/Luckysheet/projects/1) 管理 + +## 💪 贡献 + +在提交PR之前,请确保仔细阅读 [贡献指南](https://dream-num.github.io/LuckysheetDocs/zh/guide/contribute.html)。 ## 用法 -#### 第一步 +### 第一步 通过CDN引入依赖 ``` - - - - - - + + + + + + ``` -#### 第二步 +### 第二步 指定一个表格容器 ```
``` -#### 第三步 +### 第三步 创建一个表格 ``` ``` +## 开发 + +### 环境 +[Node.js](https://nodejs.org/en/) Version >= 6 + +### 安装 +``` +npm install +npm install gulp -g +``` +### 开发 +``` +npm run dev +``` +### 打包 +``` +npm run build +``` ## 合作项目 - [鲁班h5](https://github.com/ly525/luban-h5) -- [excelize](https://github.com/360EntSecGroup-Skylar/excelize) - [h5-Dooring](https://github.com/MrXujiang/h5-Dooring) - -## 加入共建 - -1. 任何疑问或者建议,欢迎提交[Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose) -2. 如果您想为 Luckysheet 实现一个重要功能,需要先撰写 RFC 文档,按照Luckysheet的 [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) 机制进行操作,在经过社区讨论完善后才可以进行代码的提交。 -3. 如果您对Luckysheet感兴趣,非常欢迎加入开发组,一起来完善这个插件(下方扫码添加小编微信备注:共建),有4类任务可以认领 - - BUG修复 - - 新功能添加 - - 文档 - - 推广 - - 您将收获: - - Luckysheet官方readme文档贡献者链接 - - 参与大型开源项目,技术和视野提升 +- [Furion](https://gitee.com/monksoul/Furion) +- [AFFiNE.PRO](https://github.com/toeverything/AFFiNE) ## 交流 -- 添加小编微信,拉你进Luckysheet开发者交流微信群,备注:加群 - - 微信群 +- [Github 论坛](https://github.com/mengshukeji/Luckysheet/discussions) +- 以下扫码加入官方微信群或者QQ群 -或者 +| 加小编微信: msuniver,备注:加群 | QQ群:767964895 | +|---|---| +|| | -- 加入Luckysheet开发者交流QQ群 - - 微信群 [英文社群](./README.md) ## 赞助 -如果你感觉这个项目对你有用或者有所启发,可以请作者喝杯果汁: +Luckysheet是MIT许可的开源项目,其持续稳定的开发离不开这些优秀的 [**支持者**](https://dream-num.github.io/LuckysheetDocs/zh/about/sponsor.html#%E8%B5%9E%E5%8A%A9%E8%80%85%E5%88%97%E8%A1%A8)。 如果您想加入他们,请考虑: -注意事项: -1. 付款留言请备注:昵称,您的网站地址 -2. 默认会将您加入到下方的赞助者列表。如果您想匿名赞助,付款留言请备注:匿名 -3. 如果您忘记留言昵称或者网站地址,请联系小编email: alexads@foxmail.com或者微信:dushusir2。 +- [成为Patreon的支持者或赞助商](https://www.patreon.com/mengshukeji) +- [成为Open Collective的支持者或赞助商](https://opencollective.com/luckysheet) +- 通过PayPal,微信或支付宝一次性捐赠 -| 微信 | 支付宝 | -|---|---| -| | | +| PayPal | 微信 | 支付宝 | +|---|---|---| +| [Paypal Me](https://www.paypal.me/wbfsa) | | | + +### Patreon和OpenCollective有什么区别? -### [Paypal Me](https://www.paypal.me/wbfsa) +通过Patreon捐赠的资金将直接用于支持menshshukeji在Luckysheet上的工作。 通过OpenCollective捐赠的资金由透明费用管理,将用于补偿核心团队成员的工作和费用或赞助社区活动。 通过在任一平台上捐款,您的姓名/徽标将得到适当的认可和曝光。 ## 赞助者列表 + (按时间顺序排列) - *勇 ¥ 30 - 虚我 ¥ 200 @@ -219,23 +170,127 @@ npm run build - **平 ¥ 100 - **东 ¥ 10 - debugger ¥ 20 +- 烦了烦 ¥ 10 +- 文顶顶 ¥ 200 +- yangxshn ¥ 10 +- 爱乐 ¥ 100 +- 小李飞刀刀 ¥ 66 +- 张铭 ¥ 200 +- 曹治军 ¥ 1 +- *特 ¥ 10 +- **权 ¥ 9.9 +- **sdmq ¥ 20 +- *旭 ¥ 10 +- Quentin ¥ 20 +- 周宇凡 ¥ 100 +- *超 ¥ 10 +- 维宁 ¥ 100 +- hyy ¥ 20 +- 雨亭寒江月 ¥ 50 +- **功 ¥ 10 +- **光 ¥ 20 +- terrywan ¥ 100 +- 王晓洪 ¥ 10 +- Sun ¥ 10 +- 忧绣 ¥ 100 +- Jasonx ¥ 10 +- 国勇 ¥ 66.6 +- 郎志 ¥ 100 +- 匿名 ¥ 1 +- ni ¥ 100 +- 苏 ¥ 50 +- Mads_chan ¥ 1 +- LK ¥ 100 +- 智连方舟 李汪石 ¥ 168 +- **发 ¥ 260 +- *超 ¥ 10 +- *勇 ¥ 10 +- *腾 ¥ 15 +- 名字好难起 ¥ 20 +- 大山 ¥ 1 +- waiting ¥ 1000 +- **宇 ¥ 10.00 +- 刘小帅的哥哥 ¥ 20.00 +- 宁静致远 ¥ 10.00 +- Eleven ¥ 1.00 +- **帆 ¥ 188 +- henry ¥ 100 +- .波罗 ¥ 50 +- 花落有家 ¥ 50 +- 踏遍南水北山 ¥ 1 +- LC ¥ 5 +- **明 ¥ 8.80 +- *军 ¥ 20 +- 张彪 ¥ 50 +- 企业文档云@肖敏 ¥ 10 +- 匿名 ¥ 50 +- 逍遥行 ¥ 10 +- z.wasaki ¥ 50 +- Make Children ¥ 20 +- Foam ¥ 20 +- 奥特曼( o|o)ノ三 ¥ 50 +- **凯 ¥ 10 +- **兵 ¥ 20 +- **川 ¥ 1 +- 二万 ¥ 50 +- 蔚然成林 ¥ 10 +- 邹杰 ¥ 10 +- 张永强 ¥ 50 +- 鱼得水 ¥ 270 +- Ccther ¥ 1 +- Eric Cheng ¥ 10 +- 佚名 ¥ 1 +- 花叶 ¥ 50 +- GT ¥ 20 +- 菜菜心 ¥ 10 +- fisher ¥ 1 +- JC ¥ 5 +- 佚名 ¥ 20 +- 独孤一剑 ¥ 50 +- mxt ¥ 20 +- 一叶迷山 ¥ 100 +- Jeff ¥ 100 +- 八千多条狗🐶 ¥ 100 +- 晓峰 ¥ 10 +- 戒 ¥ 1 +- 浪里个浪 ¥ 1 +- 回调函数 ¥ 50 +- 赖瓜子 ¥ 5 +- Milo•J ¥ 20 +- 可道云 ¥ 200 +- *程 ¥ 10 +- 来一杯卡布酸奶 ¥ 5 +- 刘久胜 ¥ 100 +- 快意江湖 ¥ 50 +- *新 ¥ 9.9 +- **龙 ¥ 100 ## 贡献者和感谢 -### 团队成员 +### 核心团队活跃成员 - [@wbfsa](https://github.com/wbfsa) -- [@wpxp123456](https://github.com/wpxp123456) +- [@eiji-th](https://github.com/eiji-th) +- [@fly-95](https://github.com/fly-95) - [@tonytonychopper123](https://github.com/tonytonychopper123) - [@Dushusir](https://github.com/Dushusir) +- [@iamxuchen800117](https://github.com/iamxuchen800117) +- [@wpxp123456](https://github.com/wpxp123456) - [@c19c19i](https://weibo.com/u/3884623955) +- [@zhangchen915](https://github.com/zhangchen915) +- [@jerry-f](https://github.com/jerry-f) +- [@flowerField](https://github.com/flowerField) -### 活跃成员 +### 社区伙伴 +- [@yiwasheng](https://github.com/yiwasheng) - [@danielcai1987](https://github.com/danielcai1987) - [@qq6690876](https://github.com/qq6690876) - [@javahuang](https://github.com/javahuang) - [@TimerGang](https://github.com/TimerGang) - [@gsw945](https://github.com/gsw945) - [@swen-xiong](https://github.com/swen-xiong) +- [@lzmch](https://github.com/lzmch) +- [@kdevilpf](https://github.com/kdevilpf) +- [@WJWM0316](https://github.com/WJWM0316) ## 版权信息 [MIT](http://opensource.org/licenses/MIT) diff --git a/README.md b/README.md index c88215da9061573c3b38aaf0e0bcfb92af020759..2863adc28724fa7cf395a0de4cf4c16e5b075c0d 100644 --- a/README.md +++ b/README.md @@ -9,147 +9,95 @@ +# Luckysheet 3.x has been renamed to [Univer](https://github.com/dream-num/univer) English| [简体中文](./README-zh.md) ## Introduction 🚀Luckysheet is an online spreadsheet like excel that is powerful, simple to configure, and completely open source. + ## Links | Source Code | Documentation | Demo | Plugins Demo | Forum | | ------ | -------- | ------ | ------ | ------ | - | [Github](https://github.com/mengshukeji/Luckysheet)| [Online Documentation](https://mengshukeji.github.io/LuckysheetDocs/) | [Online Demo](https://mengshukeji.github.io/LuckysheetDemo) | [Import Excel Demo](https://mengshukeji.github.io/LuckyexcelDemo/) | [Chinese Forum](https://support.qq.com/product/288322) | + | [Github](https://github.com/mengshukeji/Luckysheet)| [Online Documentation](https://dream-num.github.io/LuckysheetDocs/) | [Online Demo](https://dream-num.github.io/LuckysheetDemo) / [Cooperative editing demo](http://luckysheet.lashuju.com/demo/) | [Import Excel Demo](https://dream-num.github.io/LuckyexcelDemo/) | [Chinese Forum](https://support.qq.com/product/288322) | | [Gitee Mirror](https://gitee.com/mengshukeji/Luckysheet)| [Gitee Online Documentation](https://mengshukeji.gitee.io/LuckysheetDocs/) | [Gitee Online Demo](https://mengshukeji.gitee.io/luckysheetdemo/) | [Gitee Import Excel Demo](https://mengshukeji.gitee.io/luckyexceldemo/) | [Google Group](https://groups.google.com/g/luckysheet) | ![Demo](/docs/.vuepress/public/img/LuckysheetDemo.gif) ## Plugins -- Excel import and export library: [Luckyexcel](https://github.com/mengshukeji/Luckyexcel) -- Chart plugin: [chartMix](https://github.com/mengshukeji/chartMix) +- [Luckyexcel](https://github.com/mengshukeji/Luckyexcel): Excel import and export library +- [chartMix](https://github.com/mengshukeji/chartMix): Chart plugin + +## Ecosystem + +| Project | Description | +|---------|-------------| +| [Luckysheet Vue] | Luckysheet and Luckyexcel in a vue cli3 project | +| [Luckysheet Vue3] | Luckysheet and Luckyexcel in a vue3 project with vite| +| [Luckysheet React] | Luckysheet in a React project | +| [Luckyexcel Node] | Use Luckyexcel in koa2 | +| [Luckysheet Server] | Java backend Luckysheet Server | +| [Luckysheet Server Starter] | LuckysheetServer docker deployment startup template | + +[Luckysheet Vue]: https://github.com/mengshukeji/luckysheet-vue +[Luckysheet Vue3]: https://github.com/hjwforever/luckysheet-vue3-vite +[Luckysheet React]: https://github.com/mengshukeji/luckysheet-react +[Luckyexcel Node]: https://github.com/mengshukeji/Luckyexcel-node +[Luckysheet Server]: https://github.com/mengshukeji/LuckysheetServer +[Luckysheet Server Starter]: https://github.com/mengshukeji/LuckysheetServerStarter + ## Features -### 🛠️Formatting -+ **Styling** (Change font style, size, color, or apply effects) -+ **Conditional formatting** (highlight interesting cells or ranges of cells, emphasize unusual values, and visualize data by using data bars, color scales, and icon sets that correspond to specific variations in the data) -+ **Align or rotate text** -+ **Support text truncation, overflow, automatic line wrapping** -+ **Data types** - + **currency, percentages, decimals, dates** - + **Custom** (E.g `##,###0.00` , `$1,234.56$##,###0.00_);[Red]($##,###0.00)`, `_($* ##,###0.00_);_(...($* "-"_);_(@_)`, `08-05 PM 01:30MM-dd AM/PM hh:mm` ) -+ **Cell segmentation style** (Alt+Enter line break, sub,super, in-cell style) - -### 🧬Cells -+ **Move cells by drag and dropping** (Operate on selection) -+ **Fill handle** (For a series like 1, 2, 3, 4, 5..., type 1 and 2 in the first two cells. For the series 2, 4, 6, 8..., type 2 and 4. Support arithmetic sequence, geometric sequence,date, week,chinese numbers) -+ **Auto Fill Options** (Fill copy, sequence, only format, no format, day, month, year) -+ **Multiple selection** (Hold Ctrl Selecting multiple cells, copy and paste) -+ **Find and replace** (Such as a particular number or text string, Support regular expression, whole word, case sensitive) -+ **Location** (Cells can be selected according to the data type) -+ **Merge cells** -+ **Data validation** (Checkbox, drop-down list, datePicker) - -### 🖱️Row & columns -+ **Hide, Insert, Delete rows and columns** -+ **Frozen rows and columns** (First row, first column, Frozen to selection, freeze adjustment lever can be dragged) -+ **Split text** (Split text into different columns with the Convert Text to Columns Wizard) - -### 🔨Operation -+ **Undo/Redo** -+ **Copy/Paste/Cut** (Copy from excel to Luckysheet with format, vice versa) -+ **Hot key** (The operating experience is consistent with excel, if there are differences or missing, please feedback to us) -+ **Format Painter** (Similar to google sheet) -+ **Selection by drag and dropping** (Change the parameters of formula and chart through selection) - -### ⚙️Formulas & functions -+ **Built-in formulas** - + Math (SUMIFS, AVERAGEIFS, SUMIF, SUM, etc.) - + Text (CONCATENATE, REGEXMATCH, MID) - + Date (DATEVALUE, DATEDIF, NOW, WEEKDAY, etc.) - + Financial (PV, FV, IRR, NPV, etc.) - + Logical (IF, AND, OR, IFERROR, etc.) - + Lookup (VLOOKUP, HLOOkUP, INDIRECT, OFFSET, etc.) - + Dynamic Array (Excel2019 new formulas, SORT,FILTER,UNIQUE,RANDARRAY,SEQUENCE) -+ **Array** (={1,2,3,4,5,6}, Crtl+Shift+Enter) -+ **Remote formulas** (DM_TEXT_TFIDF, DM_TEXT_TEXTRANK,DATA_CN_STOCK_CLOSE etc. Need remote interface, can realize complex calculation) -+ **Custom** (Some formula suitable for use in China have been added. AGE_BY_IDCARD, SEX_BY_IDCARD, BIRTHDAY_BY_IDCARD, PROVINCE_BY_IDCARD, CITY_BY_IDCARD, etc. You can define any formula you want) - -### 📐Tables -+ **Filters** (Support color , numerical, date, text filtering) -+ **Sort** (Sort multiple fields simultaneously) - -### 📈Pivot table -+ **Arrange fields** (Add fileds to rows, columns, values, area, it is similar to excel) -+ **Aggregation** (Surport Sum,Count,CountA,CountUnique,Average,Max,Min,Median,Product,Stdev,Stdevp,Var,VarP etc.) -+ **Filter data** (Add fileds to filters area and analyze the desired data ) -+ **Drill down** (Double click pivot table cell to drill down for detail data ) -+ **Create a PivotChart** (Pivot table can create a chart ) - -### 📊Chart -+ **Support types** (Line, Column, Area, Bar, Pie, comming soon Scatter, Radar, Gauge, Funnel etc.) -+ **Chart Plugins** (Link to another project [ChartMix](https://github.com/mengshukeji/chartMix)(MIT): ECharts is currently supported,Highcharts, Ali G2, amCharts, googleChart, chart.js are being developed gradually) -+ **Sparklines** (Support by formula : Line, Pie, Box, Pie etc.) - -### ✍️Share -+ **Comments** (Add, delete, update) -+ **Collaborate** (Simultaneous editing by multiple users) - -### 📚Insert object -+ **Insert picture** (JPG,PNG,SVG and so on) - -### ⚡Luckysheet -+ **Matrix operation** (Operate selection through the right-click menu: transpose, rotate, numerical calculation) -+ **Screenshot** (Take a screenshot with selection) -+ **Copy to** (In the right-click menu, copy selection to json, array etc.) -+ **EXCEL import/export** (Specially adapted to Luckysheet, export is under development) - - -### ⏱️Coming soon -+ **Print** (Like excel print option, save to PDF) -+ **Tree menu** (Just like the outline (group) function of excel) -+ **Table new Features** (filter, slicer) -+ **CSV,TXT import/export** (Specially adapted to Luckysheet) -+ **Insert Shapes** ([Pen tool](https://github.com/mengshukeji/Pentool) Shapes) -+ **Documentation** (Improve documentation and API) -+ **More...** (Please advise us) - -## Requirements -[Node.js](https://nodejs.org/en/) Version >= 6 +- **Formatting**: style, conditional formatting, text alignment and rotation, text truncation, overflow, automatic line wrapping, multiple data types, cell segmentation style +- **Cells**: drag and drop, fill handle, multiple selection, find and replace, location, merge cells, data verification +- **Row & column**: hide, insert, delete rows or columns, freeze, and split text +- **Operation**: undo, redo, copy, paste, cut, hot key, format painter, drag and drop selection +- **Formulas & Functions**: Built-in, remote and custom formulas +- **Tables**: filter, sort +- **Enhanced functions**: Pivot tables, charts, comments, cooperative editing, insert picture, matrix calculations, screenshots, copying to other formats, EXCEL import and export, etc. -## Installation -``` -npm install -npm install gulp -g -``` +For a more detailed feature list, please refer to: [Features](https://dream-num.github.io/LuckysheetDocs/guide/#features) -## Development -Development -``` -npm run dev -``` -Package -``` -npm run build -``` +## 📖 Resources +- Priority reading for new users: [User Guide](https://github.com/mengshukeji/Luckysheet/wiki/User-Guide) +- For the tutorials, learning materials and supporting solutions provided by the community, please refer to: [Tutorials and Resources](https://dream-num.github.io/LuckysheetDocs/guide/resource.html) + +## 📜 Changelog + +Detailed changes for each release are documented in the [CHANGELOG.md](CHANGELOG.md). + +## ❗️ Issues + +Please make sure to read the [Issue Reporting Checklist](https://dream-num.github.io/LuckysheetDocs/guide/contribute.html#how-to-submit-issues) before opening an issue. Issues not conforming to the guidelines may be closed immediately. + +## ✅ TODO + +Managed with [GitHub Projects](https://github.com/mengshukeji/Luckysheet/projects/1) + +## 💪Contribution + +Please make sure to read the[ Contributing Guide](https://dream-num.github.io/LuckysheetDocs/guide/contribute.html) before making a pull request. ## Usage -#### First step +### First step Introduce dependencies through CDN ``` - - - - - - + + + + + + ``` -#### Second step +### Second step Specify a table container ```
``` -#### Third step +### Third step Create a table ``` ``` +## Development + +### Requirements +[Node.js](https://nodejs.org/en/) Version >= 6 + +### Installation +``` +npm install +npm install gulp -g +``` +### Development +``` +npm run dev +``` +### Package +``` +npm run build +``` + ## Partner project - [luban-h5](https://github.com/ly525/luban-h5) -- [excelize](https://github.com/360EntSecGroup-Skylar/excelize) - [h5-Dooring](https://github.com/MrXujiang/h5-Dooring) - -## Co-construction - -1. Any questions or suggestions are welcome to submit [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose) -2. If you want to implement an important function for Luckysheet, you need to write an RFC document first, follow Luckysheet's [RFC](https://github.com/mengshukeji/Luckysheet-rfcs) mechanism to operate, and only after community discussion and improvement, you can submit the code. -3. If you are interested in Luckysheet, you are very welcome to join the development team to improve this plugin together (Email: alexads@foxmail.com), there are 4 types of tasks that can be claimed - - BUG - - New features - - Documentation - - Popularize - - You will gain: - - Luckysheet official readme document contributor link - - Participate in large open source projects, improve technology and vision +- [Furion](https://gitee.com/monksoul/Furion) +- [AFFiNE.PRO](https://github.com/toeverything/AFFiNE) ## Communication - +- [Github Discussions](https://github.com/mengshukeji/Luckysheet/discussions) - [Gitter](https://gitter.im/mengshukeji/Luckysheet) [Chinese community](./README-zh.md) ## Sponsor -If you find this project useful, you can buy author a glass of juice: +Luckysheet is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [backers](https://dream-num.github.io/LuckysheetDocs/about/sponsor.html#sponsors-list). If you'd like to join them, please consider: + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/mengshukeji). +- [Become a backer or sponsor on Open Collective](https://opencollective.com/luckysheet). +- One-time donation via PayPal, WeChat or Alipay -Note: -1. Please note the payment message: nickname, your website address -2. By default, you will be added to the sponsor list below. If you want to sponsor anonymously, please leave a note on payment: anonymous -3. If you forget your nickname or website address, please contact the editor email: alexads@foxmail.com or WeChat: dushusir2. +| PayPal | WeChat | Alipay | +|---|---|---| +| [Paypal Me](https://www.paypal.me/wbfsa) | | | -| WeChat | Alipay | -|---|---| -| | | +### What's the difference between Patreon and OpenCollective? -### [Paypal Me](https://www.paypal.me/wbfsa) +Funds donated via Patreon go directly to support mengshukeji's work on Luckysheet. Funds donated via OpenCollective are managed with transparent expenses and will be used for compensating work and expenses for core team members or sponsoring community events. Your name/logo will receive proper recognition and exposure by donating on either platform. ## Sponsors List + (Sort by time) - *勇 ¥ 30 - 虚我 ¥ 200 @@ -213,27 +169,127 @@ Note: - **平 ¥ 100 - **东 ¥ 10 - debugger ¥ 20 +- 烦了烦 ¥ 10 +- 文顶顶 ¥ 200 +- yangxshn ¥ 10 +- 爱乐 ¥ 100 +- 小李飞刀刀 ¥ 66 +- 张铭 ¥ 200 +- 曹治军 ¥ 1 +- *特 ¥ 10 +- **权 ¥ 9.9 +- **sdmq ¥ 20 +- *旭 ¥ 10 +- Quentin ¥ 20 +- 周宇凡 ¥ 100 +- *超 ¥ 10 +- 维宁 ¥ 100 +- hyy ¥ 20 +- 雨亭寒江月 ¥ 50 +- **功 ¥ 10 +- **光 ¥ 20 +- terrywan ¥ 100 +- 王晓洪 ¥ 10 +- Sun ¥ 10 +- 忧绣 ¥ 100 +- Jasonx ¥ 10 +- 国勇 ¥ 66.6 +- 郎志 ¥ 100 +- 匿名 ¥ 1 +- ni ¥ 100 +- 苏 ¥ 50 +- Mads_chan ¥ 1 +- LK ¥ 100 +- 智连方舟 李汪石 ¥ 168 +- **发 ¥ 260 +- *超 ¥ 10 +- *勇 ¥ 10 +- *腾 ¥ 15 +- 名字好难起 ¥ 20 +- 大山 ¥ 1 +- waiting ¥ 1000 +- **宇 ¥ 10.00 +- 刘小帅的哥哥 ¥ 20.00 +- 宁静致远 ¥ 10.00 +- Eleven ¥ 1.00 +- **帆 ¥ 188 +- henry ¥ 100 +- .波罗 ¥ 50 +- 花落有家 ¥ 50 +- 踏遍南水北山 ¥ 1 +- LC ¥ 5 +- **明 ¥ 8.80 +- *军 ¥ 20 +- 张彪 ¥ 50 +- 企业文档云@肖敏 ¥ 10 +- 匿名 ¥ 50 +- 逍遥行 ¥ 10 +- z.wasaki ¥ 50 +- Make Children ¥ 20 +- Foam ¥ 20 +- 奥特曼( o|o)ノ三 ¥ 50 +- **凯 ¥ 10 +- **兵 ¥ 20 +- **川 ¥ 1 +- 二万 ¥ 50 +- 蔚然成林 ¥ 10 +- 邹杰 ¥ 10 +- 张永强 ¥ 50 +- 鱼得水 ¥ 50 +- Ccther ¥ 1 +- Eric Cheng ¥ 10 +- 佚名 ¥ 1 +- 花叶 ¥ 50 +- GT ¥ 20 +- 菜菜心 ¥ 10 +- fisher ¥ 1 +- JC ¥ 5 +- 佚名 ¥ 20 +- 独孤一剑 ¥ 50 +- mxt ¥ 20 +- 一叶迷山 ¥ 100 +- Jeff ¥ 100 +- 八千多条狗🐶 ¥ 100 +- 晓峰 ¥ 10 +- 戒 ¥ 1 +- 浪里个浪 ¥ 1 +- 回调函数 ¥ 50 +- 赖瓜子 ¥ 5 +- Milo•J ¥ 20 +- 可道云 ¥ 200 +- *程 ¥ 10 +- 来一杯卡布酸奶 ¥ 5 +- 刘久胜 ¥ 100 +- 快意江湖 ¥ 50 +- *新 ¥ 9.9 +- **龙 ¥ 100 ## Authors and acknowledgment -### Team +### Active Core Team Members - [@wbfsa](https://github.com/wbfsa) -- [@wpxp123456](https://github.com/wpxp123456) +- [@eiji-th](https://github.com/eiji-th) +- [@fly-95](https://github.com/fly-95) - [@tonytonychopper123](https://github.com/tonytonychopper123) - [@Dushusir](https://github.com/Dushusir) +- [@iamxuchen800117](https://github.com/iamxuchen800117) +- [@wpxp123456](https://github.com/wpxp123456) - [@c19c19i](https://weibo.com/u/3884623955) +- [@zhangchen915](https://github.com/zhangchen915) +- [@jerry-f](https://github.com/jerry-f) +- [@flowerField](https://github.com/flowerField) -### Active participants +### Community Partners +- [@yiwasheng](https://github.com/yiwasheng) - [@danielcai1987](https://github.com/danielcai1987) - [@qq6690876](https://github.com/qq6690876) - [@javahuang](https://github.com/javahuang) - [@TimerGang](https://github.com/TimerGang) - [@gsw945](https://github.com/gsw945) - [@swen-xiong](https://github.com/swen-xiong) - -## Donate - - +- [@lzmch](https://github.com/lzmch) +- [@kdevilpf](https://github.com/kdevilpf) +- [@WJWM0316](https://github.com/WJWM0316) ## License [MIT](http://opensource.org/licenses/MIT) diff --git a/deploy.bat b/deploy.bat index a7d776b240991f959291decb66040230e6240fbd..51f8cdaac3441bbf57aa3b48f01960e85c14d251 100644 --- a/deploy.bat +++ b/deploy.bat @@ -3,10 +3,14 @@ npm run build cd dist git init git remote add origin https://github.com/mengshukeji/LuckysheetDemo.git +git config --local user.email "1414556676@qq.com" +git config --local user.name "Dushusir" git add . git commit -m 'deploy Luckysheet demo' git push -f origin master:gh-pages +# =============================================== + # deploy Docs npm run docs:build cd docs/.vuepress/dist @@ -16,6 +20,12 @@ git add . git commit -m 'deploy Luckysheet docs' git push -f origin master:gh-pages +# =============================================== + +# add a tags +git tag -a doc -m "doc" + + # replease npm run build npm run release -- --release-as patch @@ -29,3 +39,65 @@ npm run commit npm version patch git push -u origin master npm publish + + +# ============================================== + +# test feature branch +git checkout -b fea origin/feature +git pull + +## After some test, create PR merge feature to master branch + +git checkout master +git branch -d fea + +# =============================================== + +# test pull request: https://docs.github.com/cn/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/checking-out-pull-requests-locally + +# 139 is ID, dev is branch name +git fetch origin pull/139/head:test-139 +git checkout test-139 +# test code +git push origin test-139 +# create new PR ,merge test-139 to master + +# list all remote and local branchs +git branch -a +# delete remote branch +git push origin --delete dev +git checkout master +# delete local branch +git branch -d dev + +# pr +## 1. fork 到自己的仓库 + +## 2. git clone 到本地 + +## 3. 上游建立连接 +git remote add upstream https://github.com/mengshukeji/Luckysheet.git + +## 4. 创建开发分支 +git checkout -b dev + +## 5. 修改提交代码 +git add . +git commit -m "add" +git push origin dev + +## 6. 同步代码,将最新代码同步到本地 +git fetch upstream +git rebase upstream/master + +## 7. 如果有冲突(没有可以略过) +git status # 查看冲突文件,并修改冲突 +git add . +git rebase --continue + +## 8.提交分支代码 +git push origin dev + +## 7. 提交pr +去自己github仓库对应fork的项目下new pull request \ No newline at end of file diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 39f2bacc6ecb3591c86e01cf5b301065b3af87e9..e812419914f95d920ff793f73bea8b0dd6da8483 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -16,8 +16,9 @@ module.exports = { }, themeConfig: { + domain: 'https://dream-num.github.io/LuckysheetDemo', logo: '/img/logo.png', - + author: 'Luckysheet', // 仓库地址 repo: 'mengshukeji/Luckysheet', // 允许编辑链接文字 @@ -42,7 +43,14 @@ module.exports = { nav: [ { text: 'Home', link: '/' }, { text: 'Guide', link: '/guide/' }, - { text: 'Demo', link: 'https://mengshukeji.github.io/LuckysheetDemo/' } + { text: 'Demo', link: 'https://dream-num.github.io/LuckysheetDemo/' }, + { + text: 'More', + ariaLabel: 'More', + items: [ + { text: 'About', link: '/about/' } + ] + }, ], // 侧边栏 sidebar: { @@ -53,7 +61,14 @@ module.exports = { 'cell', 'operate', 'api', - 'FAQ' + 'resource', + 'FAQ', + 'contribute' + ], + '/about/': [ + '', + 'sponsor', + 'company' ], }, }, @@ -77,7 +92,14 @@ module.exports = { nav: [ { text: '首页', link: '/zh/' }, { text: '指南', link: '/zh/guide/' }, - { text: '演示', link: 'https://mengshukeji.github.io/LuckysheetDemo/' } + { text: '演示', link: 'https://dream-num.github.io/LuckysheetDemo/' }, + { + text: '了解更多', + ariaLabel: '了解更多', + items: [ + { text: '关于', link: '/zh/about/' } + ] + }, ], // 侧边栏 sidebar: { @@ -88,11 +110,38 @@ module.exports = { 'cell', 'operate', 'api', - 'FAQ' + 'resource', + 'FAQ', + 'contribute' + ], + '/zh/about/': [ + '', + 'sponsor', + 'company' ], }, }, }, }, + plugins: { + 'vuepress-plugin-baidu-autopush': {}, + 'sitemap': { + hostname: 'https://dream-num.github.io/LuckysheetDocs' + }, + 'vuepress-plugin-code-copy': true, + 'seo': { + siteTitle: (_, $site) => $site.title, + title: $page => $page.title, + description: $page => $page.frontmatter.description, + author: (_, $site) => $site.themeConfig.author, + tags: $page => $page.frontmatter.tags, + twitterCard: _ => 'summary_large_image', + type: $page => ['guide'].some(folder => $page.regularPath.startsWith('/' + folder)) ? 'article' : 'website', + url: (_, $site, path) => ($site.themeConfig.domain || '') + path, + image: ($page, $site) => $page.frontmatter.image && (($site.themeConfig.domain && !$page.frontmatter.image.startsWith('http') || '') + $page.frontmatter.image), + publishedAt: $page => $page.frontmatter.date && new Date($page.frontmatter.date), + modifiedAt: $page => $page.lastUpdated && new Date($page.lastUpdated), + } + } } \ No newline at end of file diff --git a/docs/about/README.md b/docs/about/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6ceeae8c021f1fc014581911448eb21f27304e7d --- /dev/null +++ b/docs/about/README.md @@ -0,0 +1,28 @@ +# Meet the Team + +Luckysheet is a project led by an individual and jointly developed by several friends with the same interests. + +### Active Core Team Members +- [@wbfsa](https://github.com/wbfsa) +- [@eiji-th](https://github.com/eiji-th) +- [@fly-95](https://github.com/fly-95) +- [@tonytonychopper123](https://github.com/tonytonychopper123) +- [@Dushusir](https://github.com/Dushusir) +- [@iamxuchen800117](https://github.com/iamxuchen800117) +- [@wpxp123456](https://github.com/wpxp123456) +- [@c19c19i](https://weibo.com/u/3884623955) +- [@zhangchen915](https://github.com/zhangchen915) +- [@jerry-f](https://github.com/jerry-f) +- [@flowerField](https://github.com/flowerField) + +### Community Partners +- [@yiwasheng](https://github.com/yiwasheng) +- [@danielcai1987](https://github.com/danielcai1987) +- [@qq6690876](https://github.com/qq6690876) +- [@javahuang](https://github.com/javahuang) +- [@TimerGang](https://github.com/TimerGang) +- [@gsw945](https://github.com/gsw945) +- [@swen-xiong](https://github.com/swen-xiong) +- [@lzmch](https://github.com/lzmch) +- [@kdevilpf](https://github.com/kdevilpf) +- [@WJWM0316](https://github.com/WJWM0316) \ No newline at end of file diff --git a/docs/about/company.md b/docs/about/company.md new file mode 100644 index 0000000000000000000000000000000000000000..e01b43cd4b17e18866522a3b8a5a8a8a1ec61802 --- /dev/null +++ b/docs/about/company.md @@ -0,0 +1,49 @@ +# Community case + +We collected a lot of case feedback from the community, and also discovered Luckysheet usage scenarios that we did not expect before. + +It is our responsibility to actively listen to the voice of the community, and to continuously update and iterate with your support and feedback. + + +## Company Case + + + + + + + + + + + + + + + + +
+ + + +

雄安智评云数字科技有限公司

+
+ + + +

Code the Future

+
+ + + +

吉客云

+
+ + + +

华为

+
+ + + +
\ No newline at end of file diff --git a/docs/about/sponsor.md b/docs/about/sponsor.md new file mode 100644 index 0000000000000000000000000000000000000000..ac1e47b76282148b55426a794f7c16edfb43824d --- /dev/null +++ b/docs/about/sponsor.md @@ -0,0 +1,128 @@ +# Sponsor + +## Why sponsor + +If you run a business and is using Luckysheet in a revenue-generating product, it would make business sense to sponsor Luckysheet development: it ensures the project that your product relies on stays healthy and actively maintained. It can also help your exposure in the Luckysheet community and more people pay attention to your products. + +Of course, individual users are also welcome to buy author a glass of juice if Luckysheet has helped you in your work or personal projects 😋. + +## How to sponsor + +Luckysheet is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome [**backers**](#sponsors-list). If you'd like to join them, please consider: + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/mengshukeji). +- [Become a backer or sponsor on Open Collective](https://opencollective.com/luckysheet). +- One-time donation via PayPal, WeChat or Alipay + +| PayPal | WeChat | Alipay | +|---|---|---| +| [Paypal Me](https://www.paypal.me/wbfsa) | | | + +### What's the difference between Patreon and OpenCollective? + +Funds donated via Patreon go directly to support mengshukeji's work on Luckysheet. Funds donated via OpenCollective are managed with transparent expenses and will be used for compensating work and expenses for core team members or sponsoring community events. Your name/logo will receive proper recognition and exposure by donating on either platform. + +## Sponsors List + +(Sort by time) +- *勇 ¥ 30 +- 虚我 ¥ 200 +- 甜党 ¥ 50 +- Alphabet(Google)-gcf ¥ 1 +- **平 ¥ 100 +- **东 ¥ 10 +- debugger ¥ 20 +- 烦了烦 ¥ 10 +- 文顶顶 ¥ 200 +- yangxshn ¥ 10 +- 爱乐 ¥ 100 +- 小李飞刀刀 ¥ 66 +- 张铭 ¥ 200 +- 曹治军 ¥ 1 +- *特 ¥ 10 +- **权 ¥ 9.9 +- **sdmq ¥ 20 +- *旭 ¥ 10 +- Quentin ¥ 20 +- 周宇凡 ¥ 100 +- *超 ¥ 10 +- 维宁 ¥ 100 +- hyy ¥ 20 +- 雨亭寒江月 ¥ 50 +- **功 ¥ 10 +- **光 ¥ 20 +- terrywan ¥ 100 +- 王晓洪 ¥ 10 +- Sun ¥ 10 +- 忧绣 ¥ 100 +- Jasonx ¥ 10 +- 国勇 ¥ 66.6 +- 郎志 ¥ 100 +- 匿名 ¥ 1 +- ni ¥ 100 +- 苏 ¥ 50 +- Mads_chan ¥ 1 +- LK ¥ 100 +- 智连方舟 李汪石 ¥ 168 +- **发 ¥ 260 +- *超 ¥ 10 +- *勇 ¥ 10 +- *腾 ¥ 15 +- 名字好难起 ¥ 20 +- 大山 ¥ 1 +- waiting ¥ 1000 +- **宇 ¥ 10.00 +- 刘小帅的哥哥 ¥ 20.00 +- 宁静致远 ¥ 10.00 +- Eleven ¥ 1.00 +- **帆 ¥ 188 +- henry ¥ 100 +- .波罗 ¥ 50 +- 花落有家 ¥ 50 +- 踏遍南水北山 ¥ 1 +- LC ¥ 5 +- **明 ¥ 8.80 +- *军 ¥ 20 +- 张彪 ¥ 50 +- 企业文档云@肖敏 ¥ 10 +- 匿名 ¥ 50 +- 逍遥行 ¥ 10 +- z.wasaki ¥ 50 +- Make Children ¥ 20 +- Foam ¥ 20 +- 奥特曼( o|o)ノ三 ¥ 50 +- **凯 ¥ 10 +- **兵 ¥ 20 +- **川 ¥ 1 +- 二万 ¥ 50 +- 蔚然成林 ¥ 10 +- 邹杰 ¥ 10 +- 张永强 ¥ 50 +- 鱼得水 ¥ 50 +- Ccther ¥ 1 +- Eric Cheng ¥ 10 +- 佚名 ¥ 1 +- 花叶 ¥ 50 +- GT ¥ 20 +- 菜菜心 ¥ 10 +- fisher ¥ 1 +- JC ¥ 5 +- 佚名 ¥ 20 +- 独孤一剑 ¥ 50 +- mxt ¥ 20 +- 一叶迷山 ¥ 100 +- Jeff ¥ 100 +- 八千多条狗🐶 ¥ 100 +- 晓峰 ¥ 10 +- 戒 ¥ 1 +- 浪里个浪 ¥ 1 +- 回调函数 ¥ 50 +- 赖瓜子 ¥ 5 +- Milo•J ¥ 20 +- 可道云 ¥ 200 +- *程 ¥ 10 +- 来一杯卡布酸奶 ¥ 5 +- 刘久胜 ¥ 100 +- 快意江湖 ¥ 50 +- *新 ¥ 9.9 +- **龙 ¥ 100 \ No newline at end of file diff --git a/docs/guide/FAQ.md b/docs/guide/FAQ.md index 7a0b90f23104a6e46284dda1727092a42483d9ea..2747772266376c3386f7fca0fafd5effe4a1ced4 100644 --- a/docs/guide/FAQ.md +++ b/docs/guide/FAQ.md @@ -1,8 +1,10 @@ # FAQ -## **Q** What is the difference between data and celldata in luckysheetfile? +The content of this chapter collects the common problems that everyone has feedback. If the official documents and this list can’t answer your questions, I recommend you to [Official Forum](https://github.com/mengshukeji/Luckysheet/discussions) -**A**: Use one-dimensional array format [celldata](/zh/guide/sheet.html#celldata), after the initialization is completed, the data converted into a two-dimensional array format is used for storage and update, and celldata is no longer used. +## What is the difference between data and celldata in luckysheetfile? + +**A**: Use one-dimensional array format [celldata](/guide/sheet.html#celldata), after the initialization is completed, the data converted into a two-dimensional array format is used for storage and update, and celldata is no longer used. If you need to take out `data` as initial data, you need to execute [transToCellData(data)](/guide/api.html#transtocelldata-data-setting) to convert it to celldata data. Among them, the celldata in `{ r, c, v }` format is converted to a two-dimensional array using [transToData(celldata)](/guide/api.html#transtodata-celldata-setting) @@ -18,41 +20,41 @@ luckysheet.transToData(celldata) ------------ -## **Q** What are the cell types? +## What are the cell types? -**A**: Refer to [Cell Format List](/zh/guide/cell.html), with examples of available cell formats +**A**: Refer to [Cell Format List](/guide/cell.html), with examples of available cell formats ------------ -## **Q** How to use Luckysheet in Vue/React project? +## How to use Luckysheet in Vue/React project? -**A**: +**A**: Check - Vue case: [luckysheet-vue](https://github.com/mengshukeji/luckysheet-vue) - React case: [luckysheet-react](https://github.com/mengshukeji/luckysheet-react) ------------ -## **Q** Why will the formula in the table not be triggered after initialization? +## Why will the formula in the table not be triggered after initialization? -**A** : Refer to [Table data format](/zh/guide/sheet.html#calcchain) ,just set the calcChain corresponding to the cell data. +**A**: Refer to [Table data format](/guide/sheet.html#calcchain) ,just set the calcChain corresponding to the cell data. ------------ -## **Q** Is the remote loading data loadUrl or updateUrl? +## Is the remote loading data loadUrl or updateUrl? -**A**: [loadUrl](/zh/guide/config.html#loadurl). Configure loadUrl, Luckysheet will request the entire table data through ajax, and updateUrl will be used as the interface address for collaborative editing in real-time saving. -Note: Initial data needs to be configured with loadUrl and loadSheetUrl parameters, while for collaborative editing, the four parameters of loadUrl, loadSheetUrl, updateUrl and allowUpdate can be configured to take effect. +**A**: [loadUrl](/guide/config.html#loadurl). Configure loadUrl, Luckysheet will request the entire table data through ajax, and updateUrl will be used as the interface address for collaborative editing in real-time saving. +Note: Initial data needs to be configured with loadUrl parameter, while for collaborative editing, the four parameters of loadUrl, updateUrl and allowUpdate can be configured to take effect. ------------ -## **Q** What is the difference between `index` and `order` for each sheet page? +## What is the difference between `index` and `order` for each sheet page? **A**: Each sheet page has a unique id, which is `index`, which can be incremented by numbers or a random string. And `order` is the sorting situation of all sheets, starting from 0, can only be numbers `0,1,2...`. ------------ -## **Q** Why can’t I run the project directly under the dist folder? +## Why can’t I run the project directly under the dist folder? **A**: Need to start the local server @@ -61,7 +63,7 @@ Note: Initial data needs to be configured with loadUrl and loadSheetUrl paramete ------------ -## **Q** How to import and export excel? +## How to import and export excel? **A**: The excel import and export library developed with Luckysheet-[Luckyexcel](https://github.com/mengshukeji/Luckyexcel) has realized the excel import function, and the export function is under development.You can refer to these 2 blog posts for excel export at this stage: @@ -70,77 +72,77 @@ Note: Initial data needs to be configured with loadUrl and loadSheetUrl paramete ------------ -## **Q** How to merge cells during initialization? +## How to merge cells during initialization? **A**: Refer to the following case: - [How Luckysheet initializes the data with merged cells](https://www.cnblogs.com/DuShuSir/p/13272397.html) ------------ -## **Q** How does 'Luckysheet' save the data from the table to the database? Is there a soulution for storage and collaboration? +## How does 'Luckysheet' save the data from the table to the database? Is there a soulution for storage and collaboration? -**A** :There are two options: +**A**: There are two options: - 1. after the table operation is completed, you can use `luckysheet.getAllSheets()` to get all sheet data that stroed in the back-end. - 2. enable the collaborative editing function to transmit data to the back-end in real-time. -refer this article: +refer this article: [How Luckysheet saves the data in the table to the database](https://www.cnblogs.com/DuShuSir/p/13857874.html) ------------ -## **Q** How to monitor cell hover or click events? how to monitor `cellRenderAfter` in real-time? +## How to monitor cell hover or click events? how to monitor `cellRenderAfter` in real-time? -**A** :我们搜集到需要针对单元格事件的二次开发需求,规划了单元格相关的钩子函数,参考[单元格钩子函数](/zh/guide/config.html#cellrenderafter)(显示的TODO的暂未开放) +**A**: We have collected the secondary development requirements for cell events, and planned the cell-related hook functions, refer to [cell hook function](/guide/config.html#cellrenderafter) (the TODO displayed is not yet open) ------------ -## **Q** How to customize the top toolbar? +## How to customize the top toolbar? -**A** : -reference: [options.showtoolbarconfig](/zh/guide/config.html#showtoolbarconfig)(TODO means waiting to developed) +**A**: +reference: [options.showtoolbarconfig](/guide/config.html#showtoolbarconfig)(TODO means waiting to developed) ------------ -## **Q** Does the project use jQuery? +## Does the project use jQuery? -**A** :yes. At the beginning, Luckysheet uses jQuery。The packaging tool will package the jQuery to this file `./plugins/js/plugin.js` +**A**: yes. At the beginning, Luckysheet uses jQuery。The packaging tool will package the jQuery to this file `./plugins/js/plugin.js` If your project (such as react / Vue) also references jQuery globally and causes conflicts, you can try to remove a jQuery. -if you want to remove jQuery in `Luckysheet`, you can find `jQuery` in source code folder `gulpfile.js`:[src/plugins/js/jquery.min.js](https://github.com/mengshukeji/Luckysheet/blob/master/gulpfile.js),then delete information related to jQuery. +if you want to remove jQuery in `Luckysheet`, you can find `jQuery` in source code folder `gulpfile.js`: [src/plugins/js/jquery.min.js](https://github.com/mengshukeji/Luckysheet/blob/master/gulpfile.js),then delete information related to jQuery. ------------ -## **Q** How to add a field to a cell object? +## How to add a field to a cell object? -**A** reference [cell object format](/zh/guide/cell.html),then read this annotation[src/controllers/postil.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/postil.js)。the annotation is a configuration in a cell object. +**A**: reference [cell object format](/guide/cell.html),then read this annotation[src/controllers/postil.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/postil.js)。the annotation is a configuration in a cell object. ------------ -## **Q** The toolbar icon is on the loading stage all the time. +## The toolbar icon is on the loading stage all the time. -**A** The luckysheet use iconfont icon in this project, if any icon cannot be loaded ,plz check your iconfont.css. we are so sorry that we did not describe it clearly in the old version documents. +**A**: The luckysheet use iconfont icon in this project, if any icon cannot be loaded ,plz check your iconfont.css. we are so sorry that we did not describe it clearly in the old version documents. -Now the documents have been updated.[official documents](/zh/guide/#使用步骤) +Now the documents have been updated.[official documents](/guide/#steps-for-usage) ------------ -## **Q** Can't run Luckyexcel after package. +## Can't run Luckyexcel after package. -**A** Terminal does not show `end`, but if the `dist` folder has this file `luckyexcel.js`, it is normal. +**A**: Terminal does not show `end`, but if the `dist` folder has this file `luckyexcel.js`, it is normal. -Lucky excel is an excel import and export library. The project uses `gulp` as a packaging tool. There is a problem with the old version of the packaging tool, but it is fixed now. if this problem still troubles you, plz check the following steps: +Lucky excel is an excel import and export library. The project uses `gulp` as a packaging tool. There is a problem with the old version of the packaging tool, but it is fixed now. if this problem still troubles you, plz check the following steps: 1. pull the latest code. 2. `npm i` 3. `npm run build` -more information:[Luckyexcel](https://github.com/mengshukeji/Luckyexcel/) +more information: [Luckyexcel](https://github.com/mengshukeji/Luckyexcel/) ------------ -## **Q** How to disable editing of cells?How to open sheet protection? +## How to disable editing of cells?How to open sheet protection? -**A** Sheet protection includes disable editing of cells that you need to make some configurations on each sheets. `config.authority`, the latest configurations[sheet protection](/zh/guide/sheet.html#config-authority)。 +**A**: Sheet protection includes disable editing of cells that you need to make some configurations on each sheets. `config.authority`, the latest configurations[sheet protection](/guide/sheet.html#config-authority)。 In order to make it easier for you to understand the function of sheet protection, the following video shows how to make the whole sheet uneditable, but allow a column of cells to be edited: @@ -150,21 +152,21 @@ In you local browser, you can open the control pannel, use `luckysheet.getLuckys ------------ -## **Q** How to configure data validation? +## How to configure data validation? -**A** there is the configuration of data validation,[data validation](/zh/guide/sheet.html#dataVerification)。Also there is the API that you can use `data validation` in any time. [setDataVerification](/zh/guide/api.html#setdataverification-optionitem-setting). +**A**: there is the configuration of data validation,[data validation](/guide/sheet.html#dataVerification)。Also there is the API that you can use `data validation` in any time. [setDataVerification](/guide/api.html#setdataverification-optionitem-setting). ------------ -## **Q** Is there a case for using Luckysheet with CDN? +## Is there a case for using Luckysheet with CDN? -**A** Luckysheet supports CDN. reference:[The case of using luckysheet by CDN](https://www.cnblogs.com/DuShuSir/p/13859103.html) +**A**: Luckysheet supports CDN. reference: [The case of using luckysheet by CDN](https://www.cnblogs.com/DuShuSir/p/13859103.html) ------------ -## **Q** how to limit the adaptive height of a picture in a cell? +## how to limit the adaptive height of a picture in a cell? -**A** First of all, you need to move the picture and adjust the cell size, and then there are the following situations: +**A**: First of all, you need to move the picture and adjust the cell size, and then there are the following situations: - if the cell contains a picture and you expand the cell, the picure will not be expanded. - if the cell contains a picture and you shorten the cell to the edge of the picture, the picture will shrink. @@ -176,11 +178,148 @@ if you want to get the position of the picture, you can overlap the picture with ------------ -## **Q** How to get the default row height and column width of the worksheet? +## How to get the default row height and column width of the worksheet? -**A** There are two ways to get it +**A**: There are two ways to get it - 1. use `luckysheet.getLuckysheetfile()` to get all configuration data, so you can get the `defaultRowHeight` and `defaultColWidth` in the sheet configuration data。 -- 2. use API to get the default row height [getDefaultRowHeight](/zh/guide/api.html#getdefaultrowheight-setting) and column width.[getDefaultColWidth](/zh/guide/api.html#getdefaultcolwidth-setting) +- 2. use API to get the default row height [getDefaultRowHeight](/guide/api.html#getdefaultrowheight-setting) and column width.[getDefaultColWidth](/guide/api.html#getdefaultcolwidth-setting) + +------------ + +## How to hide the add row button and the back to top button below the worksheet? + +**A**: Configuration is open +- Allow adding rows [enableAddRow](/guide/config.html#enableaddrow) +- Allow back to top [enableAddBackTop](/guide/config.html#enableAddBackTop) + +------------ + +## How to hide the row and column headings of the worksheet? + +**A**: Configuration is open +- The width of the row header area [rowHeaderWidth](/guide/config.html#rowheaderwidth) +- The height of the column header area [columnHeaderHeight](/guide/config.html#columnHeaderHeight) + +------------ + +## What method can be called to set `config.merge`? + +**A**: Three methods +- Interface operation +- Use API: [setRangeMerge](/guide/api.html#setrangemerge-type-setting) +- Manually assemble merge parameters + +------------ + +## Why is the official new feature ineffective? + +**A**: The first step is to check whether you have used CDN to import, + +The CDN link used in the Luckysheet tutorial is the service provided by [jsdelivr](https://www.jsdelivr.com/package/npm/luckysheet), and the code is from [npmjs.com](https://www.npmjs.com/) automatically sync the past, not from [Github](https://github.com/mengshukeji/Luckysheet/). Because our newly submitted code still needs to be tested for a period of time, it will not be released to npm immediately, causing the npm code to lag behind Github. + +If you need to try the latest code, we strongly recommend that you pull the code from the [Luckysheet Github](https://github.com/mengshukeji/Luckysheet/) main repository. After our version is stable, we will consider releasing the npm package in real time. + +The second step, if it is to import the packaged code of the github repository, test to determine whether there is a bug, you can find the problem and try to fix it, and then [submit a PR](https://github.com/mengshukeji/Luckysheet/pulls), if can't fix it, please [submit issues](https://github.com/mengshukeji/Luckysheet/issues). + +------------ + +## `npm run dev` reported an error: ʻError: Cannot find module'rollup'`? + +**A**: It may be a problem with the npm package installation, try the following steps: +1. `npm cache clean --force` +2. `npm i rimraf -g` +3. `rimraf node_modules` +4. Delete the package-lock.json file +5. `npm i` +6. `npm run dev` + +Tip: Most other npm installation problems can also be solved by trying above steps. + +------------ + +## How to carry out secondary development of Luckysheet in Vue project? + +**A**: The [luckysheet-vue](https://github.com/mengshukeji/luckysheet-vue) case is to provide an application integration solution. + +If directly developed locally: +1. Start both the Luckysheet project and your own Vue project. For example, the Luckysheet project is at http://localhost:3001 +2. Import Luckysheet to use in the Vue project through `http://localhost:3001` + +In this case, after Luckysheet is modified in real time, the changes can be seen in the Vue project + +------------ + +## Error reporting `Store.createChart` when creating chart? + +**A**: You need to introduce a chart plugin to use it. You should configure the chart plugin to use when the workbook is initialized. Refer to + +- Plugins configuration [plugins](/guide/config.html#plugins) +- 或 官方demo [src/index.html](https://github.com/mengshukeji/Luckysheet/blob/master/src/index.html) + +------------ + +## Can cells add custom attributes? + +**A**: The custom attributes directly assigned to the cell object will be filtered. To make the custom attributes take effect, you need to edit the code to remove the filter attributes. + +------------ + +## How to enter text starting with `'='`? For example, `=currentDate('YYYY-MM-DD')`, it will remove the function by default, how to prohibit the function? + +**A**: Just add a single quotation mark in front of it, and it will be forcibly recognized as a string, which is consistent with excel. For example: `'=currentDate('YYYY-MM-DD')` + +------------ + +## Why does the create callback have no effect? + +**A**: The API method `luckysheet.create()` does not have a callback, but Luckysheet provides a hook function to execute the callback method at a specified location, such as: +- Triggered before the workbook is created [workbookCreateBefore](/guide/config.html#workbookcreatebefore) +- Triggered after the workbook is created [workbookCreateAfter](/guide/config.html#workbookcreateafter) + +------------ + +## When create, the first cell is selected by default, how to remove it? + +**A**: When the cell is selected, it is highlighted by default, just remove the highlight, use API: [setRangeShow](/guide/api.html#setrangeshow-range-setting) + +```js +luckysheet.setRangeShow("A2",{show:false}) +``` + +------------ + +## Where is the right-click event bound? + +**A**: In the source code [src/controllers/hander.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/handler.js), search for `event.which == "3"` to find the code executed by the right-click event. + +------------ + +## How to add a custom toolbar? + +**A**: No configuration is currently provided, you can refer to the implementation of the print button in the toolbar to modify the source code: +1. Search for `luckysheet-icon-print` globally to find the implementation of the print button, in [src/controllers/constant.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/constant.js) add a similar template string, you need to customize a unique id +2. Modify [src/controllers/resize.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/resize.js) and add a new record in the toobarConfig object +3. Modify [src/controllers/menuButton.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/menuButton.js) to add an event listener + +------------ + +## How to add custom formulas? + +**A**: Two source codes need to be modified: +1. Add a formula to the `functionImplementation` object in the [src/function/functionImplementation.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/function/functionImplementation.js) file, format refer to formulas such as `SUM`/`AVERAGE` +2. Modify all the language packs in the [src/locale](https://github.com/mengshukeji/Luckysheet/blob/master/src/locale) file directory, and add the new formula description to the `functionlist` array in. Among them, `t` is the category of the function, `m` is the number of parameters, the minimum number of parameters and the maximum number of parameters. + +------------ + +## Is there a similar loadData interface, I want to load 10 records first, and then dynamically load the data, these data are appended to the table? + +**A**: Yes. Our `loadSheetUrl` provides this function, which can be turned on by initializing `options.enablePage = true`. + +Searching for `enablePage` in the source code, you can see that there is a `method.addDataAjax` method, which contains an ajax request to dynamically load data, which will be appended to the worksheet. + +This function is now hidden in the document, because when we made this interface, the interface parameters were matched according to our actual business, which may not be universal. We are going to abstract and release it for everyone to use. If you want to use it yourself you can change it based on this. + +It is recommended that you consider writing your own interface to load the data, and then use `setRangeValue` to append the data at the specified location, which has a higher degree of customization. ------------ \ No newline at end of file diff --git a/docs/guide/README.md b/docs/guide/README.md index 7141366d3eaecafa69591e6826431fc420eee315..32f5b7b3f4aa1516ab1c48b5fcc5346c14643925 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -4,13 +4,17 @@ Luckysheet is an online spreadsheet like excel that is powerful, simple to configure, and completely open source. ## Demo -[Online demo](https://mengshukeji.github.io/LuckysheetDemo/) +[Online demo](https://dream-num.github.io/LuckysheetDemo/) ![Demo](/LuckysheetDocs/img/LuckysheetDemo.gif) +## Online Case + +- [Cooperative editing demo](http://luckysheet.lashuju.com/demo/)(Note: The official Java backend will also be open source after finishing,using OT algorithm. Please do not operate frequently to prevent the server from crashing) + ## Features -### Formatting +### 🛠️Formatting + **Styling** (Change font style, size, color, or apply effects) + **Conditional formatting** (highlight interesting cells or ranges of cells, emphasize unusual values, and visualize data by using data bars, color scales, and icon sets that correspond to specific variations in the data) + **Align or rotate text** @@ -18,8 +22,9 @@ Luckysheet is an online spreadsheet like excel that is powerful, simple to confi + **Data types** + **currency, percentages, decimals, dates** + **Custom** (E.g `##,###0.00` , `$1,234.56$##,###0.00_);[Red]($##,###0.00)`, `_($* ##,###0.00_);_(...($* "-"_);_(@_)`, `08-05 PM 01:30MM-dd AM/PM hh:mm` ) ++ **Cell segmentation style** (Alt+Enter line break, sub,super, in-cell style) -### Cells +### 🧬Cells + **Move cells by drag and dropping** (Operate on selection) + **Fill handle** (For a series like 1, 2, 3, 4, 5..., type 1 and 2 in the first two cells. For the series 2, 4, 6, 8..., type 2 and 4. Support arithmetic sequence, geometric sequence,date, week,chinese numbers) + **Auto Fill Options** (Fill copy, sequence, only format, no format, day, month, year) @@ -27,20 +32,21 @@ Luckysheet is an online spreadsheet like excel that is powerful, simple to confi + **Find and replace** (Such as a particular number or text string, Support regular expression, whole word, case sensitive) + **Location** (Cells can be selected according to the data type) + **Merge cells** ++ **Data validation** (Checkbox, drop-down list, datePicker) -### Row & columns +### 🖱️Row & columns + **Hide, Insert, Delete rows and columns** + **Frozen rows and columns** (First row, first column, Frozen to selection, freeze adjustment lever can be dragged) + **Split text** (Split text into different columns with the Convert Text to Columns Wizard) -### Operation +### 🔨Operation + **Undo/Redo** -+ **Copy/Paste/Cut** (Copy from excel to luckysheet with format, vice versa) ++ **Copy/Paste/Cut** (Copy from excel to Luckysheet with format, vice versa) + **Hot key** (The operating experience is consistent with excel, if there are differences or missing, please feedback to us) + **Format Painter** (Similar to google sheet) + **Selection by drag and dropping** (Change the parameters of formula and chart through selection) -### Formulas & functions +### ⚙️Formulas & functions + **Built-in formulas** + Math (SUMIFS, AVERAGEIFS, SUMIF, SUM, etc.) + Text (CONCATENATE, REGEXMATCH, MID) @@ -53,39 +59,41 @@ Luckysheet is an online spreadsheet like excel that is powerful, simple to confi + **Remote formulas** (DM_TEXT_TFIDF, DM_TEXT_TEXTRANK,DATA_CN_STOCK_CLOSE etc. Need remote interface, can realize complex calculation) + **Custom** (Some formula suitable for use in China have been added. AGE_BY_IDCARD, SEX_BY_IDCARD, BIRTHDAY_BY_IDCARD, PROVINCE_BY_IDCARD, CITY_BY_IDCARD, etc. You can define any formula you want) -### Tables +### 📐Tables + **Filters** (Support color , numerical, date, text filtering) + **Sort** (Sort multiple fields simultaneously) -### Pivot table +### 📈Pivot table + **Arrange fields** (Add fileds to rows, columns, values, area, it is similar to excel) + **Aggregation** (Surport Sum,Count,CountA,CountUnique,Average,Max,Min,Median,Product,Stdev,Stdevp,Var,VarP etc.) + **Filter data** (Add fileds to filters area and analyze the desired data ) + **Drill down** (Double click pivot table cell to drill down for detail data ) + **Create a PivotChart** (Pivot table can create a chart ) -### Chart +### 📊Chart + **Support types** (Line, Column, Area, Bar, Pie, comming soon Scatter, Radar, Gauge, Funnel etc.) + **Chart Plugins** (Link to another project [ChartMix](https://github.com/mengshukeji/chartMix)(MIT): ECharts is currently supported,Highcharts, Ali G2, amCharts, googleChart, chart.js are being developed gradually) + **Sparklines** (Support by formula : Line, Pie, Box, Pie etc.) -### Share +### ✍️Share + **Comments** (Add, delete, update) + **Collaborate** (Simultaneous editing by multiple users) -### LuckySheet +### 📚Insert object ++ **Insert picture** (JPG,PNG,SVG and so on) + +### ⚡Luckysheet + **Matrix operation** (Operate selection through the right-click menu: transpose, rotate, numerical calculation) + **Screenshot** (Take a screenshot with selection) + **Copy to** (In the right-click menu, copy selection to json, array etc.) -+ **EXCEL,CSV,TXT import/export** (Specially adapted to luckysheet) -+ **Insert picture and Shapes** (JPG,PNG,SVG,Pen tool and so on) -+ **Data validation** (Checkbox, drop-down list, datePicker) -+ **Cell segmentation style** (Alt+Enter line break, sub,super, in-cell style) ++ **EXCEL import/export** (Specially adapted to Luckysheet, export is under development) -### Coming soon +### ⏱️Coming soon + **Print** (Like excel print option, save to PDF) + **Tree menu** (Just like the outline (group) function of excel) + **Table new Features** (filter, slicer) ++ **CSV,TXT import/export** (Specially adapted to Luckysheet) ++ **Insert Shapes** ([Pen tool](https://github.com/mengshukeji/Pentool) Shapes) + **Documentation** (Improve documentation and API) + **More...** (Please advise us) @@ -118,15 +126,19 @@ There are two ways to introduce dependencies #### CDN ```html - - - - - - + + + + + + ``` -Note that `https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js` will pull the latest luckysheet code. If you want to specify the luckysheet version, please add the version number after the luckysheet , Such as: `https://cdn.jsdelivr.net/npm/luckysheet@2.0.0/dist/luckysheet.umd.js` +Note that the path of `https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js` means that the latest luckysheet code will be pulled, but if Luckysheet has just been released, the jsdelivr website may not have time Synchronize from npm, so using this path will still pull to the previous version. We recommend that you directly specify the latest version. + +To specify the Luckysheet version, please add the version number after all CDN dependent files, such as: `https://cdn.jsdelivr.net/npm/luckysheet@2.1.12/dist/luckysheet.umd.js`. + +> How do I know which version is the latest version? View the latest [release record](https://github.com/mengshukeji/Luckysheet/releases) or [package.json](https://github.com/mengshukeji/Luckysheet/blob/master/package.json)` version` field. If it is not convenient to access jsdelivr.net, you can also import it locally @@ -237,8 +249,8 @@ You can see the complete settings If you encounter problems with Luckysheet, follow the steps below to find the answer 1. Use Doge or Google to search for common technical issues -2. For Luckysheet related issues, please view [Luckysheet Official Document](https://mengshukeji.github.io/LuckysheetDocs/)(Note that the function of marking TODO has not yet been implemented) -3. Search [FAQ List](https://mengshukeji.github.io/LuckysheetDocs/guide/FAQ.html) +2. For Luckysheet related issues, please view [Luckysheet Official Document](https://dream-num.github.io/LuckysheetDocs/)(Note that the function of marking TODO has not yet been implemented) +3. Search [FAQ List](https://dream-num.github.io/LuckysheetDocs/guide/FAQ.html) 4. Search [Official Forum](https://groups.google.com/g/luckysheet) to see if anyone has encountered it 5. Try to check or experiment by yourself to find the answer 6. Please try to read the source code to find the answer, diff --git a/docs/guide/api.md b/docs/guide/api.md index bdd25b03beda2bcb6f0bf5944a6177ba8147249d..6ee77b6907f84831e4f7893cf5a526b62ab185d9 100644 --- a/docs/guide/api.md +++ b/docs/guide/api.md @@ -6,6 +6,7 @@ Use note: 1. When script is introduced globally, all APIs are mounted under the window.luckysheet object, which can be printed and seen in the browser console; when npm is introduced, all APIs are also mounted under the luckysheet object 2. The first parameter of the `success` callback function is the return value of the API method 3. If you need a new API, please submit it to github [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose), and decide whether to open the new API according to the number of likes +4. The required `order` parameter in the API method is the value of `order` in the worksheet object, not `index` ## Cell operation @@ -175,6 +176,7 @@ Use note: + {Boolean} [isWholeWord]: Whether to match the whole word; the default is `false` + {Boolean} [isCaseSensitive]: Whether to match case sensitively; the default is `false` + {Number} [order]: Worksheet subscript; the default value is the current worksheet subscript + + {String} [type]: cell attribute; the default value is `"m"` - **Explanation**: @@ -184,6 +186,8 @@ Use note: - Find the string `"value"` in the current worksheet `luckysheet.find("value")` + - Find cells in the current worksheet whose formula contains `"SUM"` + `luckysheet.find("SUM",{type:"f"})` ------------ @@ -316,6 +320,16 @@ Use note: Pay special attention to the setting of `range` in `setting` only when `isRange` is set to `true`, which is different from the general range format. + If you want to use this API to set the freeze after the workbook is initialized, you can execute it in the hook function after the workbook is created, such as: + ```js + luckysheet.create({ + hook:{ + workbookCreateAfter:function(){ + luckysheet.setBothFrozen(false); + } + } + }); + - **Usage**: - Frozen ranks @@ -571,7 +585,7 @@ Use note: - **Parameter**: - - {Number} [columnInfo]: Correspondence between the number of columns and the width + - {Object} [columnInfo]: Correspondence between the number of columns and the width - {PlainObject} [setting]: optional parameters + {Number} [order]: Worksheet subscript; the default value is the current worksheet subscript @@ -714,6 +728,179 @@ Use note: ------------ + +### getRangeWithFlatten() + +- **Explanation**: + + Returns an array representing the positions of all cells in the specified area, which is different from the getrange method, which organizes the data of the selection by cell (rather than a continuous area). + +- **Usage**: + + - Select the specified area in the table, and then execute + + `luckysheet.getRange()` + + The returned result is: + ```json + [ + {"row":[0,0],"column":[0,2]}, + {"row":[1,1],"column":[0,0]}, + {"row":[3,3],"column":[0,0]} + ] + ``` + Where,{"row":[0,0],"column":[0,2]} denote a whole continuous region. + + - Select the area above in the table and execute + + `luckysheet.getRangeWithFlatten()` + + The returned result is: + ```json + [ + {"r":0,"c":0}, + {"r":0,"c":1}, + {"r":0,"c":2}, + {"r":1,"c":0}, + {"r":3,"c":0} + ] + ``` + +------------ + + +### getRangeValuesWithFlatte() + +- **Explanation**: + + Returns an array of objects representing the contents of all cells in a specified range + +- **Usage**: + + - Select the specified area in the table, and then execute + + `luckysheet.getRange()` + + The returned result is: + ```json + [ + {"row":[0,0],"column":[0,2]}, + {"row":[1,1],"column":[0,0]}, + {"row":[3,3],"column":[0,0]} + ] + ``` + Where,{"row":[0,0],"column":[0,2]} denote a whole continuous region. + + - Select the area above in the table and execute + + `luckysheet.getRangeValuesWithFlatte()` + + The returned result is: + ```json + [ + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 1, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "1" + }, + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 2, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "2" + }, + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 3, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "3" + }, + { + "v": "Background", + "ct": { + "fa": "General", + "t": "g" + }, + "m": "Background", + "bg": null, + "bl": 1, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1 + }, + { + "v": "Border", + "ct": { + "fa": "General", + "t": "g" + }, + "m": "Border", + "bg": null, + "bl": 1, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1 + } + ] + ``` +------------ + +### getRangeAxis() + +- **Explanation**: + + Returns an array of coordinate strings corresponding to the current selection. Multiple selections may exist. Each selection may be a single cell (such as A1) or a rectangular region of multiple cells (such as D9: E12) + +- **Usage**: + + - The current selection is"E10:E14"、"A7:B13"、"C4"、 "A3" and "C6:D9", execute + + `luckysheet.getRangeAxis()` + + The returned result is: + ```json + ["E10:E14", "A7:B13", "C4", "A3", "C6:D9"] + ``` + +------------ + ### getRangeValue([setting]) - **Parameter**: @@ -850,7 +1037,6 @@ Use note: ------------ ### getRangeJson(title [,setting]) - - **Parameter**: @@ -877,8 +1063,7 @@ Use note: The returned result is: ```json [ - { "A": "value1", "B": "value3" }, - { "A": "value2", "B": "value4" } + { "value1": "value2", "value3": "value4" } ] ``` @@ -889,7 +1074,8 @@ Use note: The returned result is: ```json [ - { "value1": "value2", "value3": "value4" } + { "A": "value1", "B": "value3" }, + { "A": "value2", "B": "value4" } ] ``` @@ -1102,8 +1288,6 @@ Use note: ### setRangeShow(range [,setting])
-[todo] - - **Parameter**: - {Array | Object | String} [range]: The range of the selection, the format of the supported selection is `"A1:B2"`, `"sheetName!A1:B2"` or `{row:[0,1],column: [0,1]}`, allows an array of multiple selections; the default is the current selection @@ -1201,7 +1385,7 @@ Use note: } ] ] - luckysheet.setRangeValue(data) + luckysheet.setRangeValue(data,{range:"A1:B2"}) ``` ------------ @@ -1746,9 +1930,9 @@ Use note: + `"flipLeftRight"`: flip left and right + `"flipClockwise"`: rotate clockwise + `"flipCounterClockwise"`: rotate counterclockwise - + `"Transpose"`: Transpose - + `"DeleteZeroByRow"`: delete 0 values at both ends by row - + `"DeleteZeroByColumn"`: delete zero values at both ends by column + + `"transpose"`: Transpose + + `"deleteZeroByRow"`: delete 0 values at both ends by row + + `"deleteZeroByColumn"`: delete zero values at both ends by column + `"removeDuplicateByRow"`: delete duplicate values by row + `"removeDuplicateByColumn"`: remove duplicate values by column + `"newMatrix"`: Produce a new matrix @@ -1828,7 +2012,7 @@ Use note: Return all worksheet configurations, the format is the same as the worksheet configuration, and the results obtained can be used as options.data when the form is initialized. - Therefore, this API is suitable for manually operating and configuring a table, and then taking out all the worksheet information to save it, and then use it for table creation in other places. If you want to get all the workbook data including the workbook configuration, you can use [toJson](#toJson()) + Therefore, this API is suitable for manually operating and configuring a table, and then taking out all the worksheet information to save it, and then use it for table creation in other places. If you want to get all the workbook data including the workbook configuration, it is recommended to use [toJson](#toJson()), and it can be directly used to initialize Luckysheet. - **Usage**: @@ -1892,9 +2076,6 @@ Use note: ### getConfig([setting]) -[todo] - - - **Parameter**: - {PlainObject} [setting]: optional parameters @@ -1908,9 +2089,6 @@ Use note: ### setConfig([setting]) -[todo] - - - **Parameter**: - {PlainObject} [setting]: optional parameters @@ -1921,6 +2099,19 @@ Use note: Quickly set the current worksheet config configuration +------------ +### updataSheet([setting]) + +- **参数**: + + - {PlainObject} [setting]: optional parameters + + {Array} [data]: Worksheet Configuration + + {Function} [success]: callback function for the end of the operation + +- **说明**: + + Update the corresponding sheet according to the set sheet configuration + ------------ ### setSheetAdd([setting]) @@ -2269,9 +2460,6 @@ Use note: ### scroll([setting]) -[todo] - - - **参数**: - {PlainObject} [setting]: optional parameters @@ -2331,8 +2519,6 @@ Use note: ### setWorkbookName(name [,setting]) -[todo] - - **Parameter**: - {Number} [name]: Workbook name @@ -2345,6 +2531,19 @@ Use note: ------------ +### getWorkbookName(name [,setting]) + +- **Parameter**: + + - {PlainObject} [setting]: optional parameters + + {Function} [success]: callback function for the end of the operation + +- **Explanation**: + + get workbook name + +------------ + ### undo([setting]) [todo] @@ -2379,17 +2578,41 @@ Use note: ### refreshFormula([setting]) -[todo] +- **Parameter**: + + - {Function} [success]: callback function for the end of the operation + +- **Explanation**: + + Force refresh formula. When you directly modify the values of multiple cells without triggering a refresh, and these cells are associated with formulas, you can use this API to force a formula refresh to be triggered at the end. + +------------ + +### refreshMenuButtonFocus([data],[r],[c],[success]) - **Parameter**: - - {PlainObject} [setting]: optional parameters - + {Object | String} [range]: Set the target selection range of the parameter. The supported selection format is `"A1:B2"`, `"sheetName!A1:B2"` or `{row:[0,1], column:[0,1]}`, allows an array of multiple selections; the default is the current selection ;The default is the entire current worksheet - + {Function} [success]: callback function for the end of the operation + - {Array} [data]: Operational data + - {Number} [r]: Specified row + - {Number} [c]: Specified column + - {Function} [success]: callback function for the end of the operation + +- **Explanation**: + + Refreshes the top status bar status of the specified cell. + +------------ + +### checkTheStatusOfTheSelectedCells(type,status) + +- **Parameter**: + + - {String} type: type + - {String} status: Target state value - **Explanation**: - Force refresh formula. When you directly modify the values of multiple cells without triggering a refresh, and these cells are associated with formulas, you can use this API to force a formula refresh to be triggered at the end. It is generally recommended to specify the affected cell range to prevent For performance issues, if you can't determine it, leave it blank to keep the entire worksheet traversed and refreshed. + Check whether the status of all specified types of cells in the selection meets the conditions (mainly bold, italics, strikeouts, underscores, etc.). ------------ @@ -2568,8 +2791,6 @@ Use note: ### toJson() -[todo] - - **Explanation**: The exported json string can be directly used as the parameter `options` when the workbook is initialized by `luckysheet.create(options)`. The usage scenario is to manually save all the parameters after the user manipulates the table, and then initialize the table elsewhere. Use, similar to the import and export of a luckysheet proprietary format. diff --git a/docs/guide/config.md b/docs/guide/config.md index d50edd709d39241ab1bb64b4cad3349b70818259..c03224f7056b2ff6b8140f6830dc529502689015 100644 --- a/docs/guide/config.md +++ b/docs/guide/config.md @@ -28,7 +28,6 @@ Luckysheet has opened more detailed custom configuration options, which are as f - Customize the toolbar ([showtoolbarConfig](#showtoolbarConfig)) - Customize the bottom sheet bar ([showsheetbarConfig](#showsheetbarConfig)) - Customize the counting bar ([showstatisticBarConfig](#showstatisticBarConfig)) -- Custom add row and back to the top ([sheetBottomConfig](#sheetBottomConfig)) - Custom cell right-click menu ([cellRightClickConfig](#cellRightClickConfig)) - Customize the right-click menu of the bottom sheet bar ([sheetRightClickConfig](#sheetRightClickConfig)) @@ -59,24 +58,22 @@ The following are all supported setting parameters - Customize the bottom sheet bar [showsheetbarConfig](#showsheetbarConfig) - The bottom count bar [showstatisticBar](#showstatisticBar) - Custom Count Bar [showstatisticBarConfig](#showstatisticBarConfig) -- Custom add row and back to top [sheetBottomConfig](#sheetBottomConfig) -- Allow editing [allowEdit](#allowEdit) - Allow adding rows [enableAddRow](#enableAddRow) -- Allow adding columns [enableAddCol](#enableAddCol) +- Allow back to top [enableAddBackTop](#enableAddBackTop) - User Info [userInfo](#userInfo) - User Information Menu [userMenuItem](#userMenuItem) - Back button link [myFolderUrl](#myFolderUrl) - Ratio [devicePixelRatio](#devicePixelRatio) - Function Button [functionButton](#functionButton) - Auto-indent interface [showConfigWindowResize](#showConfigWindowResize) -- Load the next page [enablePage](#enablePage) - Refresh formula [forceCalculation](#forceCalculation) - Custom cell right-click menu [cellRightClickConfig](#cellRightClickConfig) - Customize the right-click menu of the bottom sheet bar [sheetRightClickConfig](#sheetRightClickConfig) -- Whether to show the row number area [showRowBar](#showRowBar) -- Whether to show the column number area [showColumnBar](#showColumnBar) +- The width of the row header area [rowHeaderWidth](#rowHeaderWidth) +- The height of the column header area [columnHeaderHeight](#columnHeaderHeight) - Whether to show the formula bar [sheetFormulaBar](#sheetFormulaBar) - Initialize the default font size [defaultFontSize](#defaultFontSize) +- Pager [pager](#pager) ### container - Type: String @@ -93,7 +90,7 @@ The following are all supported setting parameters ### lang - Type: String - Default: "en" -- Usage: Internationalization settings, allowing to set the language of the workbook, supporting Chinese ("zh") and English ("en") +- Usage: Internationalization settings, allow to set the language of the table, support simplified Chinese ("zh"), English ("en") and traditional Chinese ("zh_tw") and Spanish ("es") ------------ ### gridKey @@ -204,7 +201,8 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect bold: false, //'Bold (Ctrl+B)' italic: false, //'Italic (Ctrl+I)' strikethrough: false, //'Strikethrough (Alt+Shift+5)' - textColor: false, //'Text color' + underline: false, // 'Underline (Alt+Shift+6)' + textColor: false, //'Text color' fillColor: false, //'Cell color' border: false, //'border' mergeCell: false, //'Merge cells' @@ -349,27 +347,6 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect } } ``` ------------- -### sheetBottomConfig - -[todo] - -- Type: Object -- Default: {} -- Usage: Add row button and back to top button configuration below the worksheet -- Format: - ```json - { - addRow: false, // Add row button - backTop: false // Back to the top - } - ------------- -### allowEdit -- Type: Boolean -- Default: true -- Usage: Whether to allow front-end editing - ------------ ### enableAddRow - Type: Boolean @@ -377,16 +354,61 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect - Usage: Allow additional rows ------------ -### enableAddCol +### enableAddBackTop - Type: Boolean - Default: true -- Usage: Allow adding columns +- Usage: Allow back to top ------------ ### userInfo -- Type: String -- Default: `' rabbit'` -- Usage: User information display style in the upper right corner +- Type: String | Boolean | Object +- Default: false +- Usage: User information display style in the upper right corner,Support the following three formats + 1. HTML template string, such as: + + ```js + options:{ + // Other configuration + userInfo:' Lucky', + } + ``` + + Or an ordinary string, such as: + + ```js + options:{ + // Other configuration + userInfo:'Lucky', + } + ``` + + 2. Boolean type, such as: + + `false`: Do not show + ```js + options:{ + // Other configuration + userInfo:false, // Do not display user information + } + + ``` + `ture`: Show the default string + ```js + options:{ + // Other configuration + userInfo:true, // Show HTML:' Lucky' + } + + ``` + 3. Object format, set `userImage`: user avatar address and `userName`: user name, such as: + ```js + options:{ + // Other configuration + userImage:'https://cdn.jsdelivr.net/npm/luckyresources@1.0.3/assets/img/logo/logo.png', // Avatar url + userName:'Lucky', // username + } + ``` + 4. Note that if set to `undefined` or not set, the same as setting `false` ------------ ### userMenuItem @@ -418,12 +440,6 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect - Default: true - Usage: The configuration of the chart or pivot table will pop up on the right, set whether the workbook will be automatically indented after popping up ------------- -### enablePage -- Type: Boolean -- Default: false -- Usage: Allow to load next page - ------------ ### forceCalculation - Type: Boolean @@ -439,33 +455,65 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect ------------ ### cellRightClickConfig -[todo] - - Type: Object - Default: {} - Usage: Custom configuration cell right-click menu -- Format: - ```json +- Format: + ```json { - copy: false, //Copy - copyAs: false, //Copy as - paste: false, //Paste - insert: false, //Insert - delete: false, //Delete - hide: false, //Hide - deleteCell: false, //Delete cell - clear: false, //Clear content - matrix: false, //Matrix operation selection - sort: false, //Sort selection - filter: false, //Filter selection - chart: false //Chart generation - } + copy: false, // copy + copyAs: false, // copy as + paste: false, // paste + insertRow: false, // insert row + insertColumn: false, // insert column + deleteRow: false, // delete the selected row + deleteColumn: false, // delete the selected column + deleteCell: false, // delete cell + hideRow: false, // hide the selected row and display the selected row + hideColumn: false, // hide the selected column and display the selected column + rowHeight: false, // row height + columnWidth: false, // column width + clear: false, // clear content + matrix: false, // matrix operation selection + sort: false, // sort selection + filter: false, // filter selection + chart: false, // chart generation + image: false, // insert picture + link: false, // insert link + data: false, // data verification + cellFormat: false // Set cell format + } + ``` + + In addition to the cells, the configuration here also includes the row header right-click menu, the column header right-click menu, and the column header drop-down arrow menu. The specific configuration relationships are as follows: + + |Right-click menu configuration|Cell|Row header|Column header|Column arrow| + | ------------ | ------------ | ------------ | ----------- | ------------ | + |copy|copy|copy|copy|copy| + |copyAs|copy as|copy as|copy as|copy as| + |paste|paste|paste|paste|paste| + |insertRow|Insert a row|Increase N rows upwards and N rows downwards|-|-| + |insertColumn|Insert Column|-|Add N columns to the left and N columns to the right|Add N columns to the left and N columns to the right| + |deleteRow|Delete selected row|Delete selected row|-|-| + |deleteColumn|Delete selected column|-|Delete selected column|Delete selected column| + |deleteCell|Delete cell|-|-|-| + |hideRow|-|Hide the selected row and show the selected row|-|-| + |hideColumn|-|-|Hide the selected column and show the selected column|Hide the selected column and show the selected column| + |rowHeight|-|row height|-|-| + |columnWidth|-|-|Column Width|Column Width| + |clear|clear content|clear content|clear content|-| + |matrix|Matrix Operation Selection|Matrix Operation Selection|Matrix Operation Selection|-| + |sort|Sort selection|Sort selection|Sort selection|A-Z sort and Z-A sort| + |filter|Filter selection|Filter selection|Filter selection|-| + |chart|chart generation|chart generation|chart generation|-| + |image|Insert Picture|Insert Picture|Insert Picture|-| + |link|Insert link|Insert link|Insert link|-| + |data|Data Verification|Data Verification|Data Verification|-| + |cellFormat|Set cell format|Set cell format|Set cell format|-| ------------ ### sheetRightClickConfig -[todo] - - Type: Object - Default: {} - Usage: Customize the right-click menu of the bottom sheet bar @@ -476,23 +524,21 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect copy: false, //Copy rename: false, //Rename color: false, //Change color - hide: false, //Hide - show: false, //Unhide - left: false, //Move to the left - right: false //Move to the right + hide: false, //Hide, unhide + move: false, //Move to the left, move to the right } ------------ -### showRowBar -- Type: Boolean -- Default: true -- Usage: Whether to show the row number area +### rowHeaderWidth +- Type: Number +- Default: 46 +- Usage: The width of the row header area, if set to 0, it means to hide the row header ------------ -### showColumnBar -- Type: Boolean -- Default: true -- Usage: Whether to show the column number area +### columnHeaderHeight +- Type: Number +- Default: 20 +- Usage: The height of the column header area, if set to 0, it means hide the column header ------------ ### sheetFormulaBar @@ -508,6 +554,36 @@ Note that you also need to configure `loadUrl` and `loadSheetUrl` to take effect ------------ +### limitSheetNameLength +- Type: Boolean +- Default: true +- Usage:Is the length of the sheet name limited in scenarios such as sheet renaming + +------------ + +### defaultSheetNameMaxLength +- Type:Number +- Default:31 +- Usage:Default maximum allowed sheet name length + +------------ + +### pager +- Type:Object +- Default:null +- Usage:Pager button settings, the first version of the solution is directly used jquery plug-in [sPage](https://github.com/jvbei/sPage) + Clicking the paging button will trigger the hook function `onTogglePager`, which returns the current page number, which is the same as the `backFun` method of `sPage`. This pager setting is only responsible for the UI part. For the specific data request and data rendering after switching paging, please enter the `onTogglePager` custom processing in the number of hook lines. + ```js + pager: { + pageIndex: 1, //Current page number + pageSize: 10, //How many rows of data are displayed on each page + total: 50, //Total number of rows of data + selectOption: [10, 20] //Options that allow setting the number of rows per page + } + ``` + +------------ + ## Hook Function (TODO) When the hook function is used in secondary development, hooks will be implanted in each common mouse or keyboard operation, and the function passed in by the developer will be called to expand the function of Luckysheet. @@ -516,66 +592,231 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ## Cell +### cellEditBefore + +- Type: Function +- Default: null +- Usage: Triggered before entering the cell editing mode. When a cell is selected and in the non-editing state, there are usually the following three conventional methods to trigger the edit mode + - Double click the cell + - Hit Enter + - Use API: enterEditMode +- Parameter: + - {Array} [range]: Current selection range + +------------ +### cellUpdateBefore + +- Type: Function +- Default: null +- Usage: Triggered before updating this cell value, `return false` will not perform subsequent updates. After modifying the cell in the editing state, this hook is triggered before exiting the editing mode and updating the data. +- Parameter: + - {Number} [r]: The row number of the cell + - {Number} [c]: The column number of the cell + - {Object | String | Number} [value]: The content of the cell to be modified + - {Boolean} [isRefresh]: Whether to refresh the entire table + +------------ +### cellUpdated + +- Type: Function +- Default: null +- Usage: Triggered after updating this cell +- Parameter: + - {Number} [r]: The row number of the cell + - {Number} [c]: The column number of the cell + - {Object} [oldValue]: Cell object before modification + - {Object} [newValue]: Modified cell object + - {Boolean} [isRefresh]: Whether to refresh the entire table + +------------ +### cellRenderBefore + +- Type: Function +- Default: null +- Usage: Triggered before the cell is rendered, `return false` will not render the cell +- Parameter: + - {Object} [cell]:Cell object + - {Object} [position]: + + {Number} [r]: The row number of the cell + + {Number} [c]: The column number of the cell + + {Number} [start_r]: The horizontal coordinate of the upper left corner of the cell + + {Number} [start_c]: The vertical coordinate of the upper left corner of the cell + + {Number} [end_r]: The horizontal coordinate of the lower right corner of the cell + + {Number} [end_c]: The vertical coordinate of the lower right corner of the cell + - {Object} [sheet]: Current sheet object + - {Object} [ctx]: The context of the current canvas + +------------ ### cellRenderAfter + - Type: Function - Default: null -- Usage: Triggered after the cell rendering ends +- Usage: Triggered after the cell rendering ends, `return false` will not render the cell - Parameter: - - {Number} [r]: Row number of cell - - {Number} [c]: Column number of cell - - {Object} [v]: Cell object + - {Object} [cell]: Cell object + - {Object} [position]: + + {Number} [r]: The row number of the cell + + {Number} [c]: The column number of the cell + + {Number} [start_r]: The horizontal coordinate of the upper left corner of the cell + + {Number} [start_c]: The vertical coordinate of the upper left corner of the cell + + {Number} [end_r]: The horizontal coordinate of the lower right corner of the cell + + {Number} [end_c]: The vertical coordinate of the lower right corner of the cell + - {Object} [sheet]: Current worksheet object + - {Object} [ctx]: The context of the current canvas + +- Example: + + A case of drawing two pictures in the upper left corner and lower right corner of cell D1 + :::::: details + ```js + luckysheet.create({ + hook: { + cellRenderAfter: function (cell, position, sheetFile, ctx) { + var r = position.r; + var c = position.c; + if (r === 0 && c === 3) { // Specify to process cell D1 + if (!window.storeUserImage) { + window.storeUserImage = {} + } + + if (!window.storeUserImage[r + '_' + c]) { + window.storeUserImage[r + '_' + c] = {} + } + + var img = null; + var imgRight = null; + + if (window.storeUserImage[r + '_' + c].image && window.storeUserImage[r + '_' + c].imgRight) { + + // Fetch directly after loading + img = window.storeUserImage[r + '_' + c].image; + imgRight = window.storeUserImage[r + '_' + c].imgRight; + + } else { + + img = new Image(); + imgRight = new Image(); + + img.src = 'https://www.dogedoge.com/favicon/developer.mozilla.org.ico'; + imgRight.src = 'https://www.dogedoge.com/static/icons/twemoji/svg/1f637.svg'; + + // The picture is cached in the memory, fetched directly next time, no need to reload + window.storeUserImage[r + '_' + c].image = img; + window.storeUserImage[r + '_' + c].imgRight = imgRight; + + } + + + if (img.complete) { //Direct rendering that has been loaded + ctx.drawImage(img, position.start_c, position.start_r, 10, 10); + } else { + img.onload = function () { + ctx.drawImage(img, position.start_c, position.start_r, 10, 10); + } + + } + + if (imgRight.complete) { + ctx.drawImage(imgRight, position.end_c - 10, position.end_r - 10, 10, 10); + } else { + + imgRight.onload = function () { + ctx.drawImage(imgRight, position.end_c - 10, position.end_r - 10, 10, 10); + } + } + + } + } + } + }) + ``` + ::: ------------ -### cellHover +### cellAllRenderBefore + - Type: Function - Default: null -- Usage: Triggered when the mouse moves over the cell (hover) +- Usage:The method executed before all cells are rendered. Internally, this method is added before `luckysheetDrawMain` renders the table. - Parameter: - - {Number} [r]: Row number of cell - - {Number} [c]: Column number of cell - - {Object} [v]: Cell object + - {Object} [data]: Two-dimensional array data of the current worksheet + - {Object} [sheet]: Current worksheet object + - {Object} [ctx]: The context of the current canvas ------------ -### cellEditBefore +### rowTitleCellRenderBefore + - Type: Function - Default: null -- Usage: Triggered after double-clicking the cell, that is, when double-clicking the cell to edit the content, this method is triggered first +- Usage: Triggered before the row header cell is rendered, `return false` will not render the row header - Parameter: - - {Number} [r]: Row number of cell - - {Number} [c]: Column number of cell - - {Object} [v]: Cell object + - {String} [rowNum]: Row number + - {Object} [position]: + + {Number} [r]: The row number of the cell + + {Number} [top]: The vertical coordinate of the upper left corner of the cell + + {Number} [width]: Cell width + + {Number} [height]: Cell height + - {Object} [ctx]: The context of the current canvas ------------ -### cellEditAfter +### rowTitleCellRenderAfter + - Type: Function - Default: null -- Usage: Triggered after double-clicking the cell, that is, when double-clicking the cell to edit the content, this method is finally triggered +- Usage: Triggered after the row header cell is rendered, `return false` will not render the row header - Parameter: - - {Number} [r]: Row number of cell - - {Number} [c]: Column number of cell - - {Object} [oldV]: Cell object before Modified - - {Object} [newV]: Cell object after Modified + - {String} [rowNum]: Row number + - {Object} [position]: + + {Number} [r]: The row number of the cell + + {Number} [top]: The vertical coordinate of the upper left corner of the cell + + {Number} [width]: Cell width + + {Number} [height]: Cell height + - {Object} [ctx]: The context of the current canvas ------------ +### columnTitleCellRenderBefore -## Selected area +- Type: Function +- Default: null +- Usage: Triggered before the column header cell is rendered, `return false` will not render the column header +- Parameter: + - {Object} [columnAbc]: Column header characters + - {Object} [position]: + - {Number} [c]: The column number of the cell + - {Number} [left]: The horizontal coordinate of the upper left corner of the cell + - {Number} [width]: Cell width + - {Number} [height]: Cell height + - {Object} [ctx]: The context of the current canvas + +------------ +### columnTitleCellRenderAfter -### rangeSelectBefore - Type: Function - Default: null -- Usage: Frame selection or trigger before setting selection +- Usage: Triggered after the column header cell is rendered, `return false` will not render the column header - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object} [columnAbc]: Column header characters + - {Object} [position]: + - {Number} [c]: The column number of the cell + - {Number} [left]: The horizontal coordinate of the upper left corner of the cell + - {Number} [width]: Cell width + - {Number} [height]: Cell height + - {Object} [ctx]: The context of the current canvas ------------ -### rangeSelectAfter + +## Selected area + +### rangeSelect - Type: Function - Default: null - Usage: Frame selection or trigger after setting selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object} [sheet]: Current worksheet object + - {Object | Array} [range]: Selection area, may be multiple selection areas ------------ + ### rangeMoveBefore - Type: Function - Default: null @@ -598,7 +839,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: Before the selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: Data corresponding to the selection area ------------ @@ -607,7 +848,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: After the selection is modified - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [oldData]: Before modification, the data corresponding to the selection area - {Object} [newData]: After modification, the data corresponding to the selection area @@ -617,7 +858,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: Before copying selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: Data corresponding to the selection area ------------ @@ -626,7 +867,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: After copying selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: Data corresponding to the selection area ------------ @@ -635,7 +876,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: Before pasting the selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: The data corresponding to the selection area to be pasted ------------ @@ -644,7 +885,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: After pasting the selection - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [originData]: The data corresponding to the selection area to be pasted - {Object} [pasteData]: Data to paste @@ -690,7 +931,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: Before the selection is cleared - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: The data corresponding to the selection area to be cleared ------------ @@ -699,7 +940,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: After the selection is cleared - Parameter: - - {Object || Array} [range]: Selection area, may be multiple selection areas + - {Object | Array} [range]: Selection area, may be multiple selection areas - {Object} [data]: The data corresponding to the selection area to be cleared ------------ @@ -723,12 +964,14 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ## Worksheet ### sheetCreatekBefore +(TODO) - Type: Function - Default: null - Usage: Triggered before the worksheet is created, the new worksheet also includes the new pivot table ------------ ### sheetCreateAfter +(TODO) - Type: Function - Default: null - Usage: Triggered after the worksheet is created, the new worksheet also includes the new pivot table @@ -737,6 +980,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetMoveBefore +(TODO) - Type: Function - Default: null - Usage: Before the worksheet is moved @@ -746,6 +990,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetMoveAfter +(TODO) - Type: Function - Default: null - Usage: After the worksheet is moved @@ -756,6 +1001,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetDeleteBefore +(TODO) - Type: Function - Default: null - Usage: Before the worksheet is deleted @@ -764,6 +1010,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetDeleteAfter +(TODO) - Type: Function - Default: null - Usage: After the worksheet is deleted @@ -772,6 +1019,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetEditNameBefore +(TODO) - Type: Function - Default: null - Usage: Before changing the name of the worksheet @@ -781,6 +1029,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetEditNameAfter +(TODO) - Type: Function - Default: null - Usage: After changing the name of the worksheet @@ -791,6 +1040,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetEditColorBefore +(TODO) - Type: Function - Default: null - Usage: Before changing the color of the worksheet @@ -800,6 +1050,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetEditColorAfter +(TODO) - Type: Function - Default: null - Usage: After changing the color of the worksheet @@ -810,6 +1061,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetZoomBefore +(TODO) - Type: Function - Default: null - Usage: Before worksheet zoom @@ -819,6 +1071,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ ### sheetZoomAfter +(TODO) - Type: Function - Default: null - Usage: After worksheet zoom @@ -827,6 +1080,42 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - {String} [oldZoom]: Before modification, the current worksheet zoom ratio - {String} [newZoom]: After modification, the current worksheet zoom ratio +------------ +### sheetActivateBefore +(TODO) +- Type: Function +- Default: null +- Usage:Before worksheet activate +- Parameter: + - {Number} [i]: `index` of current worksheet + +------------ +### sheetActivateAfter +(TODO) +- Type: Function +- Default: null +- Usage:After worksheet activate +- Parameter: + - {Number} [i]: `index` of current worksheet + +------------ +### sheetDeactivateBefore +(TODO) +- Type: Function +- Default: null +- Usage:Before the worksheet changes from active to inactive +- Parameter: + - {Number} [i]: `index` of current worksheet + +------------ +### sheetDeactivateAfter +(TODO) +- Type: Function +- Default: null +- Usage:After the worksheet is changed from active to inactive +- Parameter: + - {Number} [i]: `index` of current worksheet + ------------ ## Workbook @@ -866,7 +1155,7 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ### updated - Type: Function - Default: null -- Usage: The method executed after each operation is updated is executed after the canvas rendering, that is, every time the client performs a workbook operation, Luckysheet saves the operation in the history and triggers it. When undoing and redoing, it is also an operation, of course, the hook function will be triggered. +- Usage: The method executed after each operation is updated is executed after the canvas rendering, monitor changes in worksheet content, that is, every time the client performs a workbook operation, Luckysheet saves the operation in the history and triggers it. When undoing and redoing, it is also an operation, of course, the hook function will be triggered. - Parameter: - {Object} [operate]: The history information of this operation will have different history records according to different operations. Refer to the source code [History](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/controlHistory.js ) @@ -880,6 +1169,16 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura ------------ +## Cooperative + +### cooperativeMessage + +- Type:Function +- Default:null +- Usage:Receive the cooperation message, secondary development. Expanding cooperative message instruction set +- Params: + - {Object} : Receives the entire collaboration message body object sent by the server + ## Image ### imageInsertBefore @@ -1046,4 +1345,16 @@ The hook functions are uniformly configured under ʻoptions.hook`, and configura - Default: null - Usage: Customized method of drilling down cell data, note that this hook function is mounted under options: `options.fireMousedown` +------------ + +## Pager + +### onTogglePager + +- Type: Function +- Default: null +- Usage: Click the page button to call back the function, return the current page number, refer to [sPage backFun](https://github.com/jvbei/sPage) +- Parameter: + - {Object} [page]: Return the current page object + ------------ \ No newline at end of file diff --git a/docs/guide/contribute.md b/docs/guide/contribute.md new file mode 100644 index 0000000000000000000000000000000000000000..c832a8d146e8fbdaa010a1c75aff80ab7c668550 --- /dev/null +++ b/docs/guide/contribute.md @@ -0,0 +1,221 @@ + +# Contribution guide + +welcome! We are very happy that you are here and look forward to your interest in participating in Luckysheet contributions. Of course, before you participate in the Luckysheet contribution, please make sure to read the following full text: + +## Our code of conduct + +1. We promise to respect all those who participated in the contribution, not limited to those who raised questions, contributed documents and code, resolved bugs and other contributions; + +2. We are obliged to abide by local laws and regulations, and we reject all behaviors with legal risks; +3. We oppose any participant's derogatory comments, personal attacks, harassment or insult to others, and other non-professional behaviors; +4. We have the right and responsibility to delete or edit content that does not comply with this code of conduct, not limited to code, issues, wikis, documents and others. Participants who do not comply with the code of conduct may be removed from the team; +5. We accept the supervision of anyone, and anyone can report to us the facts that are found to be inconsistent with this code of conduct through problem feedback. + +## How to participate in contributing? + +* Contributed documents: Browsing the document can deepen your understanding of Luckysheet. Once you find that the document is not clearly written or the logic is confusing, you can correct, modify, and supplement. You can go to [Google Forum](https://groups.google.com/g/luckysheet) to give feedback +* Contributing code: Welcome everyone to contribute code to the Luckysheet community, you are welcome to claim the Open state [Issues](https://github.com/mengshukeji/Luckysheet/issues) and unfinished features, submit a PR, and become one of the contributors If you find that some functions cannot meet your needs or have problems during use, please record in Issues +* Participate in the issue discussion: you can post your suggestions under any [Issues](https://github.com/mengshukeji/Luckysheet/issues) +* Review code: You can see PR submitted by all contributors on [Github](https://github.com/mengshukeji/Luckysheet), you can review their code and post your suggestions + +## How to submit issues + +Before you submit features/improvements, you should pay attention to the following points: + +* Please confirm whether the feature/improvement has been submitted by others +* An easy-to-understand title to explain the bug/submission feature/improvement you submitted +* If it is a bug, describe the cause of the bug in detail. If it can be reproduced, please try to provide complete reproduction steps +* If it is a feature, then the feature should have wide applicability, suitable for most users, and it is best to provide detailed design documents +* If it is an improvement, describe the benefits of this improvement as clearly as possible + +Specific steps: + +* Create [Issues](https://github.com/mengshukeji/Luckysheet/issues) and describe the issue clearly +* If you want to solve the issue, assign the issue to your own name. If you just submit a bug/feature/improvement and don’t have time to contribute code, set assignne to empty +* If it is a relatively large feature/improvement, try to output the design document first and follow the [Luckysheet RFC](https://github.com/mengshukeji/Luckysheet-rfcs) process for others to review + +## How to claim Issues + +In Luckysheet's [Issues](https://github.com/mengshukeji/Luckysheet/issues) list, there are many issues created by others that have not been repaired. If you are interested, you can claim these issues. The steps to claim are as follows: + +* Leave a message under the issue, express the idea of claiming the task, and specify **@I can solve it** +* If the submitter has no comments, assign the issue to your own name and update the progress in time +* If it is a relatively large feature, try to output the design document first and follow the [Luckysheet RFC](https://github.com/mengshukeji/Luckysheet-rfcs) process for others to review +* Develop the code and submit the code to github + +## How to submit code + +1. Fork to own warehouse + +Go to the Github page of [Luckysheet](https://github.com/mengshukeji/Luckysheet), and click the Fork button in the upper right corner to proceed. + +2. Git clone to local + +```shell +git clone https://github.com//Luckysheet.git +``` + +3. Establish a connection upstream + +```shell + +cd Luckysheet +gitremote add upstream https://github.com/mengshukeji/Luckysheet.git +``` + +4. Create a development branch + +```shell +git checkout -b dev +``` + +5. Modify the submission code + +```shell +git add. +npm run commit +git push origin dev +``` + +6. Sync code, synchronize the latest code to the local + +```shell +git fetch upstream +git rebase upstream/master +``` + +7. If there is a conflict (nothing can be ignored) + +```shell +git status # View conflict files and modify conflicts +git add. +git rebase --continue +``` +When submitting the git rebase --continue command, if vim prompts to edit the commit information, you can add your changes, then save and exit +> For vim commands, please refer to the [vim](https://www.runoob.com/linux/linux-vim.html) + +8. Submit branch code + +```shell +git push origin dev +``` + +If you are prompted to pull first, you can pull it before submitting +```shell +git pull origin dev +git push origin dev +``` +If the vim prompt to edit the commit information pops up, you can exit directly through the vim command +> For vim commands, please refer to [vim](https://www.runoob.com/linux/linux-vim.html) + +9. Submit pr +Go to the fork project in your github warehouse, switch to the branch you just created and modified, click new pull request, and add the corresponding description, and finally click Create pull request to submit + +## Code Specification + +> General code specification example + +* Keep the block depth to a minimum. Avoid nested If conditions as much as possible +```js +// CORRECT +if (!comparison) return + +if (variable) { + for (const item of items) {} +} else if (variable2) { + // Do something here +} + +// INCORRECT +if (comparison) { + if (variable) { + for (const item in items) {} + } else if (variable2) { + // Do something here + } +} else { + return +} +``` + +* Do not use operands for chain comparison +```js +// CORRECT + +if (cb) cb() +if (!cb || (cb === fn)) cb() + +// INCORRECT + +cb && cb() +(!cb || (cb === fn)) && cb() +``` + +* All variables should be declared at the beginning of the block in alphabetical order +```js +// CORRECT +function foo () { + const foo ='bar' + const bar ='foo' + + if (conditional) {} + + ... + + return foo +} + +// INCORRECT + +function foo () { + const foo ='bar' + + if (conditional) {} + + const bar ='foo' + + ... + + return foo +} +``` + +* Return as soon as possible +```js +// CORRECT +if (condition) return'foo' +if (condition2) return'bar' +// Return must have a blank line above +return'fizz' + +// INCORRECT +const variable ='' + +if (condition) { + variable ='foo' +} else if (condition2) { + variable ='bar' +} else { + variable ='fizz' +} + +return variable +``` + +## How to contribute documents + +## How to become Luckysheet Committer + +As long as anyone contributes to the Luckysheet project, you are the officially recognized Contributor of the Luckysheet project. There is no exact standard for growing from Contributor to Committer, and there is no expected timetable, but Committer candidates are generally A long-term active contributor, becoming Committer does not require a huge architectural improvement contribution, or how many lines of code contributions, contributing code, contributing documents, participating in mailing list discussions, helping to answer questions, etc., are all ways to increase their influence . + +List of potential contributions (in no particular order): + +* Submit the bugs, features, and improvements you found to the issue +* Update the official documents so that the project documents are the most recent, the best practices for writing Luckysheet, and various useful documents for the users +* Perform test and report test results, performance test and other MQ performance comparison test, etc. +* Review the work of others (including code and non-code) and publish your own suggestions +* Guide new contributors and be familiar with the community process +* Post a blog about Luckysheet +* Any contribution to the development of the Luckysheet community +* ...... diff --git a/docs/guide/data.md b/docs/guide/data.md index d7d8298074ca5a6df990b77379b8c3e463a374dd..bbd2c8931250635d71b27f516318895ff936db1c 100644 --- a/docs/guide/data.md +++ b/docs/guide/data.md @@ -219,7 +219,7 @@ ``` ### config.borderInfo - - Type:Object + - Type:Array - Default:{} - Usage:The border information of the cell - example: diff --git a/docs/guide/operate.md b/docs/guide/operate.md index c349bf7f063b8c6ca501898208c5dcd323570b98..77c58fd6a81dd7c83795030368a28a798630d0a6 100644 --- a/docs/guide/operate.md +++ b/docs/guide/operate.md @@ -886,3 +886,18 @@ There are four types of chart operations: add new chart -"add", move chart posit ```js luckysheetfile[0].chart[v.chart_id] = v; ``` + +## Backend return format + +Data format returned by websocket backend +```js +{ + createTime: command sending time + data:{} modified command + id: "7a" websocket id + returnMessage: "success" + status: "0" 0 tells the front end to modify according to the data command 1 meaningless + type: 0: connection is successful, 1: send to the currently connected user, 2: send information to other users, 3: send selection location information, 999: user disconnected + username: username +} +``` \ No newline at end of file diff --git a/docs/guide/resource.md b/docs/guide/resource.md new file mode 100644 index 0000000000000000000000000000000000000000..12c972459d7f1a96b5b9b70ec59895225985d692 --- /dev/null +++ b/docs/guide/resource.md @@ -0,0 +1,32 @@ +# Tutorials and resources + +Open source software is inseparable from the contribution of the community. Here will be a list of tutorials, learning materials and supporting solutions provided by the community. + +If you have written or found an excellent tutorial and want to recommend it to us, please directly [edit this page](https://github.com/mengshukeji/Luckysheet/edit/master/docs/guide/resource.md) submit a PR. + +## Blog +- [How Luckysheet initializes the data with merged cells](https://www.cnblogs.com/DuShuSir/p/13272397.html)[Pending translation] +- [How Luckysheet saves the data in the table to the database](https://www.cnblogs.com/DuShuSir/p/13857874.html)[Pending translation] +- [Case of introducing Luckysheet into local HTML using CDN loading](https://www.cnblogs.com/DuShuSir/p/13859103.html)[Pending translation] +- [Basic usage of Luckysheet, use `loadUrl` to load server data](https://blog.csdn.net/DCDC2020/article/details/108486525) +- [Luckysheet import and export implementation-Java background processing](https://blog.csdn.net/u014632228/article/details/109738221) + +## Front-end case + +### Community Case +- [luckysheet-vue-importAndExport](https://github.com/oy-paddy/luckysheet-vue-importAndExport/tree/master/) + +## Back-end case + +### Official case +- [Java backend Luckysheet Server](https://github.com/mengshukeji/LuckysheetServer) + +### Community Case +- [Luckysheet save and restore](https://gitee.com/ichiva/luckysheet-saved-in-recovery) (Java version) +- [Online form for collaborative editing based on Luckysheet](https://github.com/DilemmaVi/ecsheet) (Java version) +- [Use .net core 3.1 and Npoi to make a basic export based on LuckSheet](https://gitee.com/xiong-kangli/luck-sheet_.-net-core) (.NET version) +- [Collaborative editing in go language version](https://github.com/fandypeng/excel2config)(Go version) + +## Learning Materials + +- [How to build a web data analysis report from 0 to 1](https://github.com/mengshukeji/LuckyResources/blob/master/ppt/%E5%A6%82%E4%BD%95%E4%BB%8E0%E5%88%B01%E6%90%AD%E5%BB%BA%20Web%20%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E6%8A%A5%E8%A1%A8.pptx)[Pending translation] \ No newline at end of file diff --git a/docs/guide/sheet.md b/docs/guide/sheet.md index 389482eb6dd1c3db5fe90e2f0682c9d5c73044d5..fa92bd4b923ac25bb857d38dcaec10615336254b 100644 --- a/docs/guide/sheet.md +++ b/docs/guide/sheet.md @@ -42,7 +42,6 @@ eg: options.data: "luckysheet_conditionformat_save": {},//condition format "frozen": {}, //freeze row and column configuration "chart": [], //Chart configuration - "allowEdit": true, //is editable "zoomRatio":1, // zoom ratio "image":[], //image "showGridLines": 1, //Whether to show grid lines @@ -254,7 +253,7 @@ eg: options.data: ``` #### config.borderInfo -- type:Object +- type:Array - default:{} - usage:The border information of the cell - example: @@ -306,7 +305,7 @@ eg: options.data: 1. selection `rangeType: "range"` + Border type `borderType:"border-left" | "border-right" | "border-top" | "border-bottom" | "border-all" | "border-outside" | "border-inside" | "border-horizontal" | "border-vertical" | "border-none"`, - + Border thickness `style: 1 Thin | 2 Hair | 3 Dotted | 4 Dashed | 5 DashDot | 6 DashDotDot | 7 Double | 8 Medium | 9 MediumDashed | 10 MediumDashDot | 11 MediumDashDotDot | 12 SlantedDashDot | 13 Thick` + + Border thickness `style: 1 Thin | 2 Hair | 3 Dotted | 4 Dashed | 5 DashDot | 6 DashDotDot | 7 Double | 8 Medium | 9 MediumDashed | 10 MediumDashDot | 11 MediumDashDotDot | 12 SlantedDashDot | 13 Thick`, If it corresponds to the value of getLineStyle() of aspose.cells, you need to make a conversion yourself, refer to [aspose.cells](https://apireference.aspose.com/cells/net/aspose.cells/cellbordertype) + Border color `color: Hexadecimal color value` + Selection area `range: Row and column information array` @@ -1276,12 +1275,6 @@ eg: options.data: ``` ::: ------------- -### allowEdit -- type:Boolean -- default:true -- usage: is this sheet editable - ------------ ### zoomRatio - type:Number @@ -1375,7 +1368,6 @@ At this point, the lucky sheet file contains many local parameters that are not "frozen": {}, //Freeze row and column configuration "freezen": {}, //Storage freeze row and column rendering data "chart": [], //Chart configuration - "allowEdit": true, //Editable "zoomRatio":1, // Zoom ratio "image":[], //image "showGridLines": 1, //Whether to show grid lines diff --git a/docs/zh/about/README.md b/docs/zh/about/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fa46a8f275a6a24c8355dc4163823fe45663765f --- /dev/null +++ b/docs/zh/about/README.md @@ -0,0 +1,28 @@ +# 认识团队 + +Luckysheet是由个人主导、几个志同道合的小伙伴一同开发的项目。 + +## 核心团队活跃成员 +- [@wbfsa](https://github.com/wbfsa) +- [@eiji-th](https://github.com/eiji-th) +- [@fly-95](https://github.com/fly-95) +- [@tonytonychopper123](https://github.com/tonytonychopper123) +- [@Dushusir](https://github.com/Dushusir) +- [@iamxuchen800117](https://github.com/iamxuchen800117) +- [@wpxp123456](https://github.com/wpxp123456) +- [@c19c19i](https://weibo.com/u/3884623955) +- [@zhangchen915](https://github.com/zhangchen915) +- [@jerry-f](https://github.com/jerry-f) +- [@flowerField](https://github.com/flowerField) + +## 社区伙伴 +- [@yiwasheng](https://github.com/yiwasheng) +- [@danielcai1987](https://github.com/danielcai1987) +- [@qq6690876](https://github.com/qq6690876) +- [@javahuang](https://github.com/javahuang) +- [@TimerGang](https://github.com/TimerGang) +- [@gsw945](https://github.com/gsw945) +- [@swen-xiong](https://github.com/swen-xiong) +- [@lzmch](https://github.com/lzmch) +- [@kdevilpf](https://github.com/kdevilpf) +- [@WJWM0316](https://github.com/WJWM0316) \ No newline at end of file diff --git a/docs/zh/about/company.md b/docs/zh/about/company.md new file mode 100644 index 0000000000000000000000000000000000000000..8e5ff6eb6b2c1b76484130a3e651cb642013189c --- /dev/null +++ b/docs/zh/about/company.md @@ -0,0 +1,49 @@ +# 社区案例 + +我们搜集到了很多来自社区的案例反馈,还发现了以前我们没有预想到的Luckysheet使用场景。 + +积极聆听社区的声音,在大家的支持和反馈中不断更新迭代,已是我们的责任。 + + +## 公司案例 + + + + + + + + + + + + + + + + +
+ + + +

雄安智评云数字科技有限公司

+
+ + + +

Code the Future

+
+ + + +

吉客云

+
+ + + +

华为

+
+ + + +
\ No newline at end of file diff --git a/docs/zh/about/sponsor.md b/docs/zh/about/sponsor.md new file mode 100644 index 0000000000000000000000000000000000000000..f55690376e5dff5ebba840a68c08f5b9da6827dc --- /dev/null +++ b/docs/zh/about/sponsor.md @@ -0,0 +1,128 @@ +# 赞助 + +## 为什么赞助 + +如果您经营一家企业并在盈利产品中使用Luckysheet,那么赞助Luckysheet开发将具有商业意义:它可确保您的产品所依赖的项目保持健康并得到积极维护。 它还可以帮助您在Luckysheet社区中曝光,使得更多的人关注您的产品。 + +当然,如果Luckysheet在您的工作或个人项目中为您提供了帮助,也欢迎请作者喝杯果汁😋。 + +## 赞助方式 + +Luckysheet是MIT许可的开源项目,其持续稳定的开发离不开这些优秀的 [**支持者**](#赞助者列表)。 如果您想加入他们,请考虑: + +- [成为Patreon的支持者或赞助商](https://www.patreon.com/mengshukeji) +- [成为Open Collective的支持者或赞助商](https://opencollective.com/luckysheet) +- 通过PayPal,微信或支付宝一次性捐赠 + +| PayPal | 微信 | 支付宝 | +|---|---|---| +| [Paypal Me](https://www.paypal.me/wbfsa) | | | + +### Patreon和OpenCollective有什么区别? + +通过Patreon捐赠的资金将直接用于支持menshshukeji在Luckysheet上的工作。 通过OpenCollective捐赠的资金由透明费用管理,将用于补偿核心团队成员的工作和费用或赞助社区活动。 通过在任一平台上捐款,您的姓名/徽标将得到适当的认可和曝光。 + +## 赞助者列表 + +(按时间顺序排列) +- *勇 ¥ 30 +- 虚我 ¥ 200 +- 甜党 ¥ 50 +- Alphabet(Google)-gcf ¥ 1 +- **平 ¥ 100 +- **东 ¥ 10 +- debugger ¥ 20 +- 烦了烦 ¥ 10 +- 文顶顶 ¥ 200 +- yangxshn ¥ 10 +- 爱乐 ¥ 100 +- 小李飞刀刀 ¥ 66 +- 张铭 ¥ 200 +- 曹治军 ¥ 1 +- *特 ¥ 10 +- **权 ¥ 9.9 +- **sdmq ¥ 20 +- *旭 ¥ 10 +- Quentin ¥ 20 +- 周宇凡 ¥ 100 +- *超 ¥ 10 +- 维宁 ¥ 100 +- hyy ¥ 20 +- 雨亭寒江月 ¥ 50 +- **功 ¥ 10 +- **光 ¥ 20 +- terrywan ¥ 100 +- 王晓洪 ¥ 10 +- Sun ¥ 10 +- 忧绣 ¥ 100 +- Jasonx ¥ 10 +- 国勇 ¥ 66.6 +- 郎志 ¥ 100 +- 匿名 ¥ 1 +- ni ¥ 100 +- 苏 ¥ 50 +- Mads_chan ¥ 1 +- LK ¥ 100 +- 智连方舟 李汪石 ¥ 168 +- **发 ¥ 260 +- *超 ¥ 10 +- *勇 ¥ 10 +- *腾 ¥ 15 +- 名字好难起 ¥ 20 +- 大山 ¥ 1 +- waiting ¥ 1000 +- **宇 ¥ 10.00 +- 刘小帅的哥哥 ¥ 20.00 +- 宁静致远 ¥ 10.00 +- Eleven ¥ 1.00 +- **帆 ¥ 188 +- henry ¥ 100 +- .波罗 ¥ 50 +- 花落有家 ¥ 50 +- 踏遍南水北山 ¥ 1 +- LC ¥ 5 +- **明 ¥ 8.80 +- *军 ¥ 20 +- 张彪 ¥ 50 +- 企业文档云@肖敏 ¥ 10 +- 匿名 ¥ 50 +- 逍遥行 ¥ 10 +- z.wasaki ¥ 50 +- Make Children ¥ 20 +- Foam ¥ 20 +- 奥特曼( o|o)ノ三 ¥ 50 +- **凯 ¥ 10 +- **兵 ¥ 20 +- **川 ¥ 1 +- 二万 ¥ 50 +- 蔚然成林 ¥ 10 +- 邹杰 ¥ 10 +- 张永强 ¥ 50 +- 鱼得水 ¥ 50 +- Ccther ¥ 1 +- Eric Cheng ¥ 10 +- 佚名 ¥ 1 +- 花叶 ¥ 50 +- GT ¥ 20 +- 菜菜心 ¥ 10 +- fisher ¥ 1 +- JC ¥ 5 +- 佚名 ¥ 20 +- 独孤一剑 ¥ 50 +- mxt ¥ 20 +- 一叶迷山 ¥ 100 +- Jeff ¥ 100 +- 八千多条狗🐶 ¥ 100 +- 晓峰 ¥ 10 +- 戒 ¥ 1 +- 浪里个浪 ¥ 1 +- 回调函数 ¥ 50 +- 赖瓜子 ¥ 5 +- Milo•J ¥ 20 +- 可道云 ¥ 200 +- *程 ¥ 10 +- 来一杯卡布酸奶 ¥ 5 +- 刘久胜 ¥ 100 +- 快意江湖 ¥ 50 +- *新 ¥ 9.9 +- **龙 ¥ 100 \ No newline at end of file diff --git a/docs/zh/guide/FAQ.md b/docs/zh/guide/FAQ.md index 5954cafb401900f4c6aa492cf59dc85fff2e742b..0b2bce2f0957cb347c606b3136224a087d47b128 100644 --- a/docs/zh/guide/FAQ.md +++ b/docs/zh/guide/FAQ.md @@ -1,10 +1,10 @@ # 常见问题 -本章内容搜集了大家反馈的常见问题,如果官方文档和此列表都不能解答您的疑问,推荐到[官方论坛](https://support.qq.com/product/288322)反馈 +本章内容搜集了大家反馈的常见问题,如果官方文档和此列表都不能解答您的疑问,推荐到[官方论坛](https://github.com/mengshukeji/Luckysheet/discussions)反馈 -## **Q** luckysheetfile中的data和celldata有什么区别? +## luckysheetfile中的data和celldata有什么区别? -**A** : 表格初始化时使用一维数组格式的 [celldata](/zh/guide/sheet.html#celldata),初始化完成后转化为二维数组格式的data作为存储更新使用,celldata不再使用。 +**A**:表格初始化时使用一维数组格式的 [celldata](/zh/guide/sheet.html#celldata),初始化完成后转化为二维数组格式的data作为存储更新使用,celldata不再使用。 如果需要将`data`拿出来作为初始化数据,则需要执行 [transToCellData(data)](/zh/guide/api.html#transtocelldata-data-setting)转换为celldata数据。 其中`{ r, c, v }`格式的celldata转换为二维数组使用的是[transToData(celldata)](/zh/guide/api.html#transtodata-celldata-setting) @@ -20,68 +20,67 @@ luckysheet.transToData(celldata) ------------ -## **Q** 单元格的类型有哪些? +## 单元格的类型有哪些? -**A** : 参考[单元格格式列表](/zh/guide/cell.html),例举了可用的单元格格式 +**A**:参考[单元格格式列表](/zh/guide/cell.html),例举了可用的单元格格式 ------------ -## **Q** 如何在Vue/React项目中使用Luckysheet? - -**A** :  +## 如何在Vue/React项目中使用Luckysheet? +**A**:参考 - Vue案例:[luckysheet-vue](https://github.com/mengshukeji/luckysheet-vue) - React案例:[luckysheet-react](https://github.com/mengshukeji/luckysheet-react) ------------ -## **Q** 为什么初始化后表格里面的公式不会被触发? +## 为什么初始化后表格里面的公式不会被触发? -**A** : 参考 [表格数据格式](/zh/guide/sheet.html#calcchain) ,设置单元格数据对应的calcChain即可。 +**A**:参考 [表格数据格式](/zh/guide/sheet.html#calcchain) ,设置单元格数据对应的calcChain即可。 ------------ -## **Q** 远端加载数据是loadUrl还是updateUrl? +## 远端加载数据是loadUrl还是updateUrl? -**A** : [loadUrl](/zh/guide/config.html#loadurl)。配置了loadUrl,Luckysheet会通过ajax请求整个表格数据,而updateUrl会作为协同编辑实时保存的接口地址。 -注意:初始化数据需要配置loadUrl和loadSheetUrl参数,而协同编辑则在配置loadUrl、loadSheetUrl、updateUrl和allowUpdate四个参数才能生效。 +**A**:[loadUrl](/zh/guide/config.html#loadurl)。配置了loadUrl,Luckysheet会通过ajax请求整个表格数据,而updateUrl会作为协同编辑实时保存的接口地址。 +注意:初始化数据需要配置loadUrl参数,而协同编辑则在配置loadUrl、updateUrl和allowUpdate四个参数才能生效。 ------------ -## **Q** 每个sheet页的`index`和`order`有什么区别? +## 每个sheet页的`index`和`order`有什么区别? -**A** : 每个sheet页都有一个唯一id,就是`index`,可以用数字递增,也可以使用随机字符串,而`order`是所有的sheet的排序情况,从0开始,只能为数字`0,1,2...`。 +**A**:每个sheet页都有一个唯一id,就是`index`,可以用数字递增,也可以使用随机字符串,而`order`是所有的sheet的排序情况,从0开始,只能为数字`0,1,2...`。 ------------ -## **Q** dist文件夹下为什么不能直接运行项目? +## dist文件夹下为什么不能直接运行项目? -**A** :需要启动本地服务器 +**A**:需要启动本地服务器 - [Node搭建本地服务器](https://github.com/JacksonTian/anywhere) - [Python搭建本地服务器](https://developer.mozilla.org/zh-CN/docs/Learn/Common_questions/set_up_a_local_testing_server) ------------ -## **Q** excel导入导出怎么做? +## excel导入导出怎么做? -**A** :配合Luckysheet开发的excel导入导出库-[Luckyexcel](https://github.com/mengshukeji/Luckyexcel)已经实现了excel导入功能,导出功能正在开发当中。现阶段excel导出可以参考这2篇博文: +**A**:配合Luckysheet开发的excel导入导出库-[Luckyexcel](https://github.com/mengshukeji/Luckyexcel)已经实现了excel导入功能,导出功能正在开发当中。现阶段excel导出可以参考这2篇博文: - [基于LuckySheet在线表格的Excel下载功能开发](https://www.cnblogs.com/recode-hyh/p/13168226.html) - [使用exceljs导出luckysheet表格](https://blog.csdn.net/csdn_lsy/article/details/107179708) ------------ -## **Q** 初始化时合并单元格怎么做? +## 初始化时合并单元格怎么做? -**A** :参考以下案例 +**A**:参考以下案例 - [Luckysheet如何初始化含合并单元格的数据](https://www.cnblogs.com/DuShuSir/p/13272397.html) ------------ -## **Q** Luckysheet如何把表格里的数据保存到数据库?有没有服务端存储和协作的解决方案? +## Luckysheet如何把表格里的数据保存到数据库?有没有服务端存储和协作的解决方案? -**A** :有两个方案: +**A**:有两个方案: - 一是表格操作完成后,使用`luckysheet.getAllSheets()`方法获取到全部的工作表数据,全部发送到后台存储。 - 二是开启协同编辑功能,实时传输数据给后端。 @@ -89,22 +88,22 @@ luckysheet.transToData(celldata) ------------ -## **Q** 如何监听单元格hover或者点击事件?`cellRenderAfter`如何实时监听变化? +## 如何监听单元格hover或者点击事件?`cellRenderAfter`如何实时监听变化? -**A** :我们搜集到需要针对单元格事件的二次开发需求,规划了单元格相关的钩子函数,参考[单元格钩子函数](/zh/guide/config.html#cellrenderafter)(显示的TODO的暂未开放) +**A**:我们搜集到需要针对单元格事件的二次开发需求,规划了单元格相关的钩子函数,参考[单元格钩子函数](/zh/guide/config.html#cellrenderafter)(显示的TODO的暂未开放) ------------ -## **Q** 顶部的工具栏不支持自定义配置? +## 顶部的工具栏不支持自定义配置? -**A** : +**A**: 顶部工具栏的自定义配置使用初始[options.showtoolbarconfig](/zh/guide/config.html#showtoolbarconfig)(如果标注TODO表示暂未开发) ------------ -## **Q** 项目使用了jQuery吗? +## 项目使用了jQuery吗? -**A** :是的。Luckysheet内部启动时间比开源的时间早很多,所以用到了jQuery。打包工具会把jQuery集成到打包目录的`./plugins/js/plugin.js`文件中。 +**A**:是的。Luckysheet内部启动时间比开源的时间早很多,所以用到了jQuery。打包工具会把jQuery集成到打包目录的`./plugins/js/plugin.js`文件中。 如果您的项目中(比如React/Vue)也自己全局引用了jQuery,且造成了冲突,可以尝试去掉一个jQuery。 @@ -112,23 +111,23 @@ luckysheet.transToData(celldata) ------------ -## **Q** 如何为单元格对象新增字段? +## 如何为单元格对象新增字段? -**A** 首先参考[单元格对象格式](/zh/guide/cell.html),然后参照源码批注的部分[src/controllers/postil.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/postil.js)。批注是一个加在单元格对象上的一个配置。 +**A**:首先参考[单元格对象格式](/zh/guide/cell.html),然后参照源码批注的部分[src/controllers/postil.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/postil.js)。批注是一个加在单元格对象上的一个配置。 ------------ -## **Q** 工具栏图标加载不出来? +## 工具栏图标加载不出来? -**A** 工具栏及其他部分图标采用了iconfont图标,加载不出来是因为缺少了iconfont.css的引入,之前旧版官方文档未写清楚这一点对大家造成误导,很抱歉。 +**A**:工具栏及其他部分图标采用了iconfont图标,加载不出来是因为缺少了iconfont.css的引入,之前旧版官方文档未写清楚这一点对大家造成误导,很抱歉。 详细的Luckysheet使用教程参考已经更新的[官方文档](/zh/guide/#使用步骤) ------------ -## **Q** Luckyexcel打包后不动? +## Luckyexcel打包后不动? -**A** 打包的终端命令行不显示结束,但是如果`dist`文件夹内已经有了结果文件`luckyexcel.js`,则表明是正常的。 +**A**:打包的终端命令行不显示结束,但是如果`dist`文件夹内已经有了结果文件`luckyexcel.js`,则表明是正常的。 Luckyexcel是excel导入导出库,项目采用了gulp作为打包工具,旧版打包工具有点问题在命令行显示这块有些问题,问题已经修复。请还出现此问题的小伙伴做如下更新操作: 1. pull最新代码 @@ -139,9 +138,9 @@ Luckyexcel是excel导入导出库,项目采用了gulp作为打包工具,旧 ------------ -## **Q** 单元格不可编辑如何控制?表格保护怎么操作? +## 单元格不可编辑如何控制?表格保护怎么操作? -**A** 单元格不可编辑属于工作表保护的功能范畴,需要配置在每个sheet页中`config.authority`,最新的设置参数请参考[工作表保护](/zh/guide/sheet.html#config-authority)。 +**A**:单元格不可编辑属于工作表保护的功能范畴,需要配置在每个sheet页中`config.authority`,最新的设置参数请参考[工作表保护](/zh/guide/sheet.html#config-authority)。 为了大家便于理解工作表保护的功能使用,下方的视频演示了如何让当前整个工作表不可编辑,但是允许某一列单元格可编辑的功能: @@ -151,21 +150,21 @@ Luckyexcel是excel导入导出库,项目采用了gulp作为打包工具,旧 ------------ -## **Q** 数据验证怎么配置? +## 数据验证怎么配置? -**A** 最新文档已经提供了数据验证的配置信息,参考[数据验证配置](/zh/guide/sheet.html#dataVerification)。官方也提供了API方法 [setDataVerification](/zh/guide/api.html#setdataverification-optionitem-setting),用于动态设置数据验证功能。 +**A**:最新文档已经提供了数据验证的配置信息,参考[数据验证配置](/zh/guide/sheet.html#dataVerification)。官方也提供了API方法 [setDataVerification](/zh/guide/api.html#setdataverification-optionitem-setting),用于动态设置数据验证功能。 ------------ -## **Q** Luckysheet通过引入CDN有案例吗? +## Luckysheet通过引入CDN有案例吗? -**A** Luckysheet支持CDN方式引入,参考:[本地HTML采用cdn加载方式引入Luckysheet的案例](https://www.cnblogs.com/DuShuSir/p/13859103.html) +**A**:Luckysheet支持CDN方式引入,参考:[本地HTML采用cdn加载方式引入Luckysheet的案例](https://www.cnblogs.com/DuShuSir/p/13859103.html) ------------ -## **Q** 请问一下图片怎么限制在单元格里面自适应高度? +## 请问一下图片怎么限制在单元格里面自适应高度? -**A** 首先需要对图片设置移动并调整单元格大小,然后有以下几种情况: +**A**:首先需要对图片设置移动并调整单元格大小,然后有以下几种情况: - 如果图片位置完全在单元格内部时,当拉长单元格的宽度或高度的时候,图片不会随着单元格的变大而伸缩变大 - 如果图片位置完全在单元格内部时,当拉短单元格的宽度或高度,贴到图片的边时,图片会随着单元格的变小而伸缩变小 @@ -177,11 +176,150 @@ Luckyexcel是excel导入导出库,项目采用了gulp作为打包工具,旧 ------------ -## **Q** 如何获取工作表默认的行高列宽? +## 如何获取工作表默认的行高列宽? -**A** 有两种方式可以获取 +**A**:有两种方式可以获取 - 一是使用`luckysheet.getLuckysheetfile()`获取到所有工作表配置后,在各个工作表的配置中直接取得默认行高`defaultRowHeight`和默认列宽`defaultColWidth`。 - 二是开放了API可以获取到工作表默认的行高[getDefaultRowHeight](/zh/guide/api.html#getdefaultrowheight-setting)和列宽[getDefaultColWidth](/zh/guide/api.html#getdefaultcolwidth-setting) ------------- \ No newline at end of file +------------ + +## 如何隐藏工作表下方的添加行按钮和回到顶部按钮? + +**A**:已开放配置 +- 允许添加行 [enableAddRow](/zh/guide/config.html#enableaddrow) +- 允许回到顶部 [enableAddBackTop](/zh/guide/config.html#enableAddBackTop) + +------------ + +## 如何隐藏工作表的行标题和列标题? + +**A**:已开放配置 +- 行标题区域的宽度 [rowHeaderWidth](/zh/guide/config.html#rowheaderwidth) +- 列标题区域的高度 [columnHeaderHeight](/zh/guide/config.html#columnHeaderHeight) + +------------ + +## 调用什么方法能设置`config.merge`? + +**A**:三个方法 +- 界面操作 +- 用API:[setRangeMerge](/zh/guide/api.html#setrangemerge-type-setting) +- 手动组装merge参数 + +------------ + +## 为什么官方公布的新功能没有效果? + +**A**:第一步,检查下您是否使用了CDN的方式引入, + +Luckysheet教程里采用的CDN链接是 [jsdelivr](https://www.jsdelivr.com/package/npm/luckysheet) 提供的服务,代码是从 [npmjs.com](https://www.npmjs.com/) 自动同步过去的,不是从 [Github](https://github.com/mengshukeji/Luckysheet/) 同步过去的。因为我们新提交的代码,还需要经过一段时间的测试,所以不会立即发布到npm使用,导致了npm的代码稍滞后于Github。 + +如果需要尝试最新代码,我们强烈建议您从 [Luckysheet Github](https://github.com/mengshukeji/Luckysheet/) 主仓库拉取代码。后续我们版本稳定了,会考虑实时发布npm包。 + +第二步,如果是引用github仓库打包后的代码,测试判断是否有bug,您可以查找问题并尝试修复,再[提交PR](https://github.com/mengshukeji/Luckysheet/pulls),如果修复不了,请[提交issues](https://github.com/mengshukeji/Luckysheet/issues)。 + +------------ + +## `npm run dev`报错:`Error: Cannot find module 'rollup'`? + +**A**:可能是npm包安装问题,尝试以下步骤: +1. `npm cache clean --force` +2. `npm i rimraf -g` +3. `rimraf node_modules` +4. 删除package-lock.json文件 +5. `npm i` +6. `npm run dev` + +提示:大多数的其他npm安装问题,也可以尝试此步骤来解决。 + +------------ + +## 怎样在vue工程里对Luckysheet进行二次开发? + +**A**:[luckysheet-vue](https://github.com/mengshukeji/luckysheet-vue) 案例是提供一个应用集成的方案。 + +如果本地直接开发的话: +1. 把Luckysheet的工程和自己的Vue工程都启动起来,比如Luckysheet的工程在 `http://localhost:3001` +2. 在Vue工程里面通过 `http://localhost:3001` 引入Luckysheet使用 + +这样的话,Luckysheet实时修改后,Vue工程里是可以看到更改的 + +------------ + +## 创建图表时候报错`Store.createChart`? + +**A**:需要引入图表插件才能使用,工作簿初始化的时候应该配置图表插件使用,参考 + +- 插件配置 [plugins](/zh/guide/config.html#配置项) +- 或 官方demo [src/index.html](https://github.com/mengshukeji/Luckysheet/blob/master/src/index.html) + +通常,参考demo配置完后就可以和demo一样正常使用了,但是还是会偶现`chartmix is not defined`,这时需要在谷歌浏览器控制台的network里检查下图表的依赖是否都加载了,有5项依赖需要关注:`vue / vuex / element-ui / echarts / chartmix.umd.js`。 + +------------ + +## 单元格能增加自定义属性吗? + +**A**:直接赋值到单元格对象上的自定义属性会被过滤,要想使得自定义属性生效,需要二开去除过滤属性的代码。 + +------------ + +## 如何输入以`'='`开头的文本?例如`=currentDate('YYYY-MM-DD')`,它默认会去掉函数,函数怎么禁止? + +**A**:前面加一个单引号就行,会强制识别为字符串,和excel表现一致的。比如:`'=currentDate('YYYY-MM-DD')` + +------------ + +## create回调为什么没有效果? + +**A**:API 方法`luckysheet.create()`这个方法没有回调,但是Luckysheet提供了钩子函数用于在指定位置执行回调方法,比如: +- 表格创建之前触发 [workbookCreateBefore](/zh/guide/config.html#workbookcreatebefore) +- 表格创建之后触发 [workbookCreateAfter](/zh/guide/config.html#workbookcreateafter) + +------------ + +## create的时候默认选中第一个单元格,怎么去除? + +**A**:选中单元格时默认是高亮,把高亮去除即可,使用API: [setRangeShow](/zh/guide/api.html#setrangeshow-range-setting) + +```js +luckysheet.setRangeShow("A2",{show:false}) +``` + +------------ + +## 右键事件绑定在哪? + +**A**:在源码的 [src/controllers/hander.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/handler.js) 搜索`event.which == "3"`即可找到右键事件触发执行的代码。 + +------------ + +## 如何添加自定义工具栏? + +**A**:暂未提供配置,可以参照工具栏打印按钮的实现来修改源码: +1. 全局搜索 `luckysheet-icon-print`即可找到打印按钮的实现,在 [src/controllers/constant.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/constant.js) 中增加一个类似的模板字符串,需要自定义一个唯一id +2. 修改 [src/controllers/resize.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/resize.js) ,在toobarConfig对象中新增一条记录 +3. 修改 [src/controllers/menuButton.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/menuButton.js) ,新增一个事件监听 + +------------ + +## 如何添加自定义公式? + +**A**:需要修改两处源码: +1. 在 [src/function/functionImplementation.js](https://github.com/mengshukeji/Luckysheet/blob/master/src/function/functionImplementation.js) 文件中的`functionImplementation`对象中增加一个公式,格式参考`SUM`/`AVERAGE`等公式 +2. 修改 [src/locale](https://github.com/mengshukeji/Luckysheet/blob/master/src/locale) 文件目录下所有的语言包,将自己新增的公式说明加到`functionlist`数组中。其中,`t`是函数的类别,`m`是参数的个数,最小参数个数和最大参数个数。 + +------------ + +## 有没有类似loadData接口,我想实现先加载10条记录,然后再动态加载数据,这些数据都追加到表格中? + +**A**:有的。我们`loadSheetUrl`提供了这个功能,初始化`options.enablePage = true`可以开启。 + +源码里搜索`enablePage`可以看到,有个`method.addDataAjax`方法,里面就有一个ajax请求,用来动态加载数据,这些数据会追加到表格中。 + +这个功能现在在文档上是隐藏的,是因为这个接口我们做的时候,接口参数是根据我们实际业务匹配的,可能不太通用,我们准备抽象后再放出来给大家用,如果您想自己用可以依据这个改下。 + +推荐您考虑自己写接口来加载数据,然后使用`setRangeValue`来在指定位置追加数据,这样的自定义程度更高。 + +------------ diff --git a/docs/zh/guide/README.md b/docs/zh/guide/README.md index ac9fa97ff7f45430e52550aec06031a099c7274e..08e79dbe2b30a59959cbd0ca7efe8c55a276118a 100644 --- a/docs/zh/guide/README.md +++ b/docs/zh/guide/README.md @@ -4,13 +4,17 @@ Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置简单、完全开源。 ## Demo -[在线demo](https://mengshukeji.github.io/LuckysheetDemo/) +[在线demo](https://dream-num.github.io/LuckysheetDemo/) ![演示](/LuckysheetDocs/img/LuckysheetDemo.gif) +## 在线案例 + +- [协同编辑Demo](http://luckysheet.lashuju.com/demo/) + ## 特性 -### 格式设置 +### 🛠️格式设置 + **样式** (修改字体样式,字号,颜色或者其他通用的样式) + **条件格式** (突出显示所关注的单元格或单元格区域;强调异常值;使用数据栏、色阶和图标集(与数据中的特定变体对应)直观地显示数据) + **文本对齐及旋转** @@ -18,29 +22,31 @@ Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置 + **数据类型** + **货币, 百分比, 数字, 日期** + **Custom** (和excel保持一致,例如: `##,###0.00` , `$1,234.56$##,###0.00_);[Red]($##,###0.00)`, `_($* ##,###0.00_);_(...($* "-"_);_(@_)`, `08-05 PM 01:30MM-dd AM/PM hh:mm` ) ++ **单元格内多样式** (Alt+Enter单元格内换行、上标、下标、单元格内可定义每个文字的不同样式) -### 单元格 +### 🧬单元格 + **拖拽选取来修改单元格** (对选区进行操作,可以拖动四边来移动选区,也可以在右下角对选区进行下拉填充操作) -+ **选取下拉填充** (对于一个1,2,3,4,5的序列,将会按照间隔为1进行下拉填充,而对2,4,6,8将会以2作为间隔。支持等差数列,等比数列,日期,周,天,月,年,中文数字填充) ++ **选区下拉填充** (对于一个1,2,3,4,5的序列,将会按照间隔为1进行下拉填充,而对2,4,6,8将会以2作为间隔。支持等差数列,等比数列,日期,周,天,月,年,中文数字填充) + **自动填充选项** (下拉填充后,会出现填充选项的菜单,支持选择复制,序列,仅格式,只填充格式,天,月,年的选择) + **多选区操作** (可以按住Ctrl键进行单元格多选操作,支持多选区的复制粘贴) + **查找和替换** (对内容进行查找替换,支持正则表达式,整词,大小写敏感) + **定位** (可以根据单元格的数据类型进行自动定位并选中,选中后可以批量进行格式等操作) + **合并单元格** ++ **数据验证(表单功能)** (支持Checkbox, drop-down list, datePicker) -### 行和列操作 +### 🖱️行和列操作 + **隐藏,插入,删除行或列** + **冻结行或列** (支持冻结首行和首列,冻结到选区,冻结调节杆可以进行拖动操作) + **文本分列** (可以把文本根据不同符号进行拆分,和excel的分列功能类似) -### 操作体验 +### 🔨操作体验 + **撤销/重做** -+ **复制/粘贴/剪切操作** (支持luckysheet到excel和excel到luckysheet带格式的互相拷贝) ++ **复制/粘贴/剪切操作** (支持Luckysheet到excel和excel到Luckysheet带格式的互相拷贝) + **快捷键支持** (快捷键操作保持与excel一致,如果有不同或者缺失请反馈给我们) + **格式刷** (与google sheet类似) + **任意选区拖拽** (选择单元格,输入公式,插入图表,会与选区相关,可以通过任意拖动和放大缩小选区来改变与之关联的参数) -### 公式和函数 +### ⚙️公式和函数 + **内置公式** + 数学 (SUMIFS, AVERAGEIFS, SUMIF, SUM, etc.) + 文本 (CONCATENATE, REGEXMATCH, MID) @@ -53,39 +59,41 @@ Luckysheet ,一款纯前端类似excel的在线表格,功能强大、配置 + **远程公式** (DM_TEXT_TFIDF, DM_TEXT_TEXTRANK,DATA_CN_STOCK_CLOSE etc. Need remote interface, can realize complex calculation) + **自定义公式** (根据身份证识别年龄,性别,生日,省份,城市等. AGE_BY_IDCARD, SEX_BY_IDCARD, BIRTHDAY_BY_IDCARD, PROVINCE_BY_IDCARD, CITY_BY_IDCARD, etc. 可以任意加入自己的公式哦) -### 表格操作 +### 📐表格操作 + **筛选** (支持颜色、数字、字符、日期的筛选) + **排序** (同时加入多个字段进行排序) -### 数据透视表 +### 📈数据透视表 + **字段拖拽** (操作方式与excel类似,拖动字段到行、列、数值、筛选等4个区域) + **聚合方式** (支持汇总、计数、去重计数、平均、最大、最小、中位数、协方差、标准差、方差等计算) + **筛选数据** (可对字段进行筛选后再进行汇总) + **数据透视表下钻** (双击数据透视表中的数据,可以下钻查看到明细,操作方式与excel一致) + **根据数据透视表新建图表** (数据透视表产生的数据也可以进行图表的制作) -### 图表 +### 📊图表 + **支持的图表类型** (目前折线图、柱状图、面积图、条形图、饼图可以使用,散点图、雷达图、仪表盘、漏斗图正在接入,其他图表正在陆续开发中,请大家给予建议) + **关于图表插件** (图表使用了一个中间插件[ChartMix](https://github.com/mengshukeji/chartMix)(MIT协议): 目前支持ECharts,正在逐步接入Highcharts、阿里G2、amCharts、googleChart、chart.js) + **Sparklines小图** (以公式的形式进行设置和展示,目前支持:折线图、面积图、柱状图、累积图、条形图、离散图、三态图、饼图、箱线图等) -### 分享及写作 +### ✍️分享及写作 + **评论** (评论的删除、添加、修改、隐藏) + **共享编辑** (支持多用户共享编辑,内置API) -### LuckySheet专有 +### 📚插入对象 ++ **插入图片** (支持JPG,PNG,SVG的插入、修改和删除,并且随表格的变动而产生变化) + +### ⚡Luckysheet专有 + **矩阵计算** (通过右键菜单进行支持:对选区内的数据进行转置、旋转、数值计算) + **截图** (把选区的内容进行截图展示) + **复制到其他格式** (右键菜单的"复制为", 支持复制为json、array、对角线数据、去重等) -+ **EXCEL,CSV,TXT 导入及导出** (专为luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出) -+ **插入图片和svg形状** (支持JPG,PNG,SVG,Pen tool的插入、修改和删除,并且随表格的变动而产生变化) -+ **数据验证(表单功能)** (支持Checkbox, drop-down list, datePicker) -+ **单元格内多样式** (Alt+Enter单元格内换行、上标、下标、单元格内科定义每个文字的不同样式) ++ **EXCEL导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出,导出正在开发) -### 未来开发计划 +### ⏱️未来开发计划 + **打印及设置** (像excel一样进行打印设置,并导出为图片或者PDF) + **树形菜单** (类似excel中的分级显示(分组)) + **表格新功能** (类似excel中表格的筛选器和切片器) ++ **CSV,TXT导入及导出** (专为Luckysheet打造的导入导出插件,支持密码、水印、公式等的本地导入导出) ++ **插入svg形状** (支持[Pen tool](https://github.com/mengshukeji/Pentool)的插入、修改和删除,并且随表格的变动而产生变化) + **文档** (完善文档和API) + **敬请期待...** (可以提出好的建议给我们) @@ -117,15 +125,19 @@ npm run build #### CDN ```html - - - - - - + + + + + + ``` -注意,`https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js`这个路径会拉取到最新的luckysheet代码,想要指定luckysheet版本,请在luckysheet后面加上版本号,如:`https://cdn.jsdelivr.net/npm/luckysheet@2.0.0/dist/luckysheet.umd.js` +注意,`https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js`这个路径意思是会拉取到最新的luckysheet代码,但是如果Luckysheet刚刚发布,jsdelivr网站可能还没来得及从npm上同步过去,故而使用这个路径还是会拉到上一个版本,我们推荐您直接指定最新版本。 + +想要指定Luckysheet版本,请在所有的CDN依赖文件后面加上版本号,如:`https://cdn.jsdelivr.net/npm/luckysheet@2.1.12/dist/luckysheet.umd.js`。 + +> 如何知道最新版本是哪一版?查看最新 [release记录](https://github.com/mengshukeji/Luckysheet/releases) 或者 [package.json](https://github.com/mengshukeji/Luckysheet/blob/master/package.json) 的`version`字段。 如果不方便访问 jsdelivr.net,还可以采用本地方式引入 @@ -247,8 +259,8 @@ luckysheetfile = [ {sheet1设置}, {sheet2设置}, {sheet3设置} ]` 如果您使用Luckysheet遇到了问题,按以下步骤来寻找答案 1. 使用多吉或者Google搜索常见技术问题 -2. Luckysheet相关的问题优先查看[Luckysheet官方文档](https://mengshukeji.github.io/LuckysheetDocs/zh/)(注意标注TODO的功能暂未实现) -3. 搜索[常见问题列表](https://mengshukeji.github.io/LuckysheetDocs/zh/guide/FAQ.html) +2. Luckysheet相关的问题优先查看[Luckysheet官方文档](https://dream-num.github.io/LuckysheetDocs/zh/)(注意标注TODO的功能暂未实现) +3. 搜索[常见问题列表](https://dream-num.github.io/LuckysheetDocs/zh/guide/FAQ.html) 4. 搜索[官方论坛](https://support.qq.com/product/288322),看看有没有人已经遇到过 5. 尝试自己检查或试验以找到答案 6. 请尝试阅读源代码以找到答案, diff --git a/docs/zh/guide/api.md b/docs/zh/guide/api.md index 756918bcdf538f5e81976fa5e76ee282ded077f5..d91da86c19cc6fad716414da68adbf89ebc918a0 100644 --- a/docs/zh/guide/api.md +++ b/docs/zh/guide/api.md @@ -6,6 +6,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 1. script全局引入时,所有API均挂载到window.luckysheet对象下面,可以在浏览器控制台打印看到;npm引入时,API也全部挂载在luckysheet对象下 2. `success`回调函数第一个参数为API方法的返回值 3. 需要新的API请到github [Issues](https://github.com/mengshukeji/Luckysheet/issues/new/choose)中提交,根据点赞数决定是否开放新API +4. API方法中所需的`order`参数为工作表对象中的`order`的值,而不是`index` ## 单元格操作 @@ -32,7 +33,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 `luckysheet.getCellValue(0, 0)` - - 返回指定data数据的第2行第2列单元格的原始值。 + - 返回指定data数据的第2行第2列单元格的显示值。 `luckysheet.getCellValue(1, 1, {type:"m"})` @@ -178,6 +179,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 + {Boolean} [isWholeWord]: 是否整词匹配;默认为 `false` + {Boolean} [isCaseSensitive]: 是否区分大小写匹配;默认为 `false` + {Number} [order]: 工作表下标;默认值为当前工作表下标 + + {String} [type]: 单元格属性;默认值为`"m"` - **说明**: @@ -187,6 +189,8 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 - 当前工作表查找`"value"`字符串 `luckysheet.find("value")` + - 当前工作表查找公式包含`"SUM"`的单元格 + `luckysheet.find("SUM",{type:"f"})` ------------ @@ -317,6 +321,18 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 冻结行列操作 特别注意,只有在`isRange`设置为`true`的时候,才需要设置`setting`中的`range`,且与一般的range格式不同。 + + 如果想在工作簿初始化后使用此API设置冻结,可以在工作簿创建后的钩子函数中执行,比如: + ```js + luckysheet.create({ + hook:{ + workbookCreateAfter:function(){ + luckysheet.setBothFrozen(false); + } + } + }); + + ``` - **示例**: @@ -391,7 +407,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 - 在第1列的位置插入3行空白行 - `luckysheet.insertRow(0, { number: 3 })` + `luckysheet.insertColumn(0, { number: 3 })` ------------ @@ -568,7 +584,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 - **参数**: - - {Number} [columnInfo]: 列数和宽度对应关系 + - {Object} [columnInfo]: 列数和宽度对应关系 - {PlainObject} [setting]: 可选参数 + {Number} [order]: 工作表下标;默认值为当前工作表下标 @@ -702,6 +718,178 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ +### getRangeWithFlatten() + +- **说明**: + + 返回表示指定区域内所有单元格位置的数组,区别getRange方法,该方法以cell单元格(而非某块连续的区域)为单位来组织选区的数据。 + +- **示例**: + + - 在表格中选择指定的区域,然后执行 + + `luckysheet.getRange()` + + 则返回结果为: + ```json + [ + {"row":[0,0],"column":[0,2]}, + {"row":[1,1],"column":[0,0]}, + {"row":[3,3],"column":[0,0]} + ] + ``` + 其中,{"row":[0,0],"column":[0,2]} 表示的是一整块连续的区域。 + + - 在表格中选择上面的区域,然后执行 + + `luckysheet.getRangeWithFlatten()` + + 则返回结果为: + ```json + [ + {"r":0,"c":0}, + {"r":0,"c":1}, + {"r":0,"c":2}, + {"r":1,"c":0}, + {"r":3,"c":0} + ] + ``` + +------------ + +### getRangeValuesWithFlatte() + +- **说明**: + + 返回表示指定区域内所有单元格内容的对象数组 + +- **示例**: + + - 在表格中选择指定的区域,然后执行 + + `luckysheet.getRange()` + + 则返回结果为: + ```json + [ + {"row":[0,0],"column":[0,2]}, + {"row":[1,1],"column":[0,0]}, + {"row":[3,3],"column":[0,0]} + ] + ``` + 其中,{"row":[0,0],"column":[0,2]} 表示的是一整块连续的区域。 + + - 在表格中选择上面的区域,然后执行 + + `luckysheet.getRangeValuesWithFlatte()` + + 则返回结果为: + ```json + [ + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 1, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "1" + }, + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 2, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "2" + }, + { + "bg": null, + "bl": 0, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1, + "v": 3, + "ct": { + "fa": "General", + "t": "n" + }, + "m": "3" + }, + { + "v": "Background", + "ct": { + "fa": "General", + "t": "g" + }, + "m": "Background", + "bg": null, + "bl": 1, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1 + }, + { + "v": "Border", + "ct": { + "fa": "General", + "t": "g" + }, + "m": "Border", + "bg": null, + "bl": 1, + "it": 0, + "ff": 0, + "fs": 11, + "fc": "rgb(51, 51, 51)", + "ht": 1, + "vt": 1 + } + ] + ``` +------------ + + +### getRangeAxis() + +- **说明**: + + 返回对应当前选区的坐标字符串数组,可能存在多个选区。每个选区可能是单个单元格(如 A1)或多个单元格组成的矩形区域(如 D9:E12) + +- **示例**: + + - 当前选区为"E10:E14"、"A7:B13"、"C4"、 "A3"和"C6:D9",执行 + + `luckysheet.getRangeAxis()` + + 则返回结果为: + ```json + ["E10:E14", "A7:B13", "C4", "A3", "C6:D9"] + ``` + +------------ + ### getRangeValue([setting]) - **参数**: @@ -863,8 +1051,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 则返回结果为: ```json [ - { "A": "value1", "B": "value3" }, - { "A": "value2", "B": "value4" } + { "value1": "value2", "value3": "value4" } ] ``` @@ -875,7 +1062,8 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 则返回结果为: ```json [ - { "value1": "value2", "value3": "value4" } + { "A": "value1", "B": "value3" }, + { "A": "value2", "B": "value4" } ] ``` @@ -1182,7 +1370,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 } ] ] - luckysheet.setRangeValue(data) + luckysheet.setRangeValue(data,{range:"A1:B2"}) ``` ------------ @@ -1712,10 +1900,10 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 + `"flipUpDown"`: 上下翻转 + `"flipLeftRight"`: 左右翻转 + `"flipClockwise"`: 顺时针旋转 - + `"flipCounterClockwise"`: 逆时针旋转 - + `"Transpose"`: 转置 - + `"DeleteZeroByRow"`: 按行删除两端0值 - + `"DeleteZeroByColumn"`: 按列删除两端0值 + + `"flipCounterClockwise"`: 逆时针旋转api + + `"transpose"`: 转置 + + `"deleteZeroByRow"`: 按行删除两端0值 + + `"deleteZeroByColumn"`: 按列删除两端0值 + `"removeDuplicateByRow"`: 按行删除重复值 + `"removeDuplicateByColumn"`: 按列删除重复值 + `"newMatrix"`: 生产新矩阵 @@ -1791,7 +1979,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 返回所有工作表配置,格式同工作表配置,得到的结果可用于表格初始化时作为options.data使用。 - 所以此API适用于,手动操作配置完一个表格后,将所有工作表信息取出来自行保存,再用于其他地方的表格创建。如果想得到包括工作簿配置在内的所有工作簿数据,可以使用 [toJson](#toJson()) + 所以此API适用于,手动操作配置完一个表格后,将所有工作表信息取出来自行保存,再用于其他地方的表格创建。如果想得到包括工作簿配置在内的所有工作簿数据,推荐使用 [toJson](#toJson()),并且可以直接用于初始化Luckysheet。 - **示例**: @@ -1874,7 +2062,20 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 快捷设置指定工作表config配置 ------------ +### updataSheet([setting]) + +- **参数**: + + - {PlainObject} [setting]: 可选参数 + + {Array} [data]: 需要更新的工作表配置,参考create这个API的option.data + + {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 根据所传的工作表配置,更新相应的工作表 + +------------ ### setSheetAdd([setting]) - **参数**: @@ -2165,13 +2366,11 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ## 工作簿操作 -### create(options [,setting]) +### create(options) - **参数**: - {Object} [options]:表格的所有配置信息 - - {PlainObject} [setting]: 可选参数 - + {Function} [success]: 表格创建成功后的回调函数 - **说明**: @@ -2262,6 +2461,19 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ +### getWorkbookName([,setting]) + +- **参数**: + + - {PlainObject} [setting]: 可选参数 + + {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 获取工作簿名称 + +------------ + ### undo([setting]) - **参数**: @@ -2288,19 +2500,65 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ -### refreshFormula([setting]) +### refreshFormula([success]) -[todo] +- **参数**: + + - {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 强制刷新公式。当你直接修改了多个单元格的值,且没有触发刷新,且这些单元格跟公式相关联,则可以使用这个api最后强制触发一次公式刷新。 + +------------ + +### pagerInit([setting]) - **参数**: - - {PlainObject} [setting]: 可选参数 - + {Object | String} [range]: 选区范围,支持选区的格式为`"A1:B2"`、`"sheetName!A1:B2"`或者`{row:[0,1],column:[0,1]}`,只能为单个选区;默认为整个当前工作表 - + {Function} [success]: 操作结束的回调函数 + - {PlainObject} [setting]: 参数配置 + + {Number} [pageIndex]: 当前的页码(必填)。 + + {Number} [pageSize]: 每页显示多少条数据(必填)。 + + {Number} [total]: 总条数(必填)。 + + {Boolean} [showTotal]: 是否显示总数,默认关闭:false。 + + {Boolean} [showSkip]: 是否显示跳页,默认关闭:false。 + + {Boolean} [showPN]: 是否显示上下翻页,默认开启:true。 + + {Array} [selectOption]: 选择分页的条数。 + + {String} [prevPage]: 上翻页文字描述,默认"上一页"。 + + {String} [nextPage]: 下翻页文字描述,默认"下一页"。 + + {String} [totalTxt]: 数据总条数文字描述,默认"总共:{total}"。 + + + +- **说明**: + + 初始化分页器。ps:create阶段,可以直接配置options.pager参数,渲染阶段会将options.pager作为参数来初始化分页器,可通过钩子函数onTogglePager来监听页码的切换 + +### refreshMenuButtonFocus([data],[r],[c],[success]) + +- **参数**: + + - {Array} [data]: 操作数据 + - {Number} [r]: 指定的行 + - {Number} [c]: 指定的列 + - {Function} [success]: 操作结束的回调函数 - **说明**: - 强制刷新公式。当你直接修改了多个单元格的值,且没有触发刷新,且这些单元格跟公式相关联,则可以使用这个api最后强制触发一次公式刷新,一般是建议指定受影响的单元格范围便于防止性能问题,如果无法确定,则留空保持整个工作表遍历刷新。 + 刷新指定单元格的顶部状态栏状态。 + +------------ + +### checkTheStatusOfTheSelectedCells(type,status) + +- **参数**: + + - {String} type: 类型 + - {String} status: 目标状态值 + +- **说明**: + + 检查选区内所有cell指定类型的状态是否满足条件(主要是粗体、斜体、删除线和下划线等等)。 ------------ @@ -2420,6 +2678,48 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ +## 图片 + +### insertImage(src, [setting]) + +- **参数**: + + - {String} [src]: 图片src + - {PlainObject} [setting]: 可选参数 + + {Number} [order]: 工作表下标;默认值为当前工作表下标 + + {Number} [rowIndex]: 要插入图片的单元格行下标;默认为当前选区聚焦单元格行下标 || 0 + + {Number} [colIndex]: 要插入图片的单元格列下标;默认为当前选区聚焦单元格列下标 || 0 + + {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 在指定的工作表中指定单元格位置插入图片 + +### deleteImage([setting]) + +- **参数**: + + - {PlainObject} [setting]: 可选参数 + + {Number} [order]: 工作表下标;默认值为当前工作表下标 + + {String | Array} [idList]: 要删除图片的id集合,也可为字符串`"all"`,all为所有的字符串;默认为`"all"` + + {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 删除指定工作表中的图片 + +### getImageOption([setting]) + +- **参数**: + + - {PlainObject} [setting]: 可选参数 + + {Number} [order]: 工作表下标;默认值为当前工作表下标 + + {Function} [success]: 操作结束的回调函数 + +- **说明**: + + 获取指定工作表的图片配置 + ## 工作表保护 @@ -2440,7 +2740,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ -## 公共方法 +## 工具方法 ### transToCellData(data [,setting])
@@ -2474,7 +2774,6 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ### toJson() -[todo] - **说明**: @@ -2482,6 +2781,59 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 ------------ +### changLang([lang]) + +- **参数**: + + + {String} [lang]: 语言类型;暂支持`"zh"`、`"en"`、`"es"`;默认为`"zh"`; + +- **说明**: + + 传入目标语言,切换到对应的语言界面 + +### closeWebsocket() + +- **说明**: + + 关闭websocket连接 + +### getRangeByTxt([txt]) + +- **说明**: + + 将字符串格式的工作表范围转换为数组形式 + +- **参数**: + + + {String} [txt]: 选区范围,支持选区的格式为`"A1:B2"`或者指定工作表名称的写法`"sheetName!A1:B2"`,只支持单个选区;默认为当前最后一个选区 + +- **示例**: + + - 当前选区为`A1:B2`,`luckysheet.getRangeByTxt()`返回:`{column: (2) [0, 1],row: (2) [0, 1]}` + - `luckysheet.getRangeByTxt("A1:B2")`返回:`{column: (2) [0, 1],row: (2) [0, 1]}` + - `luckysheet.getRangeByTxt("Cell!A1:B2")`返回:`{column: (2) [0, 1],row: (2) [0, 1]}` + +------------ + +### getTxtByRange([range]) + +- **说明**: + + 将数组格式的工作表范围转换为字符串格式的形式 + +- **参数**: + + + {Array | Object} [range]: 选区范围,支持选区的格式为`{row:[0,1],column:[0,1]}`,允许多个选区组成的数组;默认为当前选区 + +- **示例**: + + - 当前选区为`A1:B3`,`luckysheet.getTxtByRange()`返回:当前选区`"A1:B3"` + - `luckysheet.getTxtByRange({column:[0,1],row:[0,2]})`返回:`"A1:B3"` + - `luckysheet.getTxtByRange([{column:[0,1],row:[0,2]}])`返回:`"A1:B3"` + - `luckysheet.getTxtByRange([{column:[0,1],row:[0,2]},{column:[1,1],row:[1,2]}])`返回:`"A1:B3,B2:B3"` + +------------ + ## 旧版API @@ -2572,7 +2924,7 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 按照scrollWidth, scrollHeight刷新canvas展示数据。 - > 推荐使用新API: [scroll](#scroll([setting])) + > 推荐使用新API: [scroll](/zh/guide/api.html#scroll-setting) ------------ ### setcellvalue(r, c, d, v) @@ -2667,4 +3019,4 @@ Luckysheet针对常用的数据操作需求,开放了主要功能的API,开 二维数组数据转化成 `{r, c, v}` 格式 一维数组 - > 推荐使用新API:transToCellData \ No newline at end of file + > 推荐使用新API:transToCellData diff --git a/docs/zh/guide/cell.md b/docs/zh/guide/cell.md index 287d7622fd9028f3beeda8cd1d0537c1fecf0584..b2a20c0e69dbfb8ae61d93b5b5e54e1c4788335e 100644 --- a/docs/zh/guide/cell.md +++ b/docs/zh/guide/cell.md @@ -73,6 +73,13 @@ 0 常规 、 1 删除线 Style.Font object's Underline property + + un + underline + 下划线 + 0 无 、 1 有 + + vt verticaltype @@ -182,7 +189,7 @@ "top": 10, //批注框上边距 "width": 91, //批注框宽度 "height": 48, //批注框高度 - "value": "I am a comment", //批准内容 + "value": "I am a comment", //批注内容 "isshow": true //批注框为显示状态 }, "f": "=SUM(233)" //单元格是一个求和公式 @@ -330,7 +337,7 @@ Luckysheet在存储数字类型的内容时,支持多种格式转换,所以 ] ``` -> borderInfo 详细参考:[表格数据config](/zh/guide/data.html#config) +> borderInfo 详细参考:[config.borderInfo](/zh/guide/sheet.html#config-borderinfo) ## 简化的单元格数据 @@ -604,4 +611,4 @@ Luckysheet在存储数字类型的内容时,支持多种格式转换,所以 | 货币:智利比索 | "$" 0.00 | n | $ 123.00 || | 货币:中非金融合作法郎 | "FCFA" 0.00 | n | FCFA 123.00 || -以上配置参考了[Aspose.Cells](https://docs.aspose.com/display/cellsnet/List+of+Supported+Number+Formats#ListofSupportedNumberFormats-Aspose.Cells) \ No newline at end of file +以上配置参考了[Aspose.Cells](https://docs.aspose.com/display/cellsnet/List+of+Supported+Number+Formats#ListofSupportedNumberFormats-Aspose.Cells) diff --git a/docs/zh/guide/config.md b/docs/zh/guide/config.md index e44f242f1cb406a6619be415d7d9f2b87880c444..97ad3530267df7503837ce040378746d946fe2d4 100644 --- a/docs/zh/guide/config.md +++ b/docs/zh/guide/config.md @@ -28,7 +28,6 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 自定义工具栏([showtoolbarConfig](#showtoolbarConfig)) - 自定义底部sheet页([showsheetbarConfig](#showsheetbarConfig)) - 自定义计数栏([showstatisticBarConfig](#showstatisticBarConfig)) -- 自定义添加行和回到顶部([sheetBottomConfig](#sheetBottomConfig)) - 自定义单元格右键菜单([cellRightClickConfig](#cellRightClickConfig)) - 自定义底部sheet页右击菜单([sheetRightClickConfig](#sheetRightClickConfig)) @@ -60,24 +59,27 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 自定义底部sheet页 [showsheetbarConfig](#showsheetbarConfig) - 底部计数栏 [showstatisticBar](#showstatisticBar) - 自定义计数栏 [showstatisticBarConfig](#showstatisticBarConfig) -- 自定义添加行和回到顶部 [sheetBottomConfig](#sheetBottomConfig) -- 允许编辑 [allowEdit](#allowEdit) -- 允许增加行 [enableAddRow](#enableAddRow) -- 允许增加列 [enableAddCol](#enableAddCol) +- 允许添加行 [enableAddRow](#enableAddRow) +- 默认添加行的数目 [addRowCount](#addRowCount) +- 允许回到顶部 [enableAddBackTop](#enableAddBackTop) - 用户信息 [userInfo](#userInfo) - 用户信息菜单 [userMenuItem](#userMenuItem) - 返回按钮链接 [myFolderUrl](#myFolderUrl) - 比例 [devicePixelRatio](#devicePixelRatio) - 功能按钮 [functionButton](#functionButton) - 自动缩进界面 [showConfigWindowResize](#showConfigWindowResize) -- 加载下一页 [enablePage](#enablePage) - 刷新公式 [forceCalculation](#forceCalculation) - 自定义单元格右键菜单 [cellRightClickConfig](#cellRightClickConfig) - 自定义sheet页右击菜单 [sheetRightClickConfig](#sheetRightClickConfig) -- 是否显示行号区域 [showRowBar](#showRowBar) -- 是否显示列号区域 [showColumnBar](#showColumnBar) +- 行标题区域的宽度 [rowHeaderWidth](#rowHeaderWidth) +- 列标题区域的高度 [columnHeaderHeight](#columnHeaderHeight) - 是否显示公式栏 [sheetFormulaBar](#sheetFormulaBar) - 初始化默认字体大小 [defaultFontSize](#defaultFontSize) +- 是否限制工作表名长度 [limitSheetNameLength](#limitSheetNameLength) +- 默认允许工作表名的最大长度 [defaultSheetNameMaxLength](#defaultSheetNameMaxLength) +- 分页器 [pager](#pager) +- 自定义图片上传 [uploadImage](#uploadImage) +- 自定义图片地址处理 [imageUrlHandle](#imageUrlHandle) ### container - 类型:String @@ -94,7 +96,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ### lang - 类型:String - 默认值:"en" -- 作用:国际化设置,允许设置表格的语言,支持中文("zh")和英文("en") +- 作用:国际化设置,允许设置表格的语言,支持简体中文("zh")、英文("en")、繁体中文("zh_tw")和西班牙文("es") ------------ ### gridKey @@ -123,7 +125,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 //status为1的sheet页,重点是需要提供初始化的数据celldata { "name": "Cell", - "index": "sheet_001", + "index": "sheet_01", "order": 0, "status": 1, "celldata": [{"r":0,"c":0,"v":{"v":1,"m":"1","ct":{"fa":"General","t":"n"}}}] @@ -131,13 +133,13 @@ Luckysheet开放了更细致的自定义配置选项,分别有 //其他status为0的sheet页,无需提供celldata,只需要配置项即可 { "name": "Data", - "index": "sheet_002", + "index": "sheet_02", "order": 1, "status": 0 }, { "name": "Picture", - "index": "sheet_003", + "index": "sheet_03", "order": 2, "status": 0 } @@ -153,7 +155,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ### loadSheetUrl - 类型:String - 默认值:"" -- 作用:配置`loadSheetUrl`接口地址,用于异步加载其它单元格数据。参数为`gridKey`(表格主键) 和 `index`(sheet主键合集,格式为`["sheet_01","sheet_02","sheet_0"]`)。 +- 作用:配置`loadSheetUrl`接口地址,用于异步加载其它单元格数据。参数为`gridKey`(表格主键) 和 `index`(sheet主键合集,格式为`["sheet_01","sheet_02","sheet_03"]`)。 源码的请求写法是: ```js @@ -181,7 +183,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 "v": { "v": 1, "m": "1", "ct": { "fa": "General", "t": "n" } } } ], - "sheet_0": [ + "sheet_03": [ { "r": 0, "c": 0, @@ -207,10 +209,9 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:"" - 作用:操作表格后,实时保存数据的websocket地址,此接口也是共享编辑的接口地址。 - 有个注意点,要想开启共享编辑,必须满足以下四个条件: + 有个注意点,要想开启共享编辑,必须满足以下3个条件: + `allowUpdate`为`true` + 配置了`loadUrl` - + 配置了`loadSheetUrl` + 配置了`updateUrl` 注意,发送给后端的数据默认是经过pako压缩过后的。后台拿到数据需要先解压。 @@ -277,7 +278,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 类型:Object - 默认值:{} - 作用:自定义配置工具栏,可以与showtoolbar配合使用,`showtoolbarConfig`拥有更高的优先级。 -- 格式: +- 格式1: ```json { undoRedo: false, //撤销重做,注意撤消重做是两个按钮,由这一个配置决定显示还是隐藏 @@ -291,7 +292,8 @@ Luckysheet开放了更细致的自定义配置选项,分别有 fontSize: false, // '字号大小' bold: false, // '粗体 (Ctrl+B)' italic: false, // '斜体 (Ctrl+I)' - strikethrough: false, // '删除线 (Alt+Shift+5)' + strikethrough: false, // '删除线 (Alt+Shift+5)' + underline: false, // '下划线 (Alt+Shift+6)' textColor: false, // '文本颜色' fillColor: false, // '单元格颜色' border: false, // '边框' @@ -317,7 +319,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 print:false, // '打印' } ``` -- 示例: +- 示例1: - 仅显示撤消重做和字体按钮: ```js @@ -342,7 +344,33 @@ Luckysheet开放了更细致的自定义配置选项,分别有 } } ``` - +- 格式2: + 对象格式可以很方便控制显示隐藏,使用数组形式可轻松控制按钮顺序和位置, 以下为工具栏按钮和分隔符的默认配置。 + ```json + [ + "undo", "redo", "paintFormat", "|", + "currencyFormat", "percentageFormat", "numberDecrease", "numberIncrease", "moreFormats", "|", + "font", "|", + "fontSize", "|", + "bold", "italic", "strikethrough", "underline", "textColor", "|", + "fillColor", "border", "mergeCell", "|", + "horizontalAlignMode", "verticalAlignMode", "textWrapMode", "textRotateMode", "|", + "image", "link", "chart", "postil", "pivotTable", "|", + "function", "frozenMode", "sortAndFilter", "conditionalFormat", "dataVerification", "splitColumn", "screenshot", "findAndReplace", "protection", "print" + ] + ``` +- 示例2: + - 自定义按钮和位置, 保护放到最前面, 只要字体样式相关按钮。 + ```json + { + "showtoolbarConfig": [ + "protection", "|", + "font", "|", + "fontSize", "|", + "bold", "italic", "strikethrough", "underline", "textColor" + ] + } + ``` ------------ ### showinfobar - 类型:Boolean @@ -438,44 +466,74 @@ Luckysheet开放了更细致的自定义配置选项,分别有 } ``` ------------- -### sheetBottomConfig - -[todo] - -- 类型:Object -- 默认值:{} -- 作用:sheet页下方的添加行按钮和回到顶部按钮配置 -- 格式: - ```json - { - addRow: false, // 添加行按钮 - backTop: false // 回到顶部 - } - ------------- -### allowEdit -- 类型:Boolean -- 默认值:true -- 作用:是否允许前台编辑 - ------------ ### enableAddRow - 类型:Boolean - 默认值:true -- 作用:允许增加行 +- 作用:允许添加行 + +### addRowCount +- Number +- 默认值:100 +- 作用:配置新增行处默认新增的行数目 ------------ -### enableAddCol +### enableAddBackTop - 类型:Boolean - 默认值:true -- 作用:允许增加列 +- 作用:允许回到顶部 ------------ ### userInfo -- 类型:String -- 默认值:`' rabbit'` -- 作用:右上角的用户信息展示样式 +- 类型:String | Boolean | Object +- 默认值:false +- 作用:右上角的用户信息展示样式,支持以下三种形式 + 1. HTML模板字符串,如: + + ```js + options:{ + // 其他配置 + userInfo:' Lucky', + } + ``` + + 或者一个普通字符串,如: + + ```js + options:{ + // 其他配置 + userInfo:'Lucky', + } + ``` + + 2. Boolean类型,如: + + `false`:不展示 + ```js + options:{ + // 其他配置 + userInfo:false, // 不展示用户信息 + } + + ``` + `ture`:展示默认的字符串 + ```js + options:{ + // 其他配置 + userInfo:true, // 展示HTML:' Lucky' + } + + ``` + 3. 对象格式,设置 `userImage`:用户头像地址 和 `userName`:用户名,如: + ```js + options:{ + // 其他配置 + userImage:'https://cdn.jsdelivr.net/npm/luckyresources@1.0.3/assets/img/logo/logo.png', // 头像url + userName:'Lucky', // 用户名 + } + ``` + + 4. 注意,设置为`undefined`或者不设置,同设置`false` ------------ ### userMenuItem @@ -507,12 +565,6 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:true - 作用:图表或数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进 ------------- -### enablePage -- 类型:Boolean -- 默认值:false -- 作用:允许加载下一页 - ------------ ### forceCalculation - 类型:Boolean @@ -528,8 +580,6 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### cellRightClickConfig -[todo] - - 类型:Object - 默认值:{} - 作用:自定义配置单元格右击菜单 @@ -539,22 +589,56 @@ Luckysheet开放了更细致的自定义配置选项,分别有 copy: false, // 复制 copyAs: false, // 复制为 paste: false, // 粘贴 - insert: false, // 插入 - delete: false, // 删除 - hide: false, // 隐藏 + insertRow: false, // 插入行 + insertColumn: false, // 插入列 + deleteRow: false, // 删除选中行 + deleteColumn: false, // 删除选中列 deleteCell: false, // 删除单元格 + hideRow: false, // 隐藏选中行和显示选中行 + hideColumn: false, // 隐藏选中列和显示选中列 + rowHeight: false, // 行高 + columnWidth: false, // 列宽 clear: false, // 清除内容 matrix: false, // 矩阵操作选区 sort: false, // 排序选区 filter: false, // 筛选选区 - chart: false // 图表生成 + chart: false, // 图表生成 + image: false, // 插入图片 + link: false, // 插入链接 + data: false, // 数据验证 + cellFormat: false // 设置单元格格式 } + ``` + 除了单元格,这里的配置还包括行标题右击菜单、列标题右击菜单和列标题下拉箭头的菜单,具体配置关系如下表格: + + |右击菜单配置|单元格|行标题|列标题|列箭头| + | ------------ | ------------ | ------------ | ------------ | ------------ | + |copy|复制|复制|复制|复制| + |copyAs|复制为|复制为|复制为|复制为| + |paste|粘贴|粘贴|粘贴|粘贴| + |insertRow|插入行|向上增加N行,向下增加N行|-|-| + |insertColumn|插入列|-|向左增加N列,向右增加N列|向左增加N列,向右增加N列| + |deleteRow|删除选中行|删除选中行|-|-| + |deleteColumn|删除选中列|-|删除选中列|删除选中列| + |deleteCell|删除单元格|-|-|-| + |hideRow|-|隐藏选中行和显示选中行|-|-| + |hideColumn|-|-|隐藏选中列和显示选中列|隐藏选中列和显示选中列| + |rowHeight|-|行高|-|-| + |columnWidth|-|-|列宽|列宽| + |clear|清除内容|清除内容|清除内容|-| + |matrix|矩阵操作选区|矩阵操作选区|矩阵操作选区|-| + |sort|排序选区|排序选区|排序选区|A-Z排序和Z-A排序| + |filter|筛选选区|筛选选区|筛选选区|-| + |chart|图表生成|图表生成|图表生成|-| + |image|插入图片|插入图片|插入图片|-| + |link|插入链接|插入链接|插入链接|-| + |data|数据验证|数据验证|数据验证|-| + |cellFormat|设置单元格格式|设置单元格格式|设置单元格格式|-| + ------------ ### sheetRightClickConfig -[todo] - - 类型:Object - 默认值:{} - 作用:自定义配置sheet页右击菜单 @@ -565,29 +649,27 @@ Luckysheet开放了更细致的自定义配置选项,分别有 copy: false, // 复制 rename: false, //重命名 color: false, //更改颜色 - hide: false, //隐藏 - show: false, //取消隐藏 - left: false, //向左移 - right: false //向右移 + hide: false, //隐藏,取消隐藏 + move: false, //向左移,向右移 } ------------ -### showRowBar -[todo] -- 类型:Boolean -- 默认值:true -- 作用:是否显示行号区域 +### rowHeaderWidth + +- 类型:Number +- 默认值:46 +- 作用:行标题区域的宽度,如果设置为0,则表示隐藏行标题 ------------ -### showColumnBar -[todo] -- 类型:Boolean -- 默认值:true -- 作用:是否显示列号区域 +### columnHeaderHeight + +- 类型:Number +- 默认值:20 +- 作用:列标题区域的高度,如果设置为0,则表示隐藏列标题 ------------ ### sheetFormulaBar -[todo] + - 类型:Boolean - 默认值:true - 作用:是否显示公式栏 @@ -600,14 +682,164 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ +### limitSheetNameLength +- 类型:Boolean +- 默认值:true +- 作用:工作表重命名等场景下是否限制工作表名称的长度 + +------------ + +### defaultSheetNameMaxLength +- 类型:Number +- 默认值:31 +- 作用:默认允许的工作表名最大长度 + +------------ + +### pager +- 类型:Object +- 默认值:null +- 作用:分页器按钮设置,初版方案是直接使用的jquery插件 [sPage](https://github.com/jvbei/sPage) + 点击分页按钮会触发钩子函数 `onTogglePager`,返回当前页码,同`sPage`的`backFun`方法,此分页器设置只负责UI部分,具体切换分页后的数据请求和数据渲染,请在`onTogglePager`钩子行数里自定义处理。 + ```js + pager: { + pageIndex: 1, //当前页码,必填 + total: 100, //数据总条数,必填 + selectOption: [10, 20, 30], // 选择每页的行数, + pageSize: 10, //每页显示多少条数据,默认10条 + showTotal: false, // 是否显示总数,默认关闭:false + showSkip: false, //是否显示跳页,默认关闭:false + showPN: false, //是否显示上下翻页,默认开启:true + prevPage: '', //上翻页文字描述,默认"上一页" + nextPage: '', //下翻页文字描述,默认"下一页" + totalTxt: '', // 数据总条数文字描述,默认"总共:{total}" + } + ``` + +### uploadImage + +用于自定义图片的上传,默认情况下,插入的图片是以base64的形式放入sheet数据中,如果需要单独上传图片,仅在sheet中引用图片地址可使用此配置。 + +- 类型: `function (file) => Promise(imgUrl)`,接受file对象,返回Promise,值为上传完成的图片url +- 默认值: `undefined` + +:::details 查看示例配置 + +```js +{ + uploadImage: function (file) { + return new Promise(function (resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open('POST', 'http://192.168.210.159/miniuiServer/imageUploader.php'); + + // 额外的请求头 + var headers = {}; + if (headers) { + Object.keys(headers).forEach(function (k) { + xhr.setRequestHeader(k, headers[k]); + }); + } + var data = new FormData(); + // 要上传的图片文件 + data.append('file', file, file.name || ''); + + xhr.send(data); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + var res = JSON.parse(xhr.responseText); + var url = res.downloadUrl; + if (url) { + resolve(url); // 给上传的后的地址 + } else { + reject('image upload error'); + } + } else { + reject('image upload error'); + } + } + }; + }); + } +} + +``` + +::: + +### imageUrlHandle + +图片上传的路径处理函数,和 [uploadImage](#uploadImage) 相关,一般只有使用自定义图片上传才需要此配置。 + +- 类型: `function (string) => string`,接受原始路径,返回新路径 +- 默认值: `undefined` +- 作用,处理图片显示时的路径。 + 如上传返回地址为接口地址,如: `rest/attach/[fileguid]`, 则需要处理为 `http://localhost:8080/xxx/rest/attach/[fileguid]` 才能显示,但将前面域名信息写入数据,后续使用可能会有问题,因此可使用此方法处理路径,全路径仅在展示使用,数据内仅存储 `rest/attach/[fileguid]` + +```js +{ + // 处理上传图片的地址 + imageUrlHandle: function (url) { + // 已经是 // http data 开头则不处理 + if (/^(?:\/\/|(?:http|https|data):)/i.test(url)) { + return url; + } + return location.origin + url; + } +} +``` + +------------ + ## 钩子函数 钩子函数应用于二次开发时,会在各个常用鼠标或者键盘操作时植入钩子,调用开发者传入的函数,起到扩展Luckysheet功能的作用。 钩子函数统一配置在`options.hook`下,可以分别针对单元格、sheet页、表格创建配置hook。 +> 使用案例可参考源码 [src/index.html](https://github.com/mengshukeji/Luckysheet/blob/master/src/index.html) + ## 单元格 +### cellEditBefore + +- 类型:Function +- 默认值:null +- 作用:进入单元格编辑模式之前触发。在选中了某个单元格且在非编辑状态下,通常有以下三种常规方法触发进入编辑模式 + + - 双击单元格 + - 敲Enter键 + - 使用API:enterEditMode + +- 参数: + - {Array} [range]: 当前选区范围 + +------------ +### cellUpdateBefore + +- 类型:Function +- 默认值:null +- 作用:更新这个单元格值之前触发,`return false` 则不执行后续的更新。在编辑状态下修改了单元格之后,退出编辑模式并进行数据更新之前触发这个钩子。 +- 参数: + - {Number} [r]: 单元格所在行数 + - {Number} [c]: 单元格所在列数 + - {Object | String | Number} [value]: 要修改的单元格内容 + - {Boolean} [isRefresh]: 是否刷新整个表格 + +------------ +### cellUpdated + +- 类型:Function +- 默认值:null +- 作用:更新这个单元格后触发 +- 参数: + - {Number} [r]: 单元格所在行数 + - {Number} [c]: 单元格所在列数 + - {Object} [oldValue]: 修改前的单元格对象 + - {Object} [newValue]: 修改后的单元格对象 + - {Boolean} [isRefresh]: 是否刷新整个表格 + +------------ ### cellRenderBefore - 类型:Function @@ -615,13 +847,13 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:单元格渲染前触发,`return false` 则不渲染该单元格 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [ctx]: 当前画布的context @@ -633,38 +865,94 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:单元格渲染结束后触发,`return false` 则不渲染该单元格 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [ctx]: 当前画布的context ------------- -### cellEditBefore -(TODO) -- 类型:Function -- 默认值:null -- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最先触发这个方法 -- 参数: - - {Number} [r]: 单元格所在行数 - - {Number} [c]: 单元格所在列数 - - {Object} [v]: 单元格对象 +- 示例: + + 一个在D1单元格的左上角和右下角分别绘制两张图的案例 + :::::: details + ```js + luckysheet.create({ + hook: { + cellRenderAfter: function (cell, position, sheetFile, ctx) { + var r = position.r; + var c = position.c; + if (r === 0 && c === 3) { // 指定处理D1单元格 + if (!window.storeUserImage) { + window.storeUserImage = {} + } + + if (!window.storeUserImage[r + '_' + c]) { + window.storeUserImage[r + '_' + c] = {} + } + + var img = null; + var imgRight = null; + + if (window.storeUserImage[r + '_' + c].image && window.storeUserImage[r + '_' + c].imgRight) { + + // 加载过直接取 + img = window.storeUserImage[r + '_' + c].image; + imgRight = window.storeUserImage[r + '_' + c].imgRight; + + } else { + + img = new Image(); + imgRight = new Image(); + + img.src = 'https://www.dogedoge.com/favicon/developer.mozilla.org.ico'; + imgRight.src = 'https://www.dogedoge.com/static/icons/twemoji/svg/1f637.svg'; + + // 图片缓存到内存,下次直接取,不用再重新加载 + window.storeUserImage[r + '_' + c].image = img; + window.storeUserImage[r + '_' + c].imgRight = imgRight; + + } + + + if (img.complete) { // 已经加载完成的直接渲染 + ctx.drawImage(img, position.start_c, position.start_r, 10, 10); + } else { + img.onload = function () { + ctx.drawImage(img, position.start_c, position.start_r, 10, 10); + } + + } + + if (imgRight.complete) { + ctx.drawImage(imgRight, position.end_c - 10, position.end_r - 10, 10, 10); + } else { + + imgRight.onload = function () { + ctx.drawImage(imgRight, position.end_c - 10, position.end_r - 10, 10, 10); + } + } + + } + } + } + }) + ``` + ::: ------------ -### cellEditAfter -(TODO) +### cellAllRenderBefore + - 类型:Function - 默认值:null -- 作用:双击单元格后触发,即在双击单元格编辑内容的时候,最后触发这个方法 +- 作用:所有单元格渲染之前执行的方法。在内部,这个方法加在了`luckysheetDrawMain`渲染表格之前。 - 参数: - - {Number} [r]: 单元格所在行数 - - {Number} [c]: 单元格所在列数 - - {Object} [oldV]: 修改前单元格对象 - - {Object} [newV]: 修改后单元格对象 + - {Object} [data]: 当前工作表二维数组数据 + - {Object} [sheet]:当前sheet对象 + - {Object} [ctx]: 当前画布的context ------------ ### rowTitleCellRenderBefore @@ -674,7 +962,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:行标题单元格渲染前触发,`return false` 则不渲染行标题 - 参数: - {String} [rowNum]:行号 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [top]:单元格左上角的垂直坐标 + {Number} [width]:单元格宽度 @@ -689,7 +977,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:行标题单元格渲染后触发,`return false` 则不渲染行标题 - 参数: - {String} [rowNum]:行号 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [top]:单元格左上角的垂直坐标 + {Number} [width]:单元格宽度 @@ -704,7 +992,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:列标题单元格渲染前触发,`return false` 则不渲染列标题 - 参数: - {Object} [columnAbc]:列标题字符 - - {Object} [postion]: + - {Object} [position]: - {Number} [c]:单元格所在列号 - {Number} [left]:单元格左上角的水平坐标 - {Number} [width]:单元格宽度 @@ -719,7 +1007,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:列标题单元格渲染后触发,`return false` 则不渲染列标题 - 参数: - {Object} [columnAbc]:列标题字符 - - {Object} [postion]: + - {Object} [position]: - {Number} [c]:单元格所在列号 - {Number} [left]:单元格左上角的水平坐标 - {Number} [width]:单元格宽度 @@ -737,13 +1025,13 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:单元格点击前的事件,`return false`则终止之后的点击操作 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [ctx]: 当前画布的context @@ -755,13 +1043,13 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:单元格点击后的事件,`return false`则终止之后的点击操作 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [ctx]: 当前画布的context @@ -773,18 +1061,18 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:鼠标移动事件,可通过cell判断鼠标停留在哪个单元格 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [moveState]:鼠标移动状态,可判断现在鼠标操作的对象,false和true + {Boolean} [functionResizeStatus]:工具栏拖动 - + {Boolean} [horizontalmoveState]:水平冻结分割烂拖动 - + {Boolean} [verticalmoveState]:垂直冻结分割烂拖动 + + {Boolean} [horizontalmoveState]:水平冻结分割栏拖动 + + {Boolean} [verticalmoveState]:垂直冻结分割栏拖动 + {Boolean} [pivotTableMoveState]:数据透视表字段拖动 + {Boolean} [sheetMoveStatus]:sheet改变你位置拖动 + {Boolean} [scrollStatus]:鼠标触发了滚动条移动 @@ -809,18 +1097,18 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 作用:鼠标按钮释放事件,可通过cell判断鼠标停留在哪个单元格 - 参数: - {Object} [cell]:单元格对象 - - {Object} [postion]: + - {Object} [position]: + {Number} [r]:单元格所在行号 + {Number} [c]:单元格所在列号 - + {Number} [start_r]:单元格左上角的水平坐标 - + {Number} [start_c]:单元格左上角的垂直坐标 - + {Number} [end_r]:单元格右下角的水平坐标 - + {Number} [end_c]:单元格右下角的垂直坐标 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 - {Object} [sheet]:当前sheet对象 - {Object} [moveState]:鼠标移动状态,可判断现在鼠标操作的对象,false和true + {Boolean} [functionResizeStatus]:工具栏拖动 - + {Boolean} [horizontalmoveState]:水平冻结分割烂拖动 - + {Boolean} [verticalmoveState]:垂直冻结分割烂拖动 + + {Boolean} [horizontalmoveState]:水平冻结分割栏拖动 + + {Boolean} [verticalmoveState]:垂直冻结分割栏拖动 + {Boolean} [pivotTableMoveState]:数据透视表字段拖动 + {Boolean} [sheetMoveStatus]:sheet改变你位置拖动 + {Boolean} [scrollStatus]:鼠标触发了滚动条移动 @@ -835,28 +1123,56 @@ Luckysheet开放了更细致的自定义配置选项,分别有 + {Boolean} [chartResize]:图表改变大小 + {Boolean} [rangeResize]:公式参数高亮选区的大小拖拽 + {Boolean} [rangeMove]:公式参数高亮选区的位置拖拽 + + {Boolean} [cellRightClick]:单元格右击 + + {Boolean} [rowTitleRightClick]:行标题右击 + + {Boolean} [columnTitleRightClick]:列标题右击 + + {Boolean} [sheetRightClick]:底部sheet页右击 + + {Boolean} [hyperlinkClick]:点击超链接 - {Object} [ctx]: 当前画布的context ------------ +### scroll -## 选区 - -### rangeSelectBefore -(TODO) - 类型:Function - 默认值:null -- 作用:框选或者设置选区前触发 +- 作用:鼠标滚动事件 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object} [position]: + + {Number} [scrollLeft]:横向滚动条的位置 + + {Number} [scrollTop]:垂直滚动条的位置 + + {Number} [canvasHeight]:canvas高度 + +------------ +### cellDragStop +- 类型:Function +- 默认值:null +- 作用:鼠标拖拽文件到Luckysheet内部的结束事件 +- 参数: + - {Object} [cell]:单元格对象 + - {Object} [position]: + + {Number} [r]:单元格所在行号 + + {Number} [c]:单元格所在列号 + + {Number} [start_r]:单元格左上角的垂直坐标 + + {Number} [start_c]:单元格左上角的水平坐标 + + {Number} [end_r]:单元格右下角的垂直坐标 + + {Number} [end_c]:单元格右下角的水平坐标 + - {Object} [sheet]:当前sheet对象 + - {Object} [ctx]: 当前画布的context + - {Object} [event]: 当前事件对象 + ------------ -### rangeSelectAfter -(TODO) + +## 选区操作(包括单元格) + +### rangeSelect + - 类型:Function - 默认值:null - 作用:框选或者设置选区后触发 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object} [sheet]:当前sheet对象 + - {Object | Array} [range]: 选区范围,可能为多个选区 ------------ ### rangeMoveBefore @@ -884,7 +1200,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区修改前 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 选区范围所对应的数据 ------------ @@ -894,7 +1210,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区修改后 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [oldData]: 修改前选区范围所对应的数据 - {Object} [newData]: 修改后选区范围所对应的数据 @@ -905,7 +1221,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区复制前 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 选区范围所对应的数据 ------------ @@ -915,17 +1231,17 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区复制后 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 选区范围所对应的数据 ------------ ### rangePasteBefore -(TODO) + - 类型:Function - 默认值:null - 作用:选区粘贴前 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 要被粘贴的选区范围所对应的数据 ------------ @@ -935,7 +1251,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区粘贴后 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [originData]: 要被粘贴的选区范围所对应的数据 - {Object} [pasteData]: 要粘贴的数据 @@ -986,7 +1302,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区清除前 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 要被清除的选区范围所对应的数据 ------------ @@ -996,7 +1312,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:选区清除后 - 参数: - - {Object || Array} [range]: 选区范围,可能为多个选区 + - {Object | Array} [range]: 选区范围,可能为多个选区 - {Object} [data]: 被清除的选区范围所对应的数据 ------------ @@ -1021,21 +1337,75 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ## 工作表 -### sheetCreatekBefore -(TODO) +### sheetCreateBefore + - 类型:Function - 默认值:null - 作用:创建sheet页前触发,sheet页新建也包含数据透视表新建 ------------ ### sheetCreateAfter -(TODO) + - 类型:Function - 默认值:null - 作用:创建sheet页后触发,sheet页新建也包含数据透视表新建 - 参数: - {Object} [sheet]: 当前新创建的sheet页的配置 +------------ +### sheetCopyBefore + +- 类型:Function +- 默认值:null +- 作用:拷贝创建sheet页前触发,sheet页新建也包含数据透视表新建 +- 参数: + - {Object} [targetSheet]: 被拷贝的sheet页配置 + - {Object} [copySheet]: 拷贝得到的sheet页的配置 +------------ +### sheetCopyAfter + +- 类型:Function +- 默认值:null +- 作用:拷贝创建sheet页后触发,sheet页新建也包含数据透视表新建 +- 参数: + - {Object} [sheet]: 当前创建的sheet页的配置 + +------------ +### sheetHideBefore + +- 类型:Function +- 默认值:null +- 作用:隐藏sheet页前触发 +- 参数: + - {Object} [sheet]: 将要隐藏的sheet页的配置 + +------------ +### sheetHideAfter + +- 类型:Function +- 默认值:null +- 作用:隐藏sheet页后触发 +- 参数: + - {Object} [sheet]: 要隐藏的sheet页的配置 + +------------ +### sheetShowBefore + +- 类型:Function +- 默认值:null +- 作用:显示sheet页前触发 +- 参数: + - {Object} [sheet]: 将要显示的sheet页的配置 + +------------ +### sheetShowAfter + +- 类型:Function +- 默认值:null +- 作用:显示sheet页后触发 +- 参数: + - {Object} [sheet]: 要显示的sheet页的配置 + ------------ ### sheetMoveBefore (TODO) @@ -1059,7 +1429,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### sheetDeleteBefore -(TODO) + - 类型:Function - 默认值:null - 作用:sheet删除前 @@ -1068,7 +1438,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### sheetDeleteAfter -(TODO) + - 类型:Function - 默认值:null - 作用:sheet删除后 @@ -1077,7 +1447,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### sheetEditNameBefore -(TODO) + - 类型:Function - 默认值:null - 作用:sheet修改名称前 @@ -1087,7 +1457,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### sheetEditNameAfter -(TODO) + - 类型:Function - 默认值:null - 作用:sheet修改名称后 @@ -1138,12 +1508,68 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - {String} [oldZoom]: 修改前当前sheet页缩放比例 - {String} [newZoom]: 修改后当前sheet页缩放比例 +------------ +### sheetActivate + +- 类型:Function +- 默认值:null +- 作用:激活工作表前 +- 参数: + - {Number} [i]: sheet页的`index` + - {Boolean} [isPivotInitial]: 是否切换到了数据透视表页 + - {Boolean} [isNewSheet]: 是否新建了sheet页 + +------------ +### sheetDeactivateBefore +(TODO) +- 类型:Function +- 默认值:null +- 作用:工作表从活动状态转为非活动状态前 +- 参数: + - {Number} [i]: sheet页的`index` + +------------ +### sheetDeactivateAfter +(TODO) +- 类型:Function +- 默认值:null +- 作用:工作表从活动状态转为非活动状态后 +- 参数: + - {Number} [i]: sheet页的`index` + +### imageDeleteBefore + +- 类型:Function +- 默认值:null +- 作用:图片删除前触发 +- 参数: + - {Object} [imageItem]: 要删除的图片配置对象 + +### imageDeleteAfter + +- 类型:Function +- 默认值:null +- 作用:图片删除后触发,如果自定义了图片上传,可在此处发请求删除图片 +- 参数: + - {Object} [imageItem]: 删除的图片配置对象 + +```js +{ + hook: { + imageDeleteAfter: function (imageItem) { + var src = imgItem.src; + $.post('/rest/file/deletebyurl', {downloadUrl: src}); + } + } +} +``` + ------------ ## 工作簿 ### workbookCreateBefore -(TODO) + - 类型:Function - 默认值:null - 作用:表格创建之前触发。旧的钩子函数叫做`beforeCreateDom` @@ -1152,7 +1578,7 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### workbookCreateAfter -(TODO) + - 类型:Function - 默认值:null - 作用:表格创建之后触发 @@ -1179,10 +1605,10 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ ### updated -(TODO) + - 类型:Function - 默认值:null -- 作用:每次操作更新后执行的方法,在画布渲染之后执行,即客户端每执行一次表格操作,Luckysheet将这次操作存到历史记录中后触发,撤销重做时因为也算一次操作,当然也会触发此钩子函数。 +- 作用:协同编辑中的每次操作后执行的方法,监听表格内容变化,即客户端每执行一次表格操作,Luckysheet将这次操作存到历史记录中后触发,撤销重做时因为也算一次操作,也会触发此钩子函数。 - 参数: - {Object} [operate]: 本次操作的历史记录信息,根据不同的操作,会有不同的历史记录,参考源码 [历史记录](https://github.com/mengshukeji/Luckysheet/blob/master/src/controllers/controlHistory.js) @@ -1196,7 +1622,28 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - {Object} [size]: 整个工作簿区域的宽高 ------------ +### scroll +- 类型:Function +- 默认值:null +- 作用:监听表格滚动值 +- 参数: + - {Number} [scrollLeft]: 水平方向滚动值 + - {Number} [scrollTop]: 垂直方向滚动值 + - {Number} [canvasHeight]: 滚动容器的高度 + +------------ + + +## 协作消息 + +### cooperativeMessage +- 类型:Function +- 默认值:null +- 作用:接受协作消息,二次开发。拓展协作消息指令集 +- 参数: + - {Object} : 收到服务器发送的整个协作消息体对象 + ## 图片 ### imageInsertBefore @@ -1258,56 +1705,67 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ## 批注 ### commentInsertBefore -(TODO) + - 类型:Function - 默认值:null -- 作用:插入批注之前 +- 作用:插入批注之前,`return false` 则不插入批注 - 参数: - - {Object} [cell]: 要插入的批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 ------------ ### commentInsertAfter -(TODO) + - 类型:Function - 默认值:null - 作用:插入批注之后 - 参数: + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 - {Object} [cell]: 被插入批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}`,包含批注信息 ------------ ### commentDeleteBefore -(TODO) + - 类型:Function - 默认值:null -- 作用:删除批注之前 +- 作用:删除批注之前,`return false` 则不删除批注 - 参数: - - {Object} [cell]: 要删除的批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 + - {Object} [cell]: 要删除的批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}`,可以看到批注信息 ------------ ### commentDeleteAfter -(TODO) + - 类型:Function - 默认值:null - 作用:删除批注之后 - 参数: - - {Object} [cell]: 被删除批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 + - {Object} [cell]: 被删除批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}`,可以看到批注已被删除 ------------ ### commentUpdateBefore -(TODO) + - 类型:Function - 默认值:null -- 作用:修改批注之前 +- 作用:修改批注之前,`return false` 则不修改批注 - 参数: - - {Object} [cell]: 批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 + - {String} [value]: 新的批注内容 ------------ ### commentUpdateAfter -(TODO) + - 类型:Function - 默认值:null - 作用:修改批注之后 - 参数: + - {Number} [r]:单元格所在行号 + - {Number} [c]:单元格所在列号 - {Object} [oldCell]: 修改前批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` - {Object} [newCell]: 修改后批注所在的单元格信息,如:`{ r:0,c:2,v:{m:'233',v:'233'}}` @@ -1374,6 +1832,16 @@ Luckysheet开放了更细致的自定义配置选项,分别有 ------------ +## 打印 + +### printBefore +(TODO) +- 类型:Function +- 默认值:null +- 作用:打印前 + +------------ + ## 旧版钩子函数 ### fireMousedown @@ -1382,4 +1850,16 @@ Luckysheet开放了更细致的自定义配置选项,分别有 - 默认值:null - 作用:单元格数据下钻自定义方法,注意此钩子函数是挂载在options下:`options.fireMousedown` +------------ + +## 分页器 + +### onTogglePager + +- 类型:Function +- 默认值:null +- 作用:点击分页按钮回调函数,返回当前页码,具体参数参照[sPage backFun](https://github.com/jvbei/sPage) +- 参数: + - {Object} [page]: 返回当前分页对象 + ------------ \ No newline at end of file diff --git a/docs/zh/guide/contribute.md b/docs/zh/guide/contribute.md new file mode 100644 index 0000000000000000000000000000000000000000..18ef20ede3dfe999bfe622c75c2835808cff6d77 --- /dev/null +++ b/docs/zh/guide/contribute.md @@ -0,0 +1,222 @@ + +# 贡献指南 + + 欢迎!我们很高兴您能来到这里,并非常期待您能有兴趣参与 Luckysheet 贡献。当然,在您参与 Luckysheet 贡献之前,请确保通读以下全文: + +## 我们的行为准则 + +1. 我们保证尊重所有参与贡献的人,不限于提出问题、文档和代码贡献、解决bug以及其它贡献的人; + +2. 我们有义务遵守当地法律法规,所有的附带法律风险的行为我们都是拒绝的; +3. 我们反对任何参与者存在贬损评论、人身攻击、骚扰或侮辱他人以及其他非专业行为; +4. 我们有权并有责任删除或编辑与此行为准则不符的内容,不限于代码、Issues、wiki、文档以及其它。不遵守行为准则的参与者可能会被移除团队; +5. 我们接受任何人的监督,任何人可通过问题反馈,向我们报告发现的与此行为准则不符的事实存在。 + +## 如何参与贡献? + +* 贡献文档:浏览文档可以加深您对 Luckysheet 的了解,一旦发现文档写得不清晰或逻辑混乱的地方,可以订正、修改、补充,您可以通过 [中文论坛](https://support.qq.com/products/288322)或者 [谷歌论坛](https://groups.google.com/g/luckysheet)给予反馈 +* 贡献代码:欢迎大家为 Luckysheet 社区贡献代码,欢迎您认领Open状态的 [Issues](https://github.com/mengshukeji/Luckysheet/issues) 和未完成的特性,提交PR,成为贡献者之一如果您在使用过程中发现有些功能无法满足您的需求或出现问题,请在Issues中记录 +* 参与Issue讨论:您可以在任一 [Issues](https://github.com/mengshukeji/Luckysheet/issues) 下发表您的建议 +* Review代码:您可以在 [Github](https://github.com/mengshukeji/Luckysheet)上看到所有贡献者提交的PR,您可以Review他们的代码并发表您的建议 + + +## 如何提交 Issues + +在您提交特性/改进前,应该注意以下几点: + +* 请先确认该特性/改进是否被其他人已经提交 +* 一个通俗易懂的标题来阐述你提交的Bug/提交特性/改进 +* 如果是Bug则详细描述该bug产生的原因,如果能够复现,请尽量提供完整的重现步骤 +* 如果是特性,那么该特性应该有广泛的适用性,适用于大部分用户,最好能够提供详尽的设计文档 +* 如果是改进,尽可能描述清楚此改进所带来的益处 + +具体步骤: + +* 创建 [Issues](https://github.com/mengshukeji/Luckysheet/issues) ,描述清楚问题 +* 如果你要解决该issue则将issue assign到自己名下,如果你仅仅是提交Bug/特性/改进,并没有时间去贡献代码,则assignne设置为空 +* 如果是比较大的特性/改进,尽量先输出设计文档,走 [Luckysheet RFC](https://github.com/mengshukeji/Luckysheet-rfcs) 流程,供其他人review + +## 如何认领 Issues + +在 Luckysheet 的 [Issues](https://github.com/mengshukeji/Luckysheet/issues) 列表中,有很多由其他人创建的issue并未被修复,如果你感兴趣的话,可以认领这些issue。认领步骤如下: + +* 在该issue下留言,表达想认领该任务的想法,另注明 **@I can solve it** 即可 +* 如果提交者没有意见,则将该issue assign到自己名下并及时更新进度 +* 如果是比较大的特性,尽量先输出设计文档,走 [Luckysheet RFC](https://github.com/mengshukeji/Luckysheet-rfcs) 流程,供其他人review +* 开发代码并提交代码至github + + +## 如何提交代码 + +1. fork 到自己的仓库 + +进入  [Luckysheet](https://github.com/mengshukeji/Luckysheet)  的Github页面 ,点击右上角按钮 Fork 进行 Fork。 + +2. git clone 到本地 + +```shell +git clone https://github.com//Luckysheet.git +``` + +3. 上游建立连接 + +```shell + +cd Luckysheet +git remote add upstream https://github.com/mengshukeji/Luckysheet.git +``` +4. 创建开发分支 + +```shell +git checkout -b dev +``` + +5. 修改提交代码 + +```shell +git add .  +npm run commit +git push origin dev +``` + +6. 同步代码,将最新代码同步到本地 + +```shell +git fetch upstream  +git rebase upstream/master +``` + +7. 如果有冲突(没有可以忽略) + +```shell +git status # 查看冲突文件,并修改冲突 +git add . +git rebase --continue +``` +提交git rebase --continue命令的时候,如果弹出vim提示编辑commit信息,则可以添加你的修改,然后保存退出 +> vim命令请参考阅读[vim](https://www.runoob.com/linux/linux-vim.html) + +8. 提交分支代码 + +```shell +git push origin dev +``` + +如果提示需要先pull 可以先拉取在提交 +```shell +git pull origin dev +git push origin dev +``` +若弹出vim提示编辑commit信息,可以直接通过vim命令退出 +> vim命令请参考阅读[vim](https://www.runoob.com/linux/linux-vim.html) + +9. 提交pr +去自己github仓库对应fork的项目,切换到刚刚创建修改的分支,点击new pull request,并添加上对应的描述,最后点击Create pull request进行提交 + +## 代码规范 + +> 一般性的代码规范示例 + +* 保持块深度最小。尽可能避免嵌套If条件 +```js +// CORRECT +if (!comparison) return + +if (variable) { + for (const item of items) {} +} else if (variable2) { + // Do something here +} + +// INCORRECT +if (comparison) { + if (variable) { + for (const item in items) {} + } else if (variable2) { + // Do something here + } +} else { + return +} +``` + +* 不要使用操作数进行链比较 +```js +// CORRECT + +if (cb) cb() +if (!cb || (cb === fn)) cb() + +// INCORRECT + +cb && cb() +(!cb || (cb === fn)) && cb() +``` + +* 所有变量都应该按字母顺序在块的开头声明 +```js +// CORRECT +function foo () { + const foo = 'bar' + const bar = 'foo' + + if (conditional) {} + + ... + + return foo +} + +// INCORRECT + +function foo () { + const foo = 'bar' + + if (conditional) {} + + const bar = 'foo' + + ... + + return foo +} +``` + +* 尽快返回 +```js +// CORRECT +if (condition) return 'foo' +if (condition2) return 'bar' +// Return must have a blank line above +return 'fizz' + +// INCORRECT +const variable = '' + +if (condition) { + variable = 'foo' +} else if (condition2) { + variable = 'bar' +} else { + variable = 'fizz' +} + +return variable +``` + +## 如何贡献文档 + +## 如何成为Luckysheet Committer + +任何人只要对 Luckysheet 项目做了贡献,那您就是官方承认的 Luckysheet 项目的Contributor了,从Contributor成长为Committer并没有一个确切的标准, 也没有任何预期的时间表,但是Committer的候选人一般都是长期活跃的贡献者,成为Committer并没有要求必须有巨大的架构改进贡献, 或者多少行的代码贡献,贡献代码、贡献文档、参与邮件列表的讨论、帮助回答问题等等都提升自己影响力的方式。 + +潜在贡献清单(无特定顺序): + +* 提交自己发现的Bug、特性、改进到issue +* 更新官方文档使项目的文档是最近的、撰写 Luckysheet 的最佳实践、特性剖析的各种对用户有用的文档 +* 执行测试并报告测试结果,性能测试与其他MQ的性能对比测试等 +* 审查(Review)其他人的工作(包括代码和非代码)并发表你自己的建议 +* 指导新加入的贡献者,熟悉社区流程 +* 发表关于 Luckysheet 的博客 +* 有利于 Luckysheet 社区发展的任何贡献 +* ...... diff --git a/docs/zh/guide/operate.md b/docs/zh/guide/operate.md index 02db44623b86b68648859d035622d0fb43ba94fd..8e428fe9f07f96c2ea43b5ceac503c01538bf26c 100644 --- a/docs/zh/guide/operate.md +++ b/docs/zh/guide/operate.md @@ -1266,3 +1266,18 @@ ```js luckysheetfile[0].chart[v.chart_id] = v; ``` + +## 后端返回格式 + +websocket 后端返回的数据格式 +```js +{ + createTime: 命令发送时间 + data:{} 修改的命令 + id: "7a" websocket的id + returnMessage: "success" + status: "0" 0告诉前端需要根据data的命令修改 1无意义 + type: 0:连接成功,1:发送给当前连接的用户,2:发送信息给其他用户,3:发送选区位置信息,999:用户连接断开 + username: 用户名 +} +``` \ No newline at end of file diff --git a/docs/zh/guide/resource.md b/docs/zh/guide/resource.md new file mode 100644 index 0000000000000000000000000000000000000000..74a7a08a6a34cbc71012acbe5364458c20da290b --- /dev/null +++ b/docs/zh/guide/resource.md @@ -0,0 +1,32 @@ +# 教程与资源 + +开源软件离不开社区的贡献,这里将会列举出社区提供的教程、学习资料及配套解决方案。 + +如果您写了或者发现了优秀的教程想要推荐给我们,请直接[编辑此页](https://github.com/mengshukeji/Luckysheet/edit/master/docs/zh/guide/resource.md)提交PR。 + +## 博客 +- [Luckysheet如何初始化含合并单元格的数据](https://www.cnblogs.com/DuShuSir/p/13272397.html) +- [Luckysheet如何把表格里的数据保存到数据库](https://www.cnblogs.com/DuShuSir/p/13857874.html) +- [本地HTML采用cdn加载方式引入Luckysheet的案例](https://www.cnblogs.com/DuShuSir/p/13859103.html) +- [Luckysheet基础用法,使用loadUrl加载服务端数据](https://blog.csdn.net/DCDC2020/article/details/108486525) +- [Luckysheet 导入与导出实现 - Java后台处理](https://blog.csdn.net/u014632228/article/details/109738221) + +## 前端案例 + +### 社区案例 +- [luckysheet-vue-importAndExport](https://github.com/oy-paddy/luckysheet-vue-importAndExport/tree/master/) + +## 后端案例 + +### 官方案例 +- [Java 后台 Luckysheet Server](https://github.com/mengshukeji/LuckysheetServer) + +### 社区案例 +- [Luckysheet保存与恢复](https://gitee.com/ichiva/luckysheet-saved-in-recovery)(Java版) +- [基于Luckysheet实现的协同编辑在线表格](https://github.com/DilemmaVi/ecsheet)(Java版) +- [使用.net core 3.1和Npoi 制作基于LuckSheet的基础导出](https://gitee.com/xiong-kangli/luck-sheet_.-net-core)(.NET 版本) +- [go语言版本的协同编辑](https://github.com/fandypeng/excel2config)(Go 版本) + +## 学习资料 + +- [如何从0到1搭建 Web 数据分析报表](https://github.com/mengshukeji/LuckyResources/blob/master/ppt/%E5%A6%82%E4%BD%95%E4%BB%8E0%E5%88%B01%E6%90%AD%E5%BB%BA%20Web%20%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E6%8A%A5%E8%A1%A8.pptx) \ No newline at end of file diff --git a/docs/zh/guide/sheet.md b/docs/zh/guide/sheet.md index ba633f91cde84008100a5566d61ab0691844e4d2..9fb6cae381ce83ec5a66895a726771c6710da9c4 100644 --- a/docs/zh/guide/sheet.md +++ b/docs/zh/guide/sheet.md @@ -43,7 +43,6 @@ options.data示例如下: "luckysheet_conditionformat_save": {},//条件格式 "frozen": {}, //冻结行列配置 "chart": [], //图表配置 - "allowEdit": true, //是否允许编辑 "zoomRatio":1, // 缩放比例 "image":[], //图片 "showGridLines": 1, //是否显示网格线 @@ -256,7 +255,7 @@ options.data示例如下: ``` #### config.borderInfo -- 类型:Object +- 类型:Array - 默认值:{} - 作用:单元格的边框信息 - 示例: @@ -308,7 +307,7 @@ options.data示例如下: 1. 选区 `rangeType: "range"` + 边框类型 `borderType:"border-left" | "border-right" | "border-top" | "border-bottom" | "border-all" | "border-outside" | "border-inside" | "border-horizontal" | "border-vertical" | "border-none"`, - + 边框粗细 `style: 1 Thin | 2 Hair | 3 Dotted | 4 Dashed | 5 DashDot | 6 DashDotDot | 7 Double | 8 Medium | 9 MediumDashed | 10 MediumDashDot | 11 MediumDashDotDot | 12 SlantedDashDot | 13 Thick` + + 边框粗细 `style: 1 Thin | 2 Hair | 3 Dotted | 4 Dashed | 5 DashDot | 6 DashDotDot | 7 Double | 8 Medium | 9 MediumDashed | 10 MediumDashDot | 11 MediumDashDotDot | 12 SlantedDashDot | 13 Thick`,和aspose.cells的getLineStyle()的值对应的话,需要自己做个转换,参考 [aspose.cells](https://apireference.aspose.com/cells/net/aspose.cells/cellbordertype) + 边框颜色 `color: 16进制颜色值` + 选区范围 `range: 行列信息数组` @@ -1281,12 +1280,6 @@ options.data示例如下: ``` ::: ------------- -### allowEdit -- 类型:Boolean -- 默认值:true -- 作用: 此sheet页是否允许编辑 - ------------ ### zoomRatio - 类型:Number @@ -1351,8 +1344,10 @@ options.data示例如下: + `"date"`(日期) + `"validity"`(有效性); + {String | Null} [type2]: 条件类型; - + 类型`type`值为`"dropdown"/"checkbox"`时,`type2`值可为 + + 类型`type`值为`"checkbox"`时,`type2`值可为 + `null`; + + 类型`type`值为`"dropdown"`时,`type2`值可为 + + `true` (多选) `false` (单选) + 类型`type`值为`"number"/"number_integer"/"number_decimal"/"text_length"`时,`type2`值可为 + `"bw"`(介于) + `"nb"`(不介于) @@ -1436,7 +1431,6 @@ Luckysheet在初始化完成之后进行的一系列操作,会将更多本地 "frozen": {}, //冻结行列配置 "freezen": {}, //冻结行列的渲染数据存储 "chart": [], //图表配置 - "allowEdit": true, //是否允许编辑 "zoomRatio":1, // 缩放比例 "image":[], //图片 "showGridLines": 1, //是否显示网格线 diff --git a/gulpfile.js b/gulpfile.js index 6728463087a5f386fc123253a4cefa1f851057ae..f53def0c366b9b49d11bfec997bc2d0de4d5c6a3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -12,6 +12,8 @@ const del = require('delete'); // Refresh the browser in real time const browserSync = require('browser-sync').create(); const reload = browserSync.reload; +// proxy +const { createProxyMiddleware } = require('http-proxy-middleware'); // According to html reference, files are merged // const useref = require('gulp-useref'); // File merge @@ -26,9 +28,17 @@ const commonjs = require('@rollup/plugin-commonjs'); const terser = require('rollup-plugin-terser').terser; // rollup babel plugin, support the latest ES grammar const babel = require('@rollup/plugin-babel').default; +// const gulpBabel = require('gulp-babel'); // Distinguish development and production environments const production = process.env.NODE_ENV === 'production' ? true : false; +const pkg = require('./package.json'); +const banner = `/*! @preserve + * ${pkg.name} + * version: ${pkg.version} + * https://github.com/mengshukeji/Luckysheet + */`; + // uglify js Compression configuration https://github.com/mishoo/UglifyJS#minify-options const uglifyOptions = { compress: { @@ -38,6 +48,7 @@ const uglifyOptions = { // babel config const babelConfig = { + compact:false, babelHelpers: 'bundled', exclude: 'node_modules/**', // Only compile our source code plugins: [ @@ -80,24 +91,21 @@ const paths = { //plugins src pluginsCss: ['src/plugins/css/*.css'], plugins: ['src/plugins/*.css'], - css:['src/css/*.css'], + css:['src/css/*.css','node_modules/flatpickr/dist/themes/light.css'], pluginsJs:[ - 'src/plugins/js/jquery.min.js', + 'node_modules/jquery/dist/jquery.min.js', + 'node_modules/uuid/dist/umd/uuid.min.js', 'src/plugins/js/clipboard.min.js', 'src/plugins/js/spectrum.min.js', 'src/plugins/js/jquery-ui.min.js', 'src/plugins/js/jquery.mousewheel.min.js', - 'src/plugins/js/moment.min.js', - 'src/plugins/js/moment-timezone-with-data.min.js', - 'src/plugins/js/moment-msdate.js', - 'src/plugins/js/numeral.min.js', + // 'src/plugins/js/numeral.min.js', 'src/plugins/js/html2canvas.min.js', - 'src/plugins/js/pako.min.js', 'src/plugins/js/localforage.min.js', 'src/plugins/js/lodash.min.js', - 'src/plugins/js/daterangepicker.js', 'src/plugins/js/jstat.min.js', - 'src/plugins/js/crypto-api.min.js' + 'src/plugins/js/crypto-api.min.js', + 'src/plugins/js/jquery.sPage.min.js' ], //plugins concat @@ -121,12 +129,21 @@ function clean() { return del([paths.dist]); } +// proxy middleware +const apiProxy = createProxyMiddleware('/luckysheet/', { + target: 'http://luckysheet.lashuju.com/', // set your server address + changeOrigin: true, // for vhosted sites + ws: true, // proxy websockets +}); + // Static server function serve(done) { browserSync.init({ server: { - baseDir: paths.dist - } + baseDir: paths.dist, + middleware: [apiProxy],//proxy + }, + ghostMode: false, //默认true,滚动和表单在任何设备上输入将被镜像到所有设备里,会影响本地的协同编辑消息,故关闭 }, done) } @@ -160,7 +177,7 @@ function reloadBrowser(done) { } //Package the core code -async function core() { +async function core_rollup() { const bundle = await rollup({ input: 'src/index.js', plugins: [ @@ -182,7 +199,7 @@ async function core() { name: 'luckysheet', sourcemap: true, inlineDynamicImports:true, - + banner: banner }); if(production){ @@ -192,11 +209,27 @@ async function core() { name: 'luckysheet', sourcemap: true, inlineDynamicImports:true, + banner: banner }); } } +async function core() { + + await require('esbuild').buildSync({ + format: 'iife', + globalName: 'luckysheet', + entryPoints: ['src/index.js'], + bundle: true, + minify: production, + banner: { js: banner }, + target: ['es2015'], + sourcemap: true, + outfile: 'dist/luckysheet.umd.js', + }) +} + // According to the build tag in html, package js and css function pluginsCss() { return src(paths.pluginsCss) @@ -251,6 +284,10 @@ function copyStaticExpendPlugins(){ function copyStaticDemoData(){ return src(paths.staticDemoData) .pipe(dest(paths.destStaticDemoData)); + // .pipe(gulpBabel({ + // presets: ['@babel/env'] + // })) + // .pipe(gulp.dest('dist')); } function copyStaticCssImages(){ return src(paths.staticCssImages) diff --git a/package.json b/package.json index fa288fc0a0521e50c208e30ca0e82e5b5cb0dbc1..70470dc7a2711b0c47d00b801d35313b8d06ccf2 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,12 @@ { "name": "luckysheet", - "version": "2.1.4", + "version": "2.1.13", "main": "dist/luckysheet.cjs.js", "module": "dist/luckysheet.esm.js", "browser": "dist/luckysheet.umd.js", "devDependencies": { - "@babel/preset-env": "^7.10.2", + "@babel/core": "^7.12.3", + "@babel/preset-env": "^7.12.1", "@babel/runtime-corejs3": "^7.12.1", "@commitlint/cli": "^9.1.1", "@commitlint/config-conventional": "^9.1.1", @@ -17,19 +18,32 @@ "cross-env": "^7.0.2", "delete": "^1.1.0", "gulp": "^4.0.2", + "gulp-babel": "^8.0.0", "gulp-clean-css": "^4.3.0", "gulp-concat": "^2.6.1", "gulp-if": "^3.0.0", "gulp-uglify": "^3.0.2", "gulp-useref": "^4.0.1", + "http-proxy-middleware": "^1.0.6", "rollup": "^2.32.1", "rollup-plugin-terser": "^6.1.0", "standard-version": "^8.0.2", - "vuepress": "^1.5.0" + "uuid": "^8.3.2", + "vuepress": "^1.5.0", + "vuepress-plugin-baidu-autopush": "^1.0.1", + "vuepress-plugin-code-copy": "^1.0.6", + "vuepress-plugin-seo": "^0.1.4", + "vuepress-plugin-sitemap": "^2.3.1" }, "dependencies": { "@babel/runtime": "^7.12.1", - "jspdf": "^2.1.1" + "dayjs": "^1.9.6", + "esbuild": "^0.11.6", + "escape-html": "^1.0.3", + "flatpickr": "^4.6.6", + "jquery": "^2.2.4", + "numeral": "^2.0.6", + "pako": "^1.0.11" }, "scripts": { "build": "cross-env NODE_ENV=production gulp build", diff --git a/src/assets/iconfont/demo_index.html b/src/assets/iconfont/demo_index.html index 0354cb633e617d6dabc34b3f27c7867bd22f7c3e..b24698ab6da3831942688bf0c8c440391e338231 100644 --- a/src/assets/iconfont/demo_index.html +++ b/src/assets/iconfont/demo_index.html @@ -741,992 +741,992 @@
  • - +
    链接
    -
    .icon-lianjie +
    .luckysheet-iconfont-lianjie
  • - +
    打印区域
    -
    .icon-dayinquyu +
    .luckysheet-iconfont-dayinquyu
  • - +
    打印页面配置
    -
    .icon-dayinyemianpeizhi +
    .luckysheet-iconfont-dayinyemianpeizhi
  • - +
    打印标题
    -
    .icon-dayinbiaoti +
    .luckysheet-iconfont-dayinbiaoti
  • - +
    分页预览
    -
    .icon-fenyeyulan +
    .luckysheet-iconfont-fenyeyulan
  • - +
    普通
    -
    .icon-putong +
    .luckysheet-iconfont-putong
  • - +
    页面布局
    -
    .icon-yemianbuju +
    .luckysheet-iconfont-yemianbuju
  • - +
    表格锁定
    -
    .icon-biaogesuoding +
    .luckysheet-iconfont-biaogesuoding
  • - +
    转到
    -
    .icon-zhuandao1 +
    .luckysheet-iconfont-zhuandao1
  • - +
    右箭头
    -
    .icon-youjiantou +
    .luckysheet-iconfont-youjiantou
  • - +
    菜单
    -
    .icon-caidan2 +
    .luckysheet-iconfont-caidan2
  • - +
    替换
    -
    .icon-tihuan +
    .luckysheet-iconfont-tihuan
  • - +
    冻结
    -
    .icon-dongjie1 +
    .luckysheet-iconfont-dongjie1
  • - +
    -
    .icon-jian1 +
    .luckysheet-iconfont-jian1
  • - +
    -
    .icon-jia1 +
    .luckysheet-iconfont-jia1
  • - +
    溢出
    -
    .icon-yichu1 +
    .luckysheet-iconfont-yichu1
  • - +
    升序
    -
    .icon-shengxu1 +
    .luckysheet-iconfont-shengxu1
  • - +
    内框线
    -
    .icon-neikuangxian +
    .luckysheet-iconfont-neikuangxian
  • - +
    清除筛选
    -
    .icon-qingchushaixuan +
    .luckysheet-iconfont-qingchushaixuan
  • - +
    文本向上
    -
    .icon-wenbenxiangshang +
    .luckysheet-iconfont-wenbenxiangshang
  • - +
    降序
    -
    .icon-jiangxu1 +
    .luckysheet-iconfont-jiangxu1
  • - +
    内框横线
    -
    .icon-neikuanghengxian +
    .luckysheet-iconfont-neikuanghengxian
  • - +
    内框竖线
    -
    .icon-neikuangshuxian +
    .luckysheet-iconfont-neikuangshuxian
  • - +
    自定义排序
    -
    .icon-zidingyipaixu +
    .luckysheet-iconfont-zidingyipaixu
  • - +
    logo2
    -
    .icon-logo2 +
    .luckysheet-iconfont-logo2
  • - +
    logo
    -
    .icon-logo +
    .luckysheet-iconfont-logo
  • - +
    文本倾斜
    -
    .icon-wenbenqingxie1 +
    .luckysheet-iconfont-wenbenqingxie1
  • - +
    加粗
    -
    .icon-jiacu +
    .luckysheet-iconfont-jiacu
  • - +
    搜索
    -
    .icon-sousuo +
    .luckysheet-iconfont-sousuo
  • - +
    关闭
    -
    .icon-guanbi +
    .luckysheet-iconfont-guanbi
  • - +
    下一个
    -
    .icon-xiayige +
    .luckysheet-iconfont-xiayige
  • - +
    下拉
    -
    .icon-xiala +
    .luckysheet-iconfont-xiala
  • - +
    文本颜色
    -
    .icon-wenbenyanse +
    .luckysheet-iconfont-wenbenyanse
  • - +
    上一个
    -
    .icon-shangyige +
    .luckysheet-iconfont-shangyige
  • - +
    数据透视
    -
    .icon-shujutoushi +
    .luckysheet-iconfont-shujutoushi
  • - +
    填充
    -
    .icon-tianchong +
    .luckysheet-iconfont-tianchong
  • - +
    增加小数位
    -
    .icon-zengjiaxiaoshuwei +
    .luckysheet-iconfont-zengjiaxiaoshuwei
  • - +
    编辑2
    -
    .icon-bianji2 +
    .luckysheet-iconfont-bianji2
  • - +
    截屏
    -
    .icon-jieping +
    .luckysheet-iconfont-jieping
  • - +
    减小小数位
    -
    .icon-jianxiaoxiaoshuwei +
    .luckysheet-iconfont-jianxiaoxiaoshuwei
  • - +
    菜单
    -
    .icon-caidan +
    .luckysheet-iconfont-caidan
  • - +
    数据库
    -
    .icon-shujuku +
    .luckysheet-iconfont-shujuku
  • - +
    无边框
    -
    .icon-wubiankuang +
    .luckysheet-iconfont-wubiankuang
  • - +
    编辑
    -
    .icon-bianji +
    .luckysheet-iconfont-bianji
  • - +
    清除样式
    -
    .icon-qingchuyangshi +
    .luckysheet-iconfont-qingchuyangshi
  • - +
    删除
    -
    .icon-shanchu +
    .luckysheet-iconfont-shanchu
  • - +
    文本居中对齐
    -
    .icon-wenbenjuzhongduiqi +
    .luckysheet-iconfont-wenbenjuzhongduiqi
  • - +
    打印
    -
    .icon-dayin +
    .luckysheet-iconfont-dayin
  • - +
    文本分割
    -
    .icon-wenbenfenge +
    .luckysheet-iconfont-wenbenfenge
  • - +
    函数‘
    -
    .icon-hanshu +
    .luckysheet-iconfont-hanshu
  • - +
    降序
    -
    .icon-jiangxu +
    .luckysheet-iconfont-jiangxu
  • - +
    顶部对齐
    -
    .icon-dingbuduiqi +
    .luckysheet-iconfont-dingbuduiqi
  • - +
    图片
    -
    .icon-tupian +
    .luckysheet-iconfont-tupian
  • - +
    向下90
    -
    .icon-xiangxia90 +
    .luckysheet-iconfont-xiangxia90
  • - +
    竖排文字
    -
    .icon-shupaiwenzi +
    .luckysheet-iconfont-shupaiwenzi
  • - +
    全加边框
    -
    .icon-quanjiabiankuang +
    .luckysheet-iconfont-quanjiabiankuang
  • - +
    升序
    -
    .icon-shengxu +
    .luckysheet-iconfont-shengxu
  • - +
    裁剪
    -
    .icon-caijian +
    .luckysheet-iconfont-caijian
  • - +
    金额
    -
    .icon-jine +
    .luckysheet-iconfont-jine
  • - +
    菜单1
    -
    .icon-caidan1 +
    .luckysheet-iconfont-caidan1
  • - +
    取消合并
    -
    .icon-quxiaohebing +
    .luckysheet-iconfont-quxiaohebing
  • - +
    文本下划线
    -
    .icon-wenbenxiahuaxian +
    .luckysheet-iconfont-wenbenxiahuaxian
  • - +
    上边框
    -
    .icon-shangbiankuang +
    .luckysheet-iconfont-shangbiankuang
  • - +
    定位
    -
    .icon-dingwei +
    .luckysheet-iconfont-dingwei
  • - +
    四周加边框
    -
    .icon-sizhoujiabiankuang +
    .luckysheet-iconfont-sizhoujiabiankuang
  • - +
    侧边栏收起
    -
    .icon-cebianlanshouqi +
    .luckysheet-iconfont-cebianlanshouqi
  • - +
    合并
    -
    .icon-hebing +
    .luckysheet-iconfont-hebing
  • - +
    向上倾斜
    -
    .icon-xiangshangqingxie +
    .luckysheet-iconfont-xiangshangqingxie
  • - +
    水平对齐
    -
    .icon-shuipingduiqi +
    .luckysheet-iconfont-shuipingduiqi
  • - +
    文本删除线
    -
    .icon-wenbenshanchuxian +
    .luckysheet-iconfont-wenbenshanchuxian
  • - +
    文本右对齐
    -
    .icon-wenbenyouduiqi +
    .luckysheet-iconfont-wenbenyouduiqi
  • - +
    前进
    -
    .icon-qianjin +
    .luckysheet-iconfont-qianjin
  • - +
    图表
    -
    .icon-tubiao +
    .luckysheet-iconfont-tubiao
  • - +
    右边框
    -
    .icon-youbiankuang +
    .luckysheet-iconfont-youbiankuang
  • - +
    百分号
    -
    .icon-baifenhao +
    .luckysheet-iconfont-baifenhao
  • - +
    格式刷
    -
    .icon-geshishua +
    .luckysheet-iconfont-geshishua
  • - +
    保存
    -
    .icon-baocun +
    .luckysheet-iconfont-baocun
  • - +
    数据验证
    -
    .icon-shujuyanzheng +
    .luckysheet-iconfont-shujuyanzheng
  • - +
    截断
    -
    .icon-jieduan +
    .luckysheet-iconfont-jieduan
  • - +
    格式条件
    -
    .icon-geshitiaojian +
    .luckysheet-iconfont-geshitiaojian
  • - +
    自动换行
    -
    .icon-zidonghuanhang +
    .luckysheet-iconfont-zidonghuanhang
  • - +
    侧边栏展开
    -
    .icon-cebianlanzhankai +
    .luckysheet-iconfont-cebianlanzhankai
  • - +
    筛选2
    -
    .icon-shaixuan2 +
    .luckysheet-iconfont-shaixuan2
  • - +
    向下倾斜
    -
    .icon-xiangxiaqingxie +
    .luckysheet-iconfont-xiangxiaqingxie
  • - +
    溢出
    -
    .icon-yichu +
    .luckysheet-iconfont-yichu
  • - +
    垂直合并
    -
    .icon-chuizhihebing +
    .luckysheet-iconfont-chuizhihebing
  • - +
    文本分散对齐
    -
    .icon-wenbenfensanduiqi +
    .luckysheet-iconfont-wenbenfensanduiqi
  • - +
    左边框
    -
    .icon-zuobiankuang +
    .luckysheet-iconfont-zuobiankuang
  • - +
    分页查看
    -
    .icon-fenyechakan +
    .luckysheet-iconfont-fenyechakan
  • - +
    运行
    -
    .icon-yunhang +
    .luckysheet-iconfont-yunhang
  • - +
    -
    .icon-lie +
    .luckysheet-iconfont-lie
  • - +
    全屏
    -
    .icon-quanping +
    .luckysheet-iconfont-quanping
  • - +
    筛选
    -
    .icon-shaixuan +
    .luckysheet-iconfont-shaixuan
  • - +
    更新
    -
    .icon-gengxin +
    .luckysheet-iconfont-gengxin
  • - +
    清除
    -
    .icon-qingchu +
    .luckysheet-iconfont-qingchu
  • - +
    -
    .icon-hang +
    .luckysheet-iconfont-hang
  • - +
    注释
    -
    .icon-zhushi +
    .luckysheet-iconfont-zhushi
  • - +
    -
    .icon-jian +
    .luckysheet-iconfont-jian
  • - +
    计算
    -
    .icon-jisuan +
    .luckysheet-iconfont-jisuan
  • - +
    -
    .icon-jia +
    .luckysheet-iconfont-jia
  • - +
    底部对齐
    -
    .icon-dibuduiqi +
    .luckysheet-iconfont-dibuduiqi
  • - +
    向上90
    -
    .icon-xiangshang90 +
    .luckysheet-iconfont-xiangshang90
  • - +
    无选装
    -
    .icon-wuxuanzhuang +
    .luckysheet-iconfont-wuxuanzhuang
  • - +
    显示隐藏网格
    -
    .icon-xianshiyincangwangge +
    .luckysheet-iconfont-xianshiyincangwangge
  • - +
    冻结
    -
    .icon-dongjie +
    .luckysheet-iconfont-dongjie
  • - +
    文本左对齐
    -
    .icon-wenbenzuoduiqi +
    .luckysheet-iconfont-wenbenzuoduiqi
  • - +
    后退
    -
    .icon-houtui +
    .luckysheet-iconfont-houtui
  • - +
    水平合并
    -
    .icon-shuipinghebing +
    .luckysheet-iconfont-shuipinghebing
  • - +
    下边框
    -
    .icon-xiabiankuang +
    .luckysheet-iconfont-xiabiankuang
  • - +
    设置
    -
    .icon-shezhi +
    .luckysheet-iconfont-shezhi
  • @@ -1748,7 +1748,7 @@
    <link rel="stylesheet" href="./iconfont.css">
     

    第二步:挑选相应图标并获取类名,应用于页面:

    -
    <span class="iconfont icon-xxx"></span>
    +
    <span class="iconfont luckysheet-iconfont-xxx"></span>
     

    " @@ -1761,882 +1761,882 @@

  • 链接
    -
    #icon-lianjie
    +
    #luckysheet-iconfont-lianjie
  • 打印区域
    -
    #icon-dayinquyu
    +
    #luckysheet-iconfont-dayinquyu
  • 打印页面配置
    -
    #icon-dayinyemianpeizhi
    +
    #luckysheet-iconfont-dayinyemianpeizhi
  • 打印标题
    -
    #icon-dayinbiaoti
    +
    #luckysheet-iconfont-dayinbiaoti
  • 分页预览
    -
    #icon-fenyeyulan
    +
    #luckysheet-iconfont-fenyeyulan
  • 普通
    -
    #icon-putong
    +
    #luckysheet-iconfont-putong
  • 页面布局
    -
    #icon-yemianbuju
    +
    #luckysheet-iconfont-yemianbuju
  • 表格锁定
    -
    #icon-biaogesuoding
    +
    #luckysheet-iconfont-biaogesuoding
  • 转到
    -
    #icon-zhuandao1
    +
    #luckysheet-iconfont-zhuandao1
  • 右箭头
    -
    #icon-youjiantou
    +
    #luckysheet-iconfont-youjiantou
  • 菜单
    -
    #icon-caidan2
    +
    #luckysheet-iconfont-caidan2
  • 替换
    -
    #icon-tihuan
    +
    #luckysheet-iconfont-tihuan
  • 冻结
    -
    #icon-dongjie1
    +
    #luckysheet-iconfont-dongjie1
  • -
    #icon-jian1
    +
    #luckysheet-iconfont-jian1
  • -
    #icon-jia1
    +
    #luckysheet-iconfont-jia1
  • 溢出
    -
    #icon-yichu1
    +
    #luckysheet-iconfont-yichu1
  • 升序
    -
    #icon-shengxu1
    +
    #luckysheet-iconfont-shengxu1
  • 内框线
    -
    #icon-neikuangxian
    +
    #luckysheet-iconfont-neikuangxian
  • 清除筛选
    -
    #icon-qingchushaixuan
    +
    #luckysheet-iconfont-qingchushaixuan
  • 文本向上
    -
    #icon-wenbenxiangshang
    +
    #luckysheet-iconfont-wenbenxiangshang
  • 降序
    -
    #icon-jiangxu1
    +
    #luckysheet-iconfont-jiangxu1
  • 内框横线
    -
    #icon-neikuanghengxian
    +
    #luckysheet-iconfont-neikuanghengxian
  • 内框竖线
    -
    #icon-neikuangshuxian
    +
    #luckysheet-iconfont-neikuangshuxian
  • 自定义排序
    -
    #icon-zidingyipaixu
    +
    #luckysheet-iconfont-zidingyipaixu
  • logo2
    -
    #icon-logo2
    +
    #luckysheet-iconfont-logo2
  • logo
    -
    #icon-logo
    +
    #luckysheet-iconfont-logo
  • 文本倾斜
    -
    #icon-wenbenqingxie1
    +
    #luckysheet-iconfont-wenbenqingxie1
  • 加粗
    -
    #icon-jiacu
    +
    #luckysheet-iconfont-jiacu
  • 搜索
    -
    #icon-sousuo
    +
    #luckysheet-iconfont-sousuo
  • 关闭
    -
    #icon-guanbi
    +
    #luckysheet-iconfont-guanbi
  • 下一个
    -
    #icon-xiayige
    +
    #luckysheet-iconfont-xiayige
  • 下拉
    -
    #icon-xiala
    +
    #luckysheet-iconfont-xiala
  • 文本颜色
    -
    #icon-wenbenyanse
    +
    #luckysheet-iconfont-wenbenyanse
  • 上一个
    -
    #icon-shangyige
    +
    #luckysheet-iconfont-shangyige
  • 数据透视
    -
    #icon-shujutoushi
    +
    #luckysheet-iconfont-shujutoushi
  • 填充
    -
    #icon-tianchong
    +
    #luckysheet-iconfont-tianchong
  • 增加小数位
    -
    #icon-zengjiaxiaoshuwei
    +
    #luckysheet-iconfont-zengjiaxiaoshuwei
  • 编辑2
    -
    #icon-bianji2
    +
    #luckysheet-iconfont-bianji2
  • 截屏
    -
    #icon-jieping
    +
    #luckysheet-iconfont-jieping
  • 减小小数位
    -
    #icon-jianxiaoxiaoshuwei
    +
    #luckysheet-iconfont-jianxiaoxiaoshuwei
  • 菜单
    -
    #icon-caidan
    +
    #luckysheet-iconfont-caidan
  • 数据库
    -
    #icon-shujuku
    +
    #luckysheet-iconfont-shujuku
  • 无边框
    -
    #icon-wubiankuang
    +
    #luckysheet-iconfont-wubiankuang
  • 编辑
    -
    #icon-bianji
    +
    #luckysheet-iconfont-bianji
  • 清除样式
    -
    #icon-qingchuyangshi
    +
    #luckysheet-iconfont-qingchuyangshi
  • 删除
    -
    #icon-shanchu
    +
    #luckysheet-iconfont-shanchu
  • 文本居中对齐
    -
    #icon-wenbenjuzhongduiqi
    +
    #luckysheet-iconfont-wenbenjuzhongduiqi
  • 打印
    -
    #icon-dayin
    +
    #luckysheet-iconfont-dayin
  • 文本分割
    -
    #icon-wenbenfenge
    +
    #luckysheet-iconfont-wenbenfenge
  • 函数‘
    -
    #icon-hanshu
    +
    #luckysheet-iconfont-hanshu
  • 降序
    -
    #icon-jiangxu
    +
    #luckysheet-iconfont-jiangxu
  • 顶部对齐
    -
    #icon-dingbuduiqi
    +
    #luckysheet-iconfont-dingbuduiqi
  • 图片
    -
    #icon-tupian
    +
    #luckysheet-iconfont-tupian
  • 向下90
    -
    #icon-xiangxia90
    +
    #luckysheet-iconfont-xiangxia90
  • 竖排文字
    -
    #icon-shupaiwenzi
    +
    #luckysheet-iconfont-shupaiwenzi
  • 全加边框
    -
    #icon-quanjiabiankuang
    +
    #luckysheet-iconfont-quanjiabiankuang
  • 升序
    -
    #icon-shengxu
    +
    #luckysheet-iconfont-shengxu
  • 裁剪
    -
    #icon-caijian
    +
    #luckysheet-iconfont-caijian
  • 金额
    -
    #icon-jine
    +
    #luckysheet-iconfont-jine
  • 菜单1
    -
    #icon-caidan1
    +
    #luckysheet-iconfont-caidan1
  • 取消合并
    -
    #icon-quxiaohebing
    +
    #luckysheet-iconfont-quxiaohebing
  • 文本下划线
    -
    #icon-wenbenxiahuaxian
    +
    #luckysheet-iconfont-wenbenxiahuaxian
  • 上边框
    -
    #icon-shangbiankuang
    +
    #luckysheet-iconfont-shangbiankuang
  • 定位
    -
    #icon-dingwei
    +
    #luckysheet-iconfont-dingwei
  • 四周加边框
    -
    #icon-sizhoujiabiankuang
    +
    #luckysheet-iconfont-sizhoujiabiankuang
  • 侧边栏收起
    -
    #icon-cebianlanshouqi
    +
    #luckysheet-iconfont-cebianlanshouqi
  • 合并
    -
    #icon-hebing
    +
    #luckysheet-iconfont-hebing
  • 向上倾斜
    -
    #icon-xiangshangqingxie
    +
    #luckysheet-iconfont-xiangshangqingxie
  • 水平对齐
    -
    #icon-shuipingduiqi
    +
    #luckysheet-iconfont-shuipingduiqi
  • 文本删除线
    -
    #icon-wenbenshanchuxian
    +
    #luckysheet-iconfont-wenbenshanchuxian
  • 文本右对齐
    -
    #icon-wenbenyouduiqi
    +
    #luckysheet-iconfont-wenbenyouduiqi
  • 前进
    -
    #icon-qianjin
    +
    #luckysheet-iconfont-qianjin
  • 图表
    -
    #icon-tubiao
    +
    #luckysheet-iconfont-tubiao
  • 右边框
    -
    #icon-youbiankuang
    +
    #luckysheet-iconfont-youbiankuang
  • 百分号
    -
    #icon-baifenhao
    +
    #luckysheet-iconfont-baifenhao
  • 格式刷
    -
    #icon-geshishua
    +
    #luckysheet-iconfont-geshishua
  • 保存
    -
    #icon-baocun
    +
    #luckysheet-iconfont-baocun
  • 数据验证
    -
    #icon-shujuyanzheng
    +
    #luckysheet-iconfont-shujuyanzheng
  • 截断
    -
    #icon-jieduan
    +
    #luckysheet-iconfont-jieduan
  • 格式条件
    -
    #icon-geshitiaojian
    +
    #luckysheet-iconfont-geshitiaojian
  • 自动换行
    -
    #icon-zidonghuanhang
    +
    #luckysheet-iconfont-zidonghuanhang
  • 侧边栏展开
    -
    #icon-cebianlanzhankai
    +
    #luckysheet-iconfont-cebianlanzhankai
  • 筛选2
    -
    #icon-shaixuan2
    +
    #luckysheet-iconfont-shaixuan2
  • 向下倾斜
    -
    #icon-xiangxiaqingxie
    +
    #luckysheet-iconfont-xiangxiaqingxie
  • 溢出
    -
    #icon-yichu
    +
    #luckysheet-iconfont-yichu
  • 垂直合并
    -
    #icon-chuizhihebing
    +
    #luckysheet-iconfont-chuizhihebing
  • 文本分散对齐
    -
    #icon-wenbenfensanduiqi
    +
    #luckysheet-iconfont-wenbenfensanduiqi
  • 左边框
    -
    #icon-zuobiankuang
    +
    #luckysheet-iconfont-zuobiankuang
  • 分页查看
    -
    #icon-fenyechakan
    +
    #luckysheet-iconfont-fenyechakan
  • 运行
    -
    #icon-yunhang
    +
    #luckysheet-iconfont-yunhang
  • -
    #icon-lie
    +
    #luckysheet-iconfont-lie
  • 全屏
    -
    #icon-quanping
    +
    #luckysheet-iconfont-quanping
  • 筛选
    -
    #icon-shaixuan
    +
    #luckysheet-iconfont-shaixuan
  • 更新
    -
    #icon-gengxin
    +
    #luckysheet-iconfont-gengxin
  • 清除
    -
    #icon-qingchu
    +
    #luckysheet-iconfont-qingchu
  • -
    #icon-hang
    +
    #luckysheet-iconfont-hang
  • 注释
    -
    #icon-zhushi
    +
    #luckysheet-iconfont-zhushi
  • -
    #icon-jian
    +
    #luckysheet-iconfont-jian
  • 计算
    -
    #icon-jisuan
    +
    #luckysheet-iconfont-jisuan
  • -
    #icon-jia
    +
    #luckysheet-iconfont-jia
  • 底部对齐
    -
    #icon-dibuduiqi
    +
    #luckysheet-iconfont-dibuduiqi
  • 向上90
    -
    #icon-xiangshang90
    +
    #luckysheet-iconfont-xiangshang90
  • 无选装
    -
    #icon-wuxuanzhuang
    +
    #luckysheet-iconfont-wuxuanzhuang
  • 显示隐藏网格
    -
    #icon-xianshiyincangwangge
    +
    #luckysheet-iconfont-xianshiyincangwangge
  • 冻结
    -
    #icon-dongjie
    +
    #luckysheet-iconfont-dongjie
  • 文本左对齐
    -
    #icon-wenbenzuoduiqi
    +
    #luckysheet-iconfont-wenbenzuoduiqi
  • 后退
    -
    #icon-houtui
    +
    #luckysheet-iconfont-houtui
  • 水平合并
    -
    #icon-shuipinghebing
    +
    #luckysheet-iconfont-shuipinghebing
  • 下边框
    -
    #icon-xiabiankuang
    +
    #luckysheet-iconfont-xiabiankuang
  • 设置
    -
    #icon-shezhi
    +
    #luckysheet-iconfont-shezhi
diff --git a/src/assets/iconfont/iconfont.css b/src/assets/iconfont/iconfont.css index 34103a26d49858cebbc1bb6dbf88ef56f98b1fec..d76bed6978b89c399052edd3638e7b794ff46c99 100644 --- a/src/assets/iconfont/iconfont.css +++ b/src/assets/iconfont/iconfont.css @@ -1,10 +1,10 @@ @font-face {font-family: "iconfont"; - src: url('iconfont.eot?t=1603792364334'); /* IE9 */ - src: url('iconfont.eot?t=1603792364334#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), - url('iconfont.woff?t=1603792364334') format('woff'), - url('iconfont.ttf?t=1603792364334') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ - url('iconfont.svg?t=1603792364334#iconfont') format('svg'); /* iOS 4.1- */ + src: url('iconfont.eot?t=1605236775724'); /* IE9 */ + src: url('iconfont.eot?t=1605236775724#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), + url('iconfont.woff?t=1605236775724') format('woff'), + url('iconfont.ttf?t=1605236775724') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('iconfont.svg?t=1605236775724#iconfont') format('svg'); /* iOS 4.1- */ } .iconfont { @@ -15,443 +15,443 @@ -moz-osx-font-smoothing: grayscale; } -.icon-lianjie:before { +.luckysheet-iconfont-lianjie:before { content: "\e7f8"; } -.icon-dayinquyu:before { +.luckysheet-iconfont-dayinquyu:before { content: "\e7f5"; } -.icon-dayinyemianpeizhi:before { +.luckysheet-iconfont-dayinyemianpeizhi:before { content: "\e7f6"; } -.icon-dayinbiaoti:before { +.luckysheet-iconfont-dayinbiaoti:before { content: "\e7f7"; } -.icon-fenyeyulan:before { +.luckysheet-iconfont-fenyeyulan:before { content: "\e7f2"; } -.icon-putong:before { +.luckysheet-iconfont-putong:before { content: "\e7f3"; } -.icon-yemianbuju:before { +.luckysheet-iconfont-yemianbuju:before { content: "\e7f4"; } -.icon-biaogesuoding:before { +.luckysheet-iconfont-biaogesuoding:before { content: "\e7ee"; } -.icon-zhuandao1:before { +.luckysheet-iconfont-zhuandao1:before { content: "\e7f1"; } -.icon-youjiantou:before { +.luckysheet-iconfont-youjiantou:before { content: "\e7ed"; } -.icon-caidan2:before { +.luckysheet-iconfont-caidan2:before { content: "\e7ef"; } -.icon-tihuan:before { +.luckysheet-iconfont-tihuan:before { content: "\e7f0"; } -.icon-dongjie1:before { +.luckysheet-iconfont-dongjie1:before { content: "\e7e1"; } -.icon-jian1:before { +.luckysheet-iconfont-jian1:before { content: "\e7e2"; } -.icon-jia1:before { +.luckysheet-iconfont-jia1:before { content: "\e7e3"; } -.icon-yichu1:before { +.luckysheet-iconfont-yichu1:before { content: "\e7e4"; } -.icon-shengxu1:before { +.luckysheet-iconfont-shengxu1:before { content: "\e7e5"; } -.icon-neikuangxian:before { +.luckysheet-iconfont-neikuangxian:before { content: "\e7e6"; } -.icon-qingchushaixuan:before { +.luckysheet-iconfont-qingchushaixuan:before { content: "\e7e7"; } -.icon-wenbenxiangshang:before { +.luckysheet-iconfont-wenbenxiangshang:before { content: "\e7e8"; } -.icon-jiangxu1:before { +.luckysheet-iconfont-jiangxu1:before { content: "\e7e9"; } -.icon-neikuanghengxian:before { +.luckysheet-iconfont-neikuanghengxian:before { content: "\e7ea"; } -.icon-neikuangshuxian:before { +.luckysheet-iconfont-neikuangshuxian:before { content: "\e7eb"; } -.icon-zidingyipaixu:before { +.luckysheet-iconfont-zidingyipaixu:before { content: "\e7ec"; } -.icon-logo2:before { +.luckysheet-iconfont-logo2:before { content: "\e7df"; } -.icon-logo:before { +.luckysheet-iconfont-logo:before { content: "\e7e0"; } -.icon-wenbenqingxie1:before { +.luckysheet-iconfont-wenbenqingxie1:before { content: "\e7de"; } -.icon-jiacu:before { +.luckysheet-iconfont-jiacu:before { content: "\e7d9"; } -.icon-sousuo:before { +.luckysheet-iconfont-sousuo:before { content: "\e78a"; } -.icon-guanbi:before { +.luckysheet-iconfont-guanbi:before { content: "\e78b"; } -.icon-xiayige:before { +.luckysheet-iconfont-xiayige:before { content: "\e78c"; } -.icon-xiala:before { +.luckysheet-iconfont-xiala:before { content: "\e78d"; } -.icon-wenbenyanse:before { +.luckysheet-iconfont-wenbenyanse:before { content: "\e78e"; } -.icon-shangyige:before { +.luckysheet-iconfont-shangyige:before { content: "\e78f"; } -.icon-shujutoushi:before { +.luckysheet-iconfont-shujutoushi:before { content: "\e790"; } -.icon-tianchong:before { +.luckysheet-iconfont-tianchong:before { content: "\e791"; } -.icon-zengjiaxiaoshuwei:before { +.luckysheet-iconfont-zengjiaxiaoshuwei:before { content: "\e792"; } -.icon-bianji2:before { +.luckysheet-iconfont-bianji2:before { content: "\e793"; } -.icon-jieping:before { +.luckysheet-iconfont-jieping:before { content: "\e794"; } -.icon-jianxiaoxiaoshuwei:before { +.luckysheet-iconfont-jianxiaoxiaoshuwei:before { content: "\e796"; } -.icon-caidan:before { +.luckysheet-iconfont-caidan:before { content: "\e797"; } -.icon-shujuku:before { +.luckysheet-iconfont-shujuku:before { content: "\e798"; } -.icon-wubiankuang:before { +.luckysheet-iconfont-wubiankuang:before { content: "\e799"; } -.icon-bianji:before { +.luckysheet-iconfont-bianji:before { content: "\e79a"; } -.icon-qingchuyangshi:before { +.luckysheet-iconfont-qingchuyangshi:before { content: "\e79b"; } -.icon-shanchu:before { +.luckysheet-iconfont-shanchu:before { content: "\e79c"; } -.icon-wenbenjuzhongduiqi:before { +.luckysheet-iconfont-wenbenjuzhongduiqi:before { content: "\e79d"; } -.icon-dayin:before { +.luckysheet-iconfont-dayin:before { content: "\e79e"; } -.icon-wenbenfenge:before { +.luckysheet-iconfont-wenbenfenge:before { content: "\e79f"; } -.icon-hanshu:before { +.luckysheet-iconfont-hanshu:before { content: "\e7a0"; } -.icon-jiangxu:before { +.luckysheet-iconfont-jiangxu:before { content: "\e7a1"; } -.icon-dingbuduiqi:before { +.luckysheet-iconfont-dingbuduiqi:before { content: "\e7a2"; } -.icon-tupian:before { +.luckysheet-iconfont-tupian:before { content: "\e7a3"; } -.icon-xiangxia90:before { +.luckysheet-iconfont-xiangxia90:before { content: "\e7a4"; } -.icon-shupaiwenzi:before { +.luckysheet-iconfont-shupaiwenzi:before { content: "\e7a5"; } -.icon-quanjiabiankuang:before { +.luckysheet-iconfont-quanjiabiankuang:before { content: "\e7a6"; } -.icon-shengxu:before { +.luckysheet-iconfont-shengxu:before { content: "\e7a7"; } -.icon-caijian:before { +.luckysheet-iconfont-caijian:before { content: "\e7a8"; } -.icon-jine:before { +.luckysheet-iconfont-jine:before { content: "\e7a9"; } -.icon-caidan1:before { +.luckysheet-iconfont-caidan1:before { content: "\e7aa"; } -.icon-quxiaohebing:before { +.luckysheet-iconfont-quxiaohebing:before { content: "\e7ab"; } -.icon-wenbenxiahuaxian:before { +.luckysheet-iconfont-wenbenxiahuaxian:before { content: "\e7ac"; } -.icon-shangbiankuang:before { +.luckysheet-iconfont-shangbiankuang:before { content: "\e7ad"; } -.icon-dingwei:before { +.luckysheet-iconfont-dingwei:before { content: "\e7ae"; } -.icon-sizhoujiabiankuang:before { +.luckysheet-iconfont-sizhoujiabiankuang:before { content: "\e7af"; } -.icon-cebianlanshouqi:before { +.luckysheet-iconfont-cebianlanshouqi:before { content: "\e7b0"; } -.icon-hebing:before { +.luckysheet-iconfont-hebing:before { content: "\e7b1"; } -.icon-xiangshangqingxie:before { +.luckysheet-iconfont-xiangshangqingxie:before { content: "\e7b2"; } -.icon-shuipingduiqi:before { +.luckysheet-iconfont-shuipingduiqi:before { content: "\e7b3"; } -.icon-wenbenshanchuxian:before { +.luckysheet-iconfont-wenbenshanchuxian:before { content: "\e7b4"; } -.icon-wenbenyouduiqi:before { +.luckysheet-iconfont-wenbenyouduiqi:before { content: "\e7b5"; } -.icon-qianjin:before { +.luckysheet-iconfont-qianjin:before { content: "\e7b6"; } -.icon-tubiao:before { +.luckysheet-iconfont-tubiao:before { content: "\e7b7"; } -.icon-youbiankuang:before { +.luckysheet-iconfont-youbiankuang:before { content: "\e7b8"; } -.icon-baifenhao:before { +.luckysheet-iconfont-baifenhao:before { content: "\e7b9"; } -.icon-geshishua:before { +.luckysheet-iconfont-geshishua:before { content: "\e7ba"; } -.icon-baocun:before { +.luckysheet-iconfont-baocun:before { content: "\e7bb"; } -.icon-shujuyanzheng:before { +.luckysheet-iconfont-shujuyanzheng:before { content: "\e7bc"; } -.icon-jieduan:before { +.luckysheet-iconfont-jieduan:before { content: "\e7bd"; } -.icon-geshitiaojian:before { +.luckysheet-iconfont-geshitiaojian:before { content: "\e7be"; } -.icon-zidonghuanhang:before { +.luckysheet-iconfont-zidonghuanhang:before { content: "\e7bf"; } -.icon-cebianlanzhankai:before { +.luckysheet-iconfont-cebianlanzhankai:before { content: "\e7c0"; } -.icon-shaixuan2:before { +.luckysheet-iconfont-shaixuan2:before { content: "\e7c1"; } -.icon-xiangxiaqingxie:before { +.luckysheet-iconfont-xiangxiaqingxie:before { content: "\e7c2"; } -.icon-yichu:before { +.luckysheet-iconfont-yichu:before { content: "\e7c3"; } -.icon-chuizhihebing:before { +.luckysheet-iconfont-chuizhihebing:before { content: "\e7c4"; } -.icon-wenbenfensanduiqi:before { +.luckysheet-iconfont-wenbenfensanduiqi:before { content: "\e7c5"; } -.icon-zuobiankuang:before { +.luckysheet-iconfont-zuobiankuang:before { content: "\e7c6"; } -.icon-fenyechakan:before { +.luckysheet-iconfont-fenyechakan:before { content: "\e7c7"; } -.icon-yunhang:before { +.luckysheet-iconfont-yunhang:before { content: "\e7c8"; } -.icon-lie:before { +.luckysheet-iconfont-lie:before { content: "\e7c9"; } -.icon-quanping:before { +.luckysheet-iconfont-quanping:before { content: "\e7ca"; } -.icon-shaixuan:before { +.luckysheet-iconfont-shaixuan:before { content: "\e7cb"; } -.icon-gengxin:before { +.luckysheet-iconfont-gengxin:before { content: "\e7cc"; } -.icon-qingchu:before { +.luckysheet-iconfont-qingchu:before { content: "\e7cd"; } -.icon-hang:before { +.luckysheet-iconfont-hang:before { content: "\e7ce"; } -.icon-zhushi:before { +.luckysheet-iconfont-zhushi:before { content: "\e7cf"; } -.icon-jian:before { +.luckysheet-iconfont-jian:before { content: "\e7d0"; } -.icon-jisuan:before { +.luckysheet-iconfont-jisuan:before { content: "\e7d1"; } -.icon-jia:before { +.luckysheet-iconfont-jia:before { content: "\e7d2"; } -.icon-dibuduiqi:before { +.luckysheet-iconfont-dibuduiqi:before { content: "\e7d3"; } -.icon-xiangshang90:before { +.luckysheet-iconfont-xiangshang90:before { content: "\e7d4"; } -.icon-wuxuanzhuang:before { +.luckysheet-iconfont-wuxuanzhuang:before { content: "\e7d5"; } -.icon-xianshiyincangwangge:before { +.luckysheet-iconfont-xianshiyincangwangge:before { content: "\e7d6"; } -.icon-dongjie:before { +.luckysheet-iconfont-dongjie:before { content: "\e7d7"; } -.icon-wenbenzuoduiqi:before { +.luckysheet-iconfont-wenbenzuoduiqi:before { content: "\e7d8"; } -.icon-houtui:before { +.luckysheet-iconfont-houtui:before { content: "\e7da"; } -.icon-shuipinghebing:before { +.luckysheet-iconfont-shuipinghebing:before { content: "\e7db"; } -.icon-xiabiankuang:before { +.luckysheet-iconfont-xiabiankuang:before { content: "\e7dc"; } -.icon-shezhi:before { +.luckysheet-iconfont-shezhi:before { content: "\e7dd"; } diff --git a/src/assets/iconfont/iconfont.eot b/src/assets/iconfont/iconfont.eot index 1a43660ec577d9dffc1baaccf5f26ba1ade24755..7cc74131abf21b5974ddfcba7e34d2c84c9129aa 100644 Binary files a/src/assets/iconfont/iconfont.eot and b/src/assets/iconfont/iconfont.eot differ diff --git a/src/assets/iconfont/iconfont.js b/src/assets/iconfont/iconfont.js index 1c12a401d32ea56c6be73a54965104154893c4d4..803f0f592c71846b62f9ec1590270e30f5dc1282 100644 --- a/src/assets/iconfont/iconfont.js +++ b/src/assets/iconfont/iconfont.js @@ -1 +1 @@ -!function(h){var a,l,v,i,z,o,t='',M=(M=document.getElementsByTagName("script"))[M.length-1].getAttribute("data-injectcss");if(M&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(h){console&&console.log(h)}}function p(){z||(z=!0,v())}a=function(){var h,a,l,v;(v=document.createElement("div")).innerHTML=t,t=null,(l=v.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",h=l,(a=document.body).firstChild?(v=h,(l=a.firstChild).parentNode.insertBefore(v,l)):a.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(a,0):(l=function(){document.removeEventListener("DOMContentLoaded",l,!1),a()},document.addEventListener("DOMContentLoaded",l,!1)):document.attachEvent&&(v=a,i=h.document,z=!1,(o=function(){try{i.documentElement.doScroll("left")}catch(h){return void setTimeout(o,50)}p()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,p())})}(window); \ No newline at end of file +!function(h){var l,a,v,i,t,z,o='',M=(M=document.getElementsByTagName("script"))[M.length-1].getAttribute("data-injectcss");if(M&&!h.__iconfont__svg__cssinject__){h.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(h){console&&console.log(h)}}function e(){t||(t=!0,v())}l=function(){var h,l,a,v;(v=document.createElement("div")).innerHTML=o,o=null,(a=v.getElementsByTagName("svg")[0])&&(a.setAttribute("aria-hidden","true"),a.style.position="absolute",a.style.width=0,a.style.height=0,a.style.overflow="hidden",h=a,(l=document.body).firstChild?(v=h,(a=l.firstChild).parentNode.insertBefore(v,a)):l.appendChild(h))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(l,0):(a=function(){document.removeEventListener("DOMContentLoaded",a,!1),l()},document.addEventListener("DOMContentLoaded",a,!1)):document.attachEvent&&(v=l,i=h.document,t=!1,(z=function(){try{i.documentElement.doScroll("left")}catch(h){return void setTimeout(z,50)}e()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,e())})}(window); \ No newline at end of file diff --git a/src/assets/iconfont/iconfont.json b/src/assets/iconfont/iconfont.json index 141f6ae8ed357cc4d7d05760307e74c4923ee0c3..3d547f72695a324c7fcd349b8fa165f89de2a94c 100644 --- a/src/assets/iconfont/iconfont.json +++ b/src/assets/iconfont/iconfont.json @@ -2,7 +2,7 @@ "id": "1990368", "name": "lucksheet", "font_family": "iconfont", - "css_prefix_text": "icon-", + "css_prefix_text": "luckysheet-iconfont-", "description": "", "glyphs": [ { diff --git a/src/assets/iconfont/iconfont.ttf b/src/assets/iconfont/iconfont.ttf index 1bb96c99767497999c485fd63a57de95ba2e3a5f..aadcc090259eb588177c4f8ba66df4bbd0d53566 100644 Binary files a/src/assets/iconfont/iconfont.ttf and b/src/assets/iconfont/iconfont.ttf differ diff --git a/src/assets/iconfont/iconfont.woff b/src/assets/iconfont/iconfont.woff index 14357fc56d3cd4c557d3e9310a02baa474e44efc..cebb184a1ab10a674095fc93d4dc5e36779cfaf5 100644 Binary files a/src/assets/iconfont/iconfont.woff and b/src/assets/iconfont/iconfont.woff differ diff --git a/src/assets/iconfont/iconfont.woff2 b/src/assets/iconfont/iconfont.woff2 index d309dc80a2a12924edc65c35d07d8dce548830a7..6a1edbcb844d2db9a24b26e70f7b9465a82374ff 100644 Binary files a/src/assets/iconfont/iconfont.woff2 and b/src/assets/iconfont/iconfont.woff2 differ diff --git a/src/config.js b/src/config.js index 31cb7ddf21b4c9aed9708f5f92bfaaf1a1fb01a5..c5ae6a66efec84cca45b6553cf74213fd2581ac7 100644 --- a/src/config.js +++ b/src/config.js @@ -3,6 +3,7 @@ */ export default { container: "luckysheet", //容器的ID + loading:{}, //自定义loading column: 60, //空表格默认的列数量 row: 84, //空表格默认的行数据量 allowCopy: true, //是否允许拷贝 @@ -14,9 +15,9 @@ export default { pointEditUpdate: null, //编辑器表格更新函数 pointEditZoom: 1, //编辑器表格编辑时缩放比例 // menu: "undo|redo|freezenrow|freezencolumn|download|share|chart|pivot", - data: [{ "name": "Sheet1", color: "", "status": "1", "order": "0", "data": [], "config": {}, "index":0 }, { "name": "Sheet2", color: "", "status": "0", "order": "1", "data": [], "config": {}, "index":1 }, { "name": "Sheet3", color: "", "status": "0", "order": "2", "data": [], "config": {}, "index":2 }], //客户端sheet数据[shee1, sheet2, sheet3] + 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数据[sheet1, sheet2, sheet3] title: "Luckysheet Demo", //表格的名称 - userInfo: ' rabbit', //右上角的用户信息展示样式 + userInfo:false,// 右上角的用户信息展示样式,支持 1. boolean类型:false:不展示,ture:展示默认 ' rabbit' ,2. HTML模板字符串或者普通字符串,如:' Lucky'或者'用户名', 3. 对象格式,设置 userImage:用户头像地址 和 userName:用户名 4. 不设置或者设置undefined同设置false userMenuItem: [{url:"www.baidu.com", "icon":'', "name":"我的表格"}, {url:"www.baidu.com", "icon":'', "name":"退出登陆"}], //点击右上角的用户信息弹出的菜单 myFolderUrl: "www.baidu.com", //左上角<返回按钮的链接 config: {}, //表格行高、列宽、合并单元格、公式等设置 @@ -31,9 +32,9 @@ export default { allowUpdate: false, //是否允许编辑后的后台更新 functionButton: "", //右上角功能按钮,例如' ' showConfigWindowResize: true, //图表和数据透视表的配置会在右侧弹出,设置弹出后表格是否会自动缩进 - enableAddRow: true,//允许增加行 - enableAddCol: true,//允许增加列 - enablePage: false,//允许加载下一页 + enableAddRow: true,//允许添加行 + enableAddBackTop: true,//允许回到顶部 + // enablePage: false,//允许加载下一页 autoFormatw: false, //自动格式化超过4位数的数字为 亿万格式 例:true or "true" or "TRUE" accuracy: undefined, //设置传输来的数值的精确位数,小数点后n位 传参数为数字或数字字符串,例: "0" 或 0 pageInfo:{ @@ -53,18 +54,17 @@ export default { plugins: [], //plugins, e.g. ['chart'] forceCalculation:false,//强制刷新公式,公式较多会有性能问题,慎用 rowHeaderWidth: 46, - columeHeaderHeight: 20, + columnHeaderHeight: 20, defaultColWidth:73, defaultRowHeight:19, defaultFontSize:10, - - showRowBar:true, //是否显示行号区域 - showColumnBar:true, //是否显示列号区域 + limitSheetNameLength:true, //是否限制工作表名的长度 + defaultSheetNameMaxLength:31, //默认工作表名称的最大长度 sheetFormulaBar:true, //是否显示公式栏 showtoolbarConfig:{}, //自定义工具栏 showsheetbarConfig:{}, //自定义底部sheet页 showstatisticBarConfig:{}, //自定义计数栏 - sheetBottomConfig:{}, //自定义添加行和回到顶部 cellRightClickConfig:{}, //自定义单元格右键菜单 sheetRightClickConfig:{}, //自定义底部sheet页右击菜单 -} \ No newline at end of file + imageUpdateMethodConfig:{}, //自定义图片同步方式 +} diff --git a/src/controllers/alternateformat.js b/src/controllers/alternateformat.js index da15a7471cd3631e6eb97c2b9d5a56dd82b59a17..5c0cf8f761e57e2435112a4c35d346490c7c3a8d 100644 --- a/src/controllers/alternateformat.js +++ b/src/controllers/alternateformat.js @@ -1205,7 +1205,7 @@ const alternateformat = { }, ref: function(historyRules, currentRules){ if (Store.clearjfundo) { - Store.jfundo = []; + Store.jfundo.length = 0; let redo = {}; redo["type"] = "updateAF"; diff --git a/src/controllers/cellDatePickerCtrl.js b/src/controllers/cellDatePickerCtrl.js index 41089334d9efc8d35af6229f6dabb94554addcb3..53a4eba46c2660dd616fef6add392d0594b49dc5 100644 --- a/src/controllers/cellDatePickerCtrl.js +++ b/src/controllers/cellDatePickerCtrl.js @@ -1,19 +1,53 @@ import menuButton from './menuButton'; import formula from '../global/formula'; import Store from '../store'; +import flatpickr from 'flatpickr' +import dayjs from "dayjs"; +import { update, datenum_local } from '../global/format'; +import { setCellValue, setCellFormat } from '../global/api'; + +const fitFormat = (formatStr) => { + let dateFormat = formatStr.replace(/y/g, 'Y'); + dateFormat = dateFormat.replace(/d/g, 'D'); + dateFormat = dateFormat.replace(/h/g, 'H'); + + dateFormat = dateFormat.replace(/上午\/下午/g, 'A'); + dateFormat = dateFormat.replace(/上午/g, 'A'); + dateFormat = dateFormat.replace(/下午/g, 'A'); + + dateFormat = dateFormat.replace(/AM\/PM/g, 'A'); + dateFormat = dateFormat.replace(/AM/g, 'A'); + dateFormat = dateFormat.replace(/PM/g, 'A'); + dateFormat = dateFormat.replace(/\"/g, ''); + + if (dateFormat.includes('A')) { + dateFormat = dateFormat.replace(/H/g, 'h'); + } + return dateFormat +} const cellDatePickerCtrl = { - cellFocus: function(r, c, value){ + cellFocus: function (r, c, cell) { let row = Store.visibledatarow[r], row_pre = r == 0 ? 0 : Store.visibledatarow[r - 1]; let col = Store.visibledatacolumn[c], col_pre = c == 0 ? 0 : Store.visibledatacolumn[c - 1]; let margeset = menuButton.mergeborer(Store.flowdata, r, c); - if(!!margeset){ + let type = cell.ct.fa || 'YYYY-MM-DD'; + let defaultDate = update('yyyy-MM-dd hh:mm:ss', cell.v); + let dateFormat = fitFormat(type); + let enableTime = false; + let noCalendar = false; + let enableSeconds = false; + let time_24hr = true; + let hasChineseTime = false; + + + if (!!margeset) { row = margeset.row[1]; row_pre = margeset.row[0]; - + col = margeset.column[1]; col_pre = margeset.column[0]; } @@ -25,17 +59,57 @@ const cellDatePickerCtrl = { top: row_pre }) - $("#cellDatePickerBtn").daterangepicker({ - singleDatePicker: true, - startDate: moment(value), - endDate: moment(value) - }, function(start) { - $("#luckysheet-rich-text-editor").html(start.format('YYYY-MM-DD')); - formula.updatecell(Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[1]); - }) + if (/[上午下午]/.test(type)) { + hasChineseTime = true + } + if (/[Hhms]/.test(dateFormat)) { + enableTime = true; + } + if (!/[YMD]/.test(dateFormat)) { + noCalendar = true; + } + if (/s/.test(dateFormat)) { + enableSeconds = true; + } + if (/A/.test(dateFormat)) { + time_24hr = false; + } + + const fp = flatpickr('#luckysheet-input-box', { + allowInput: false, + noCalendar, + enableSeconds, + enableTime, + dateFormat, + time_24hr, + defaultDate, + onClose() { + setTimeout(() => { + fp.destroy() + }, 0); + }, + parseDate: (datestr, format) => { + return dayjs(datestr).toDate(); + }, + formatDate: (date, format, locale) => { + if (hasChineseTime) { + return dayjs(date).format(format).replace('AM', '上午').replace('PM', '下午') + } + return dayjs(date).format(format); + }, + onChange: function (selectedDates, dateStr) { + let currentVal = datenum_local(new Date(selectedDates)) + $("#luckysheet-rich-text-editor").html(dateStr); + setCellValue(r, c, currentVal, { isRefresh: false }) + setCellFormat(r, c, 'ct', cell.ct) + if (!enableTime) { + formula.updatecell(Store.luckysheetCellUpdate[0], Store.luckysheetCellUpdate[1]); + } + } + }); - $("#cellDatePickerBtn").click(); + $("#luckysheet-input-box").click(); }, } -export default cellDatePickerCtrl; \ No newline at end of file +export default cellDatePickerCtrl; diff --git a/src/controllers/conditionformat.js b/src/controllers/conditionformat.js index f39db53e80ee9a71628835d820b28c7c60d87d00..90f9e1511638e56912520ecdc90d1b9794887409 100644 --- a/src/controllers/conditionformat.js +++ b/src/controllers/conditionformat.js @@ -13,6 +13,7 @@ import sheetmanage from './sheetmanage'; import locale from '../locale/locale'; import {checkProtectionFormatCells} from './protection'; import Store from '../store'; +import dayjs from 'dayjs' //条件格式 const conditionformat = { @@ -23,25 +24,29 @@ const conditionformat = { return `
- + ${conditionformat_Text.ruleTypeItem1}
- + ${conditionformat_Text.ruleTypeItem2}
- + ${conditionformat_Text.ruleTypeItem3}
- + ${conditionformat_Text.ruleTypeItem4}
- + ${conditionformat_Text.ruleTypeItem5}
+
+ + ${conditionformat_Text.ruleTypeItem6} +
`; }, textCellColorHtml: function(){ @@ -83,10 +88,10 @@ const conditionformat = { { "format": ["rgb(99, 190, 123)", "rgb(252, 252, 255)", "rgb(248, 105, 107)"] }, //绿-白-红色阶 { "format": ["rgb(248, 105, 107)", "rgb(252, 252, 255)", "rgb(99, 190, 123)"] }, //红-白-绿色阶 - + { "format": ["rgb(90, 138, 198)", "rgb(252, 252, 255)", "rgb(248, 105, 107)"] }, //蓝-白-红色阶 { "format": ["rgb(248, 105, 107)", "rgb(252, 252, 255)", "rgb(90, 138, 198)"] }, //红-白-蓝色阶 - + { "format": ["rgb(252, 252, 255)", "rgb(248, 105, 107)"] }, //白-红色阶 { "format": ["rgb(248, 105, 107)", "rgb(252, 252, 255)"] }, //红-白色阶 @@ -114,11 +119,11 @@ const conditionformat = { if(!checkProtectionFormatCells(Store.currentSheetIndex)){ return; } - + //保存之前的规则 let fileH = $.extend(true, [], Store.luckysheetfile); let historyRules = _this.getHistoryRules(fileH); - + //保存当前的规则 let fileClone = $.extend(true, [], _this.fileClone); for(let c = 0; c < fileClone.length; c++){ @@ -128,10 +133,10 @@ const conditionformat = { let fileC = $.extend(true, [], Store.luckysheetfile); let currentRules = _this.getCurrentRules(fileC); - + //刷新一次表格 _this.ref(historyRules, currentRules); - + //隐藏一些dom $("#luckysheet-modal-dialog-mask").hide(); $("#luckysheet-administerRule-dialog").hide(); @@ -171,28 +176,28 @@ const conditionformat = { let r1 = range[s].row[0], r2 = range[s].row[1]; let c1 = range[s].column[0], c2 = range[s].column[1]; - let row = Store.visibledatarow[r2], + let row = Store.visibledatarow[r2], row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1]; - let col = Store.visibledatacolumn[c2], + let col = Store.visibledatacolumn[c2], col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1]; - _this.selectRange.push({ - "left": col_pre, - "width": col - col_pre - 1, - "top": row_pre, - "height": row - row_pre - 1, - "left_move": col_pre, - "width_move": col - col_pre - 1, - "top_move": row_pre, - "height_move": row - row_pre - 1, - "row": [r1, r2], - "column": [c1, c2], - "row_focus": r1, - "column_focus": c1 + _this.selectRange.push({ + "left": col_pre, + "width": col - col_pre - 1, + "top": row_pre, + "height": row - row_pre - 1, + "left_move": col_pre, + "width_move": col - col_pre - 1, + "top_move": row_pre, + "height_move": row - row_pre - 1, + "row": [r1, r2], + "column": [c1, c2], + "row_focus": r1, + "column_focus": c1 }); } } - + selectionCopyShow(_this.selectRange); }); $(document).off("click.CFmultiRangeConfirm").on("click.CFmultiRangeConfirm", "#luckysheet-multiRange-dialog-confirm", function(){ @@ -204,7 +209,7 @@ const conditionformat = { let sheetIndex = $("#luckysheet-administerRule-dialog .chooseSheet option:selected").val(); _this.fileClone[getSheetIndex(sheetIndex)]["luckysheet_conditionformat_save"][dataItem].cellrange = _this.getRangeByTxt(v); - + $("#luckysheet-modal-dialog-mask").show(); $("#luckysheet-administerRule-dialog").show(); @@ -223,14 +228,14 @@ const conditionformat = { let range = []; selectionCopyShow(range); }); - + // 新建规则 $(document).off("click.CFnewConditionRule").on("click.CFnewConditionRule", "#newConditionRule", function(){ let sheetIndex = $("#luckysheet-administerRule-dialog .chooseSheet option:selected").val(); if(!checkProtectionFormatCells(sheetIndex)){ return; } - + if(Store.luckysheet_select_save.length == 0){ if(isEditMode()){ alert(conditionformat_Text.pleaseSelectRange); @@ -240,19 +245,19 @@ const conditionformat = { } return; } - + _this.newConditionRuleDialog(1); }); $(document).off("click.CFnewConditionRuleConfirm").on("click.CFnewConditionRuleConfirm", "#luckysheet-newConditionRule-dialog-confirm", function(){ - + if(!checkProtectionFormatCells(Store.currentSheetIndex)){ return; } - + let index = $("#luckysheet-newConditionRule-dialog .ruleTypeItem.on").index(); let type1 = $("#luckysheet-newConditionRule-dialog #type1 option:selected").val(); let type2 = $("#luckysheet-newConditionRule-dialog ." + type1 + "Box #type2 option:selected").val(); - + let format, rule; if(index == 0){ if(type1 == "dataBar"){ //数据条 @@ -266,8 +271,8 @@ const conditionformat = { } rule = { - "type": "dataBar", - "cellrange": $.extend(true, [], Store.luckysheet_select_save), + "type": "dataBar", + "cellrange": $.extend(true, [], Store.luckysheet_select_save), "format": format }; } @@ -284,8 +289,8 @@ const conditionformat = { } rule = { - "type": "colorGradation", - "cellrange": $.extend(true, [], Store.luckysheet_select_save), + "type": "colorGradation", + "cellrange": $.extend(true, [], Store.luckysheet_select_save), "format": format }; } @@ -295,14 +300,14 @@ const conditionformat = { let top = $(this).parents("#luckysheet-newConditionRule-dialog").find(".iconsBox .model").attr("data-top"); format = { - "len": len, + "len": len, "leftMin": leftMin, "top": top }; rule = { - "type": "icons", - "cellrange": $.extend(true, [], Store.luckysheet_select_save), + "type": "icons", + "cellrange": $.extend(true, [], Store.luckysheet_select_save), "format": format }; } @@ -330,7 +335,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v1 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr1[0].row, "column": rangeArr1[0].column }); conditionValue.push(v1); } @@ -360,7 +365,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v2 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr2[0].row, "column": rangeArr2[0].column }); conditionValue.push(v2); } @@ -395,7 +400,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column }); conditionValue.push(v); } @@ -433,7 +438,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column }); conditionValue.push(v); } @@ -462,7 +467,7 @@ const conditionformat = { _this.infoDialog(conditionformat_Text.pleaseSelectADate, ""); return; } - + conditionValue.push(v); } } @@ -492,7 +497,7 @@ const conditionformat = { _this.infoDialog(conditionformat_Text.pleaseEnterInteger, ""); return; } - + conditionValue.push(parseInt(v)); } else if(index == 3){ //平均值 @@ -509,6 +514,19 @@ const conditionformat = { conditionName = "duplicateValue"; conditionValue.push(type1); } + else if(index == 5){ //公式 + conditionName = "formula"; + + //条件值 + let v = $("#luckysheet-newConditionRule-dialog #formulaConditionVal input").val().trim(); + + if(v == ""){ + _this.infoDialog("Condition value cannot be empty!", ""); + return; + } + + conditionValue.push(v); + } //格式颜色 let textcolor; @@ -516,44 +534,44 @@ const conditionformat = { textcolor = $("#luckysheet-newConditionRule-dialog #textcolorshow").spectrum("get").toHexString(); } else{ - textcolor = null; + textcolor = null; } - + let cellcolor; if($("#luckysheet-newConditionRule-dialog #checkCellColor").is(":checked")){ cellcolor = $("#luckysheet-newConditionRule-dialog #cellcolorshow").spectrum("get").toHexString(); } else{ - cellcolor = null; + cellcolor = null; } format = { - "textColor": textcolor, + "textColor": textcolor, "cellColor": cellcolor }; rule = { "type": "default", "cellrange": $.extend(true, [], Store.luckysheet_select_save), - "format": format, - "conditionName": conditionName, - "conditionRange": conditionRange, - "conditionValue": conditionValue + "format": format, + "conditionName": conditionName, + "conditionRange": conditionRange, + "conditionValue": conditionValue }; } $("#luckysheet-newConditionRule-dialog").hide(); - + //新建规则的入口 let source = $(this).attr("data-source"); - + if(source == 0){ $("#luckysheet-modal-dialog-mask").hide(); - + //保存之前的规则 let fileH = $.extend(true, [], Store.luckysheetfile); let historyRules = _this.getHistoryRules(fileH); - + //保存当前的规则 let ruleArr = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"] == undefined ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"]; ruleArr.push(rule); @@ -561,7 +579,7 @@ const conditionformat = { let fileC = $.extend(true, [], Store.luckysheetfile); let currentRules = _this.getCurrentRules(fileC); - + //刷新一次表格 _this.ref(historyRules, currentRules); @@ -575,7 +593,7 @@ const conditionformat = { let ruleArr = !!_this.fileClone[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"] ? _this.fileClone[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"] : []; ruleArr.push(rule); _this.fileClone[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"] = ruleArr; - + //新建规则隐藏,管理规则显示 _this.administerRuleDialog(); } @@ -589,25 +607,25 @@ const conditionformat = { if(source == 1){ $("#luckysheet-administerRule-dialog").show(); } - + //新建规则隐藏 $("#luckysheet-newConditionRule-dialog").hide(); - + //隐藏虚线框 $("#luckysheet-formula-functionrange-select").hide(); $("#luckysheet-row-count-show").hide(); - $("#luckysheet-column-count-show").hide(); + $("#luckysheet-column-count-show").hide(); }); - + // 编辑规则 $(document).off("click.CFeditorConditionRule").on("click.CFeditorConditionRule", "#editorConditionRule", function(){ let sheetIndex = $("#luckysheet-administerRule-dialog .chooseSheet option:selected").val(); - + if(!checkProtectionFormatCells(sheetIndex)){ return; } - + let itemIndex = $("#luckysheet-administerRule-dialog .ruleList .listBox .item.on").attr("data-item"); let rule = { @@ -624,7 +642,7 @@ const conditionformat = { let type2 = $("#luckysheet-editorConditionRule-dialog ." + type1 + "Box #type2 option:selected").val(); let cellrange = _this.editorRule["data"].cellrange; - + let format, rule; if(index == 0){ if(type1 == "dataBar"){ //数据条 @@ -638,8 +656,8 @@ const conditionformat = { } rule = { - "type": "dataBar", - "cellrange": cellrange, + "type": "dataBar", + "cellrange": cellrange, "format": format }; } @@ -656,8 +674,8 @@ const conditionformat = { } rule = { - "type": "colorGradation", - "cellrange": cellrange, + "type": "colorGradation", + "cellrange": cellrange, "format": format }; } @@ -667,14 +685,14 @@ const conditionformat = { let top = $(this).parents("#luckysheet-editorConditionRule-dialog").find(".iconsBox .model").attr("data-top"); format = { - "len": len, + "len": len, "leftMin": leftMin, "top": top }; rule = { - "type": "icons", - "cellrange": cellrange, + "type": "icons", + "cellrange": cellrange, "format": format }; } @@ -702,7 +720,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v1 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr1[0].row, "column": rangeArr1[0].column }); conditionValue.push(v1); } @@ -732,7 +750,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v2 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr2[0].row, "column": rangeArr2[0].column }); conditionValue.push(v2); } @@ -767,7 +785,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column }); conditionValue.push(v); } @@ -805,7 +823,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column }); conditionValue.push(v); } @@ -834,7 +852,7 @@ const conditionformat = { _this.infoDialog(conditionformat_Text.pleaseSelectADate, ""); return; } - + conditionValue.push(v); } } @@ -864,7 +882,7 @@ const conditionformat = { _this.infoDialog(conditionformat_Text.pleaseEnterInteger, ""); return; } - + conditionValue.push(v); } else if(index == 3){ //平均值 @@ -881,6 +899,19 @@ const conditionformat = { conditionName = "duplicateValue"; conditionValue.push(type1); } + else if(index == 5){ //公式 + conditionName = "formula"; + + //条件值 + let v = $("#luckysheet-editorConditionRule-dialog #formulaConditionVal input").val().trim(); + console.log(v) + if(v == ""){ + _this.infoDialog("Condition value cannot be empty!", ""); + return; + } + + conditionValue.push(v); + } //格式颜色 let textcolor; @@ -888,29 +919,29 @@ const conditionformat = { textcolor = $("#luckysheet-editorConditionRule-dialog #textcolorshow").spectrum("get").toHexString(); } else{ - textcolor = null; + textcolor = null; } - + let cellcolor; if($("#luckysheet-editorConditionRule-dialog #checkCellColor").is(":checked")){ cellcolor = $("#luckysheet-editorConditionRule-dialog #cellcolorshow").spectrum("get").toHexString(); } else{ - cellcolor = null; + cellcolor = null; } format = { - "textColor": textcolor, + "textColor": textcolor, "cellColor": cellcolor }; rule = { "type": "default", "cellrange": cellrange, - "format": format, - "conditionName": conditionName, - "conditionRange": conditionRange, - "conditionValue": conditionValue + "format": format, + "conditionName": conditionName, + "conditionRange": conditionRange, + "conditionValue": conditionValue }; } @@ -918,7 +949,7 @@ const conditionformat = { let sheetIndex = _this.editorRule["sheetIndex"]; let itemIndex = _this.editorRule["itemIndex"]; _this.fileClone[getSheetIndex(sheetIndex)]["luckysheet_conditionformat_save"][itemIndex] = rule; - + //编辑规则隐藏,管理规则显示 $("#luckysheet-editorConditionRule-dialog").hide(); _this.administerRuleDialog(); @@ -936,7 +967,7 @@ const conditionformat = { // 新建规则、编辑规则 类型切换 $(document).off("click.CFnewEditorRuleItem").on("click.CFnewEditorRuleItem", ".luckysheet-newEditorRule-dialog .ruleTypeItem", function(){ $(this).addClass("on").siblings().removeClass("on"); - + let index = $(this).index(); $(this).parents(".luckysheet-newEditorRule-dialog").find(".ruleExplainBox").html(_this.getRuleExplain(index)); @@ -956,7 +987,7 @@ const conditionformat = { $(document).off("change.CFnewEditorRuleType2").on("change.CFnewEditorRuleType2", ".luckysheet-newEditorRule-dialog #type2", function(){ let type1 = $(this).parents(".luckysheet-newEditorRule-dialog").find("#type1 option:selected").val(); - if(type1 == "colorGradation"){ + if(type1 == "colorGradation"){ let type2 = $(this).find("option:selected").val(); if(type2 == "threeColor"){ @@ -1001,34 +1032,34 @@ const conditionformat = { // 删除规则 $(document).off("click.CFdeleteConditionRule").on("click.CFdeleteConditionRule", "#deleteConditionRule", function(){ let sheetIndex = $("#luckysheet-administerRule-dialog .chooseSheet option:selected").val(); - + if(!checkProtectionFormatCells(sheetIndex)){ return; } - + let itemIndex = $("#luckysheet-administerRule-dialog .ruleList .listBox .item.on").attr("data-item"); _this.fileClone[getSheetIndex(sheetIndex)]["luckysheet_conditionformat_save"].splice(itemIndex, 1); _this.administerRuleDialog(); }); - + // 规则子菜单弹出层 点击确定修改样式 $(document).off("click.CFdefault").on("click.CFdefault", "#luckysheet-conditionformat-dialog-confirm", function(){ - + if(!checkProtectionFormatCells(Store.currentSheetIndex)){ return; } - + //条件名称 let conditionName = $("#luckysheet-conditionformat-dialog .box").attr("data-itemvalue"); - + //条件单元格 let conditionRange = []; - + //条件值 let conditionValue = []; if(conditionName == "greaterThan" || conditionName == "lessThan" || conditionName == "equal" || conditionName == "textContains"){ let v = $("#luckysheet-conditionformat-dialog #conditionVal").val().trim(); - + //条件值是否是选区 let rangeArr = _this.getRangeByTxt(v); if(rangeArr.length > 1){ @@ -1041,7 +1072,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column }); conditionValue.push(v); } @@ -1076,7 +1107,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v1 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr1[0].row, "column": rangeArr1[0].column }); conditionValue.push(v1); } @@ -1106,7 +1137,7 @@ const conditionformat = { if(r1 == r2 && c1 == c2){ v2 = getcellvalue(r1, c1, Store.flowdata); - + conditionRange.push({ "row": rangeArr2[0].row, "column": rangeArr2[0].column }); conditionValue.push(v2); } @@ -1161,7 +1192,7 @@ const conditionformat = { textcolor = $("#textcolorshow").spectrum("get").toHexString(); } else{ - textcolor = null; + textcolor = null; } let cellcolor; @@ -1169,24 +1200,24 @@ const conditionformat = { cellcolor = $("#cellcolorshow").spectrum("get").toHexString(); } else{ - cellcolor = null; + cellcolor = null; } //保存之前的规则 let fileH = $.extend(true, [], Store.luckysheetfile); let historyRules = _this.getHistoryRules(fileH); - + //保存当前的规则 let rule = { "type": "default", "cellrange": $.extend(true, [], Store.luckysheet_select_save), "format": { - "textColor": textcolor, + "textColor": textcolor, "cellColor": cellcolor - }, - "conditionName": conditionName, - "conditionRange": conditionRange, - "conditionValue": conditionValue + }, + "conditionName": conditionName, + "conditionRange": conditionRange, + "conditionValue": conditionValue }; let ruleArr = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"] == undefined ? [] : Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]["luckysheet_conditionformat_save"]; ruleArr.push(rule); @@ -1194,10 +1225,10 @@ const conditionformat = { let fileC = $.extend(true, [], Store.luckysheetfile); let currentRules = _this.getCurrentRules(fileC); - + //刷新一次表格 _this.ref(historyRules, currentRules); - + //隐藏一些dom $("#luckysheet-modal-dialog-mask").hide(); $("#luckysheet-conditionformat-dialog").hide(); @@ -1207,7 +1238,7 @@ const conditionformat = { server.saveParam("all", Store.currentSheetIndex, ruleArr, { "k": "luckysheet_conditionformat_save" }); } }); - + // 图标集弹出层 选择 $(document).off("click.CFicons").on("click.CFicons", "#luckysheet-CFicons-dialog .item", function(){ $("#luckysheet-modal-dialog-mask").hide(); @@ -1216,7 +1247,7 @@ const conditionformat = { if(Store.luckysheet_select_save.length > 0){ let cellrange = $.extend(true, [], Store.luckysheet_select_save); let format = { - "len": $(this).attr("data-len"), + "len": $(this).attr("data-len"), "leftMin": $(this).attr("data-leftMin"), "top": $(this).attr("data-top") } @@ -1224,32 +1255,45 @@ const conditionformat = { _this.updateItem("icons", cellrange, format); } }); - + // 选择单元格 $(document).on("click", ".range .fa-table", function(){ let id = $(this).parents(".luckysheet-modal-dialog").attr("id"); $("#" + id).hide(); //入口 let source; + if(id == "luckysheet-conditionformat-dialog"){ - if($(this).siblings("input").attr("id") == "conditionVal"){ + let $id = $(this).siblings("input").attr("id"); + + if($id == "conditionVal"){ source = "0_1"; } else{ - source = "0_2"; + source = "0_2"; } } else if(id == "luckysheet-newConditionRule-dialog"){ - if($(this).parents(".range").attr("id") == "conditionVal"){ - source = "1_1"; + let $id = $(this).parents(".range").attr("id"); + + if($id == "formulaConditionVal"){ + source = "1_0"; + } + else if($id == "conditionVal"){ + source = "1_1"; } else{ source = "1_2"; } } else if(id == "luckysheet-editorConditionRule-dialog"){ - if($(this).parents(".range").attr("id") == "conditionVal"){ - source = "2_1"; + let $id = $(this).parents(".range").attr("id"); + + if($id == "formulaConditionVal"){ + source = "2_0"; + } + else if($id == "conditionVal"){ + source = "2_1"; } else{ source = "2_2"; @@ -1267,7 +1311,7 @@ const conditionformat = { let source = $(this).attr("data-source"); let v = $(this).parents("#luckysheet-singleRange-dialog").find("input").val(); - + if(source == "0_1"){ $("#luckysheet-conditionformat-dialog").show(); $("#luckysheet-conditionformat-dialog #conditionVal").val(v); @@ -1276,6 +1320,10 @@ const conditionformat = { $("#luckysheet-conditionformat-dialog").show(); $("#luckysheet-conditionformat-dialog #conditionVal2").val(v); } + else if(source == "1_0"){ + $("#luckysheet-newConditionRule-dialog").show(); + $("#luckysheet-newConditionRule-dialog #formulaConditionVal input").val(v); + } else if(source == "1_1"){ $("#luckysheet-newConditionRule-dialog").show(); $("#luckysheet-newConditionRule-dialog #conditionVal input").val(v); @@ -1284,6 +1332,10 @@ const conditionformat = { $("#luckysheet-newConditionRule-dialog").show(); $("#luckysheet-newConditionRule-dialog #conditionVal2 input").val(v); } + else if(source == "2_0"){ + $("#luckysheet-editorConditionRule-dialog").show(); + $("#luckysheet-editorConditionRule-dialog #formulaConditionVal input").val(v); + } else if(source == "2_1"){ $("#luckysheet-editorConditionRule-dialog").show(); $("#luckysheet-editorConditionRule-dialog #conditionVal input").val(v); @@ -1304,21 +1356,21 @@ const conditionformat = { if(source == "0_1" || source == "0_2"){ $("#luckysheet-conditionformat-dialog").show(); } - else if(source == "1_1" || source == "1_2"){ + else if(source == "1_0" || source == "1_1" || source == "1_2"){ $("#luckysheet-newConditionRule-dialog").show(); } - else if(source == "2_1" || source == "2_2"){ + else if(source == "2_0" || source == "2_1" || source == "2_2"){ $("#luckysheet-editorConditionRule-dialog").show(); } let range = []; selectionCopyShow(range); }); - + // 弹出层右上角关闭按钮 $(document).on("click", ".luckysheet-modal-dialog-title-close", function(){ let id = $(this).parents(".luckysheet-modal-dialog").attr("id"); - + //新建规则弹出层 if(id == "luckysheet-newConditionRule-dialog"){ let source = $("#" + id).find("#luckysheet-newConditionRule-dialog-close").attr("data-source"); @@ -1327,7 +1379,7 @@ const conditionformat = { $("#luckysheet-administerRule-dialog").show(); } } - + //编辑规则弹出层 if(id == "luckysheet-editorConditionRule-dialog"){ $("#luckysheet-administerRule-dialog").show(); @@ -1379,26 +1431,26 @@ const conditionformat = { const conditionformat_Text = locale().conditionformat; - $("body").append(replaceHtml(modelHTML, { - "id": "luckysheet-singleRange-dialog", - "addclass": "luckysheet-singleRange-dialog", - "title": conditionformat_Text.selectCell, - "content": ``, + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-singleRange-dialog", + "addclass": "luckysheet-singleRange-dialog", + "title": conditionformat_Text.selectCell, + "content": ``, "botton": ` - `, - "style": "z-index:100003" + `, + "style": "z-index:100003" })); let $t = $("#luckysheet-singleRange-dialog") .find(".luckysheet-modal-dialog-content") .css("min-width", 300) - .end(), - myh = $t.outerHeight(), + .end(), + myh = $t.outerHeight(), myw = $t.outerWidth(); let winw = $(window).width(), winh = $(window).height(); let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); - $("#luckysheet-singleRange-dialog").css({ - "left": (winw + scrollLeft - myw) / 2, - "top": (winh + scrollTop - myh) / 3 + $("#luckysheet-singleRange-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 }).show(); }, multiRangeDialog: function(dataItem, value){ @@ -1409,26 +1461,26 @@ const conditionformat = { const conditionformat_Text = locale().conditionformat; - $("body").append(replaceHtml(modelHTML, { - "id": "luckysheet-multiRange-dialog", - "addclass": "luckysheet-multiRange-dialog", - "title": conditionformat_Text.selectRange, - "content": ``, + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-multiRange-dialog", + "addclass": "luckysheet-multiRange-dialog", + "title": conditionformat_Text.selectRange, + "content": ``, "botton": ` - `, - "style": "z-index:100003" + `, + "style": "z-index:100003" })); let $t = $("#luckysheet-multiRange-dialog") .find(".luckysheet-modal-dialog-content") .css("min-width", 300) - .end(), - myh = $t.outerHeight(), + .end(), + myh = $t.outerHeight(), myw = $t.outerWidth(); let winw = $(window).width(), winh = $(window).height(); let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); - $("#luckysheet-multiRange-dialog").css({ - "left": (winw + scrollLeft - myw) / 2, - "top": (winh + scrollTop - myh) / 3 + $("#luckysheet-multiRange-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 }).show(); selectionCopyShow(_this.getRangeByTxt(value)); @@ -1440,7 +1492,7 @@ const conditionformat = { for(let s = 0; s < range.length; s++){ let r1 = range[s].row[0], r2 = range[s].row[1]; let c1 = range[s].column[0], c2 = range[s].column[1]; - + txt.push(getRangetxt(Store.currentSheetIndex, { "row": [r1, r2], "column": [c1, c2] }, Store.currentSheetIndex)); } @@ -1460,7 +1512,7 @@ const conditionformat = { } else{ range = []; - break; + break; } } } @@ -1469,7 +1521,6 @@ const conditionformat = { range.push(formula.getcellrange(txt)); } } - return range; }, colorSelectInit: function(){ @@ -1520,31 +1571,31 @@ const conditionformat = { const conditionformat_Text = locale().conditionformat; - $("body").append(replaceHtml(modelHTML, { - "id": "luckysheet-conditionformat-dialog", - "addclass": "luckysheet-conditionformat-dialog", - "title": title, - "content": content, + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-conditionformat-dialog", + "addclass": "luckysheet-conditionformat-dialog", + "title": title, + "content": content, "botton": ` - `, - "style": "z-index:100003" + `, + "style": "z-index:9999" })); let $t = $("#luckysheet-conditionformat-dialog") .find(".luckysheet-modal-dialog-content") .css("min-width", 300) - .end(), - myh = $t.outerHeight(), + .end(), + myh = $t.outerHeight(), myw = $t.outerWidth(); let winw = $(window).width(), winh = $(window).height(); let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); - $("#luckysheet-conditionformat-dialog").css({ - "left": (winw + scrollLeft - myw) / 2, - "top": (winh + scrollTop - myh) / 3 + $("#luckysheet-conditionformat-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 }).show(); - + _this.init(); _this.colorSelectInit(); - + if(title == locale().conditionformat.conditionformat_occurrenceDate){ _this.daterangeInit("luckysheet-conditionformat-dialog"); } @@ -1611,25 +1662,25 @@ const conditionformat = { `; - $("body").append(replaceHtml(modelHTML, { - "id": "luckysheet-CFicons-dialog", - "addclass": "luckysheet-CFicons-dialog", - "title": conditionformat_Text.icons, - "content": content, - "botton": ``, - "style": "z-index:100003" + $("body").append(replaceHtml(modelHTML, { + "id": "luckysheet-CFicons-dialog", + "addclass": "luckysheet-CFicons-dialog", + "title": conditionformat_Text.icons, + "content": content, + "botton": ``, + "style": "z-index:100003" })); let $t = $("#luckysheet-CFicons-dialog") .find(".luckysheet-modal-dialog-content") .css("min-width", 400) - .end(), - myh = $t.outerHeight(), + .end(), + myh = $t.outerHeight(), myw = $t.outerWidth(); let winw = $(window).width(), winh = $(window).height(); let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); - $("#luckysheet-CFicons-dialog").css({ - "left": (winw + scrollLeft - myw) / 2, - "top": (winh + scrollTop - myh) / 3 + $("#luckysheet-CFicons-dialog").css({ + "left": (winw + scrollLeft - myw) / 2, + "top": (winh + scrollTop - myh) / 3 }).show(); }, administerRuleDialog: function(){ @@ -1637,9 +1688,9 @@ const conditionformat = { $("#luckysheet-administerRule-dialog").remove(); const conditionformat_Text = locale().conditionformat; - + //工作表 - let opHtml = ''; + let opHtml = ''; for(let j = 0; j < Store.luckysheetfile.length; j++){ if(Store.luckysheetfile[j].status == "1"){ opHtml += `