├── .gitignore
├── README.md
├── img
├── icon.png
├── screenshot_1.png
└── screenshot_2.png
├── jsconfig.json
├── main.js
├── package-lock.json
├── package.json
└── panel
├── help.html
├── help.js
├── index.css
├── index.html
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Cocos Creator 插件:转换 excel 文件为 js 文件
2 |
3 | ---
4 |
5 | #### 如何使用
6 |
7 | 参考 [Cocos Creator 插件的安装与分享](https://docs.cocos.com/creator/manual/zh/extension/install-and-share.html)。
8 |
9 | #### 注意事项
10 | * excel 的读取路径为 `项目目录/excel/`
11 | * js 文件保存路径为 `项目目录/assets/data/`
12 | * 转换成功后,会以`同名`的 js 文件保存,请自行做好文件备份
13 | * 以`!`开头的 excel 文件会被忽略,以`!`开头的 excel 字段名同样会被忽略
14 | * excel 文件第一行为`字段名`,第二行起为`数据`
15 | * 每个 excel 文件只会解析`第一个`表格
16 | * 支持解析 `.xlsx` 的 excel 文件
17 |
18 | #### 转换格式
19 | * excel
20 |
21 | | id | name | num | object | array |
22 | | :-----: |:-----:| :-----:| :-----:| :-----:|
23 | | 0 | "名字0" | 0 | {a:1,b:2} | [0,1,2] |
24 | | 1 | "名字1" | 1 | {a:1,b:2} | [0,1,2] |
25 | | 2 | "名字2" | 2 | {a:"对象1",b:"对象1"} | ["数组1","数组2"] |
26 | | 3 | "名字3" | 3 | {a:"对象1",b:"对象1"} | ["数组1","数组2"] |
27 |
28 |
29 | * js
30 |
31 | ```javascript
32 | module.exports = [
33 | {id:0, name:"名字0", num:0, object:{a:1,b:2}, array:[0,1,2]},
34 | {id:1, name:"名字1", num:1, object:{a:1,b:2}, array:[0,1,2]},
35 | {id:2, name:"名字2", num:2, object:{a:"对象1",b:"对象1"}, array:["数组1","数组2"]},
36 | {id:3, name:"名字3", num:3, object:{a:"对象1",b:"对象1"}, array:["数组1","数组2"]},
37 | ];
38 | ```
39 |
40 | #### 截图
41 |
42 |
43 |

44 |

45 |
46 |
--------------------------------------------------------------------------------
/img/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusijie/excel2js/d198b7779fe8d591f9dcdabab90a50c42a83cbf4/img/icon.png
--------------------------------------------------------------------------------
/img/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusijie/excel2js/d198b7779fe8d591f9dcdabab90a50c42a83cbf4/img/screenshot_1.png
--------------------------------------------------------------------------------
/img/screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusijie/excel2js/d198b7779fe8d591f9dcdabab90a50c42a83cbf4/img/screenshot_2.png
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "module": "commonjs",
5 | "experimentalDecorators": true
6 | },
7 | "exclude": [
8 | "node_modules",
9 | ".vscode",
10 | ]
11 | }
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Fs = require('fire-fs');
4 | const Path = require('fire-path');
5 |
6 | module.exports = {
7 | load() {
8 | },
9 |
10 | unload() {
11 | },
12 |
13 | messages: {
14 | 'open'() {
15 | Editor.Panel.open('excel2js');
16 | },
17 |
18 | 'update-excel'(event) {
19 | let excelDir = Path.join(Editor.projectPath, 'excel');
20 | let excelArr = [];
21 | if (Fs.existsSync(excelDir)) {
22 | excelArr = Fs.readdirSync(excelDir);
23 | }
24 | if (event.reply) {
25 | event.reply(null, excelArr);
26 | }
27 | },
28 |
29 | 'convert-js'(event, excelFileInfo) {
30 | let jsDir = 'db://assets/data';
31 | if (!Editor.assetdb.exists(jsDir)) {
32 | Editor.assetdb.create(jsDir);
33 | }
34 | if (Array.isArray(excelFileInfo)) {
35 | for (let i = 0; i < excelFileInfo.length; i++) {
36 | this.convertJs(excelFileInfo[i].name);
37 | }
38 | } else {
39 | this.convertJs(excelFileInfo.name);
40 | }
41 | },
42 | },
43 |
44 | convertJs(excelFileName) {
45 | //解析excel
46 | let xlsx = Editor.require('packages://excel2js/node_modules/xlsx');
47 | let excelName = Path.join(Editor.projectPath, 'excel', excelFileName);
48 | const workbook = xlsx.readFile(excelName);
49 | const sheetNames = workbook.SheetNames;
50 | const worksheet = workbook.Sheets[sheetNames[0]];
51 | const headers = {};
52 | const data = [];
53 | const keys = Object.keys(worksheet);
54 | keys.filter(k => k[0] !== '!')// 过滤以 ! 开头的 key
55 | .forEach(k => {// 遍历所有单元格
56 | let col = k.substring(0, 1);
57 | let row = parseInt(k.substring(1));
58 | let value = worksheet[k].v;
59 | if (row === 1) {
60 | headers[col] = value;
61 | return;
62 | }
63 | if (!data[row]) {
64 | data[row] = {};
65 | }
66 | data[row][headers[col]] = value;
67 | });
68 | data.splice(0, 2);
69 |
70 | //转Array为text
71 | let jsText = 'module.exports = [\n';
72 | for (let i = 0; i < data.length; i++) {
73 | jsText += '\t{';
74 | for (let key in data[i]) {
75 | jsText += `${key}:${data[i][key]}, `;
76 | }
77 | jsText = jsText.substr(0, jsText.length - 2);
78 | jsText += '},\n';
79 | }
80 | jsText += '];';
81 |
82 | //校验js文件
83 | try {
84 | eval(jsText);
85 | } catch (error) {
86 | Editor.Ipc.sendToPanel('excel2js', 'convert-failed', excelFileName);
87 | return;
88 | }
89 |
90 | //写入js文件
91 | let excelFile = excelFileName.substr(0, excelFileName.lastIndexOf('.xlsx'));
92 | let url = `db://assets/data/${excelFile}.js`;
93 | if (Editor.assetdb.exists(url)) {
94 | Editor.assetdb.saveExists(url, jsText, (err) => {
95 | if (err) {
96 | Editor.Ipc.sendToPanel('excel2js', 'convert-failed', excelFileName);
97 | } else {
98 | Editor.Ipc.sendToPanel('excel2js', 'convert-success', excelFileName);
99 | }
100 | });
101 | } else {
102 | Editor.assetdb.create(url, jsText, (err) => {
103 | if (err) {
104 | Editor.Ipc.sendToPanel('excel2js', 'convert-failed', excelFileName);
105 | } else {
106 | Editor.Ipc.sendToPanel('excel2js', 'convert-success', excelFileName);
107 | }
108 | });
109 | }
110 | }
111 | };
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "excel2js",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "adler-32": {
8 | "version": "1.2.0",
9 | "resolved": "http://registry.npm.taobao.org/adler-32/download/adler-32-1.2.0.tgz",
10 | "integrity": "sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=",
11 | "requires": {
12 | "exit-on-epipe": "~1.0.1",
13 | "printj": "~1.1.0"
14 | }
15 | },
16 | "cfb": {
17 | "version": "1.1.0",
18 | "resolved": "http://registry.npm.taobao.org/cfb/download/cfb-1.1.0.tgz",
19 | "integrity": "sha1-RPsbMO7gFPpWM6DtXybIf9dleZo=",
20 | "requires": {
21 | "adler-32": "~1.2.0",
22 | "commander": "^2.16.0",
23 | "crc-32": "~1.2.0",
24 | "printj": "~1.1.2"
25 | }
26 | },
27 | "codepage": {
28 | "version": "1.14.0",
29 | "resolved": "http://registry.npm.taobao.org/codepage/download/codepage-1.14.0.tgz",
30 | "integrity": "sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=",
31 | "requires": {
32 | "commander": "~2.14.1",
33 | "exit-on-epipe": "~1.0.1"
34 | },
35 | "dependencies": {
36 | "commander": {
37 | "version": "2.14.1",
38 | "resolved": "http://registry.npm.taobao.org/commander/download/commander-2.14.1.tgz",
39 | "integrity": "sha1-IjUSPjevjKPGXfRbAm29NXsBuao="
40 | }
41 | }
42 | },
43 | "commander": {
44 | "version": "2.17.1",
45 | "resolved": "http://registry.npm.taobao.org/commander/download/commander-2.17.1.tgz",
46 | "integrity": "sha1-vXerfebelCBc6sxy8XFtKfIKd78="
47 | },
48 | "crc-32": {
49 | "version": "1.2.0",
50 | "resolved": "http://registry.npm.taobao.org/crc-32/download/crc-32-1.2.0.tgz",
51 | "integrity": "sha1-yy224puIUI4y2d0OwWk+e0Ghggg=",
52 | "requires": {
53 | "exit-on-epipe": "~1.0.1",
54 | "printj": "~1.1.0"
55 | }
56 | },
57 | "exit-on-epipe": {
58 | "version": "1.0.1",
59 | "resolved": "http://registry.npm.taobao.org/exit-on-epipe/download/exit-on-epipe-1.0.1.tgz",
60 | "integrity": "sha1-C92S6H1ShdJn2qgXHQ6wYVlolpI="
61 | },
62 | "frac": {
63 | "version": "1.1.2",
64 | "resolved": "http://registry.npm.taobao.org/frac/download/frac-1.1.2.tgz",
65 | "integrity": "sha1-PXT39keMiKG1AgMG10fcYxPHTQs="
66 | },
67 | "printj": {
68 | "version": "1.1.2",
69 | "resolved": "http://registry.npm.taobao.org/printj/download/printj-1.1.2.tgz",
70 | "integrity": "sha1-2Q3rKXWoufYA+zoclOP0xTx4oiI="
71 | },
72 | "ssf": {
73 | "version": "0.10.2",
74 | "resolved": "http://registry.npm.taobao.org/ssf/download/ssf-0.10.2.tgz",
75 | "integrity": "sha1-ZbK0/N/ZZ7yOg4OkE0kAmJMRWXY=",
76 | "requires": {
77 | "frac": "~1.1.2"
78 | }
79 | },
80 | "xlsx": {
81 | "version": "0.14.1",
82 | "resolved": "http://registry.npm.taobao.org/xlsx/download/xlsx-0.14.1.tgz",
83 | "integrity": "sha1-7O31Nr0elAVUhv9IT1iI3KqJvT0=",
84 | "requires": {
85 | "adler-32": "~1.2.0",
86 | "cfb": "^1.1.0",
87 | "codepage": "~1.14.0",
88 | "commander": "~2.17.1",
89 | "crc-32": "~1.2.0",
90 | "exit-on-epipe": "~1.0.1",
91 | "ssf": "~0.10.2"
92 | }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "excel2js",
3 | "version": "0.1.0",
4 | "description": "转换xlsx文件为js文件",
5 | "author": "JackyFu",
6 | "main": "main.js",
7 | "main-menu": {
8 | "i18n:MAIN_MENU.package.title/Excel2js": {
9 | "message": "excel2js:open"
10 | }
11 | },
12 | "panel": {
13 | "main": "panel/index.js",
14 | "type": "dockable",
15 | "title": "Excel2js",
16 | "width": 400,
17 | "height": 800,
18 | "min-width": 400
19 | },
20 | "panel.help": {
21 | "main": "panel/help.js",
22 | "type": "dockable",
23 | "title": "Help",
24 | "width": 660,
25 | "height": 800,
26 | "min-width": 400
27 | },
28 | "dependencies": {
29 | "xlsx": "^0.14.1"
30 | }
31 | }
--------------------------------------------------------------------------------
/panel/help.html:
--------------------------------------------------------------------------------
1 | Excel2js 帮助
2 |
3 |
4 |
5 |
6 | ### 注意事项
7 | * excel 的读取路径为 `项目目录/excel/`
8 | * js 文件保存路径为 `项目目录/assets/data/`
9 | * 转换成功后,会以`同名`的 js 文件保存,请自行做好文件备份
10 | * 以`!`开头的 excel 文件会被忽略,以`!`开头的 excel 字段名同样会被忽略
11 | * excel 文件第一行为`字段名`,第二行起为`数据`
12 | * 每个 excel 文件只会解析`第一个`表格
13 | * 支持解析 `.xlsx` 的 excel 文件
14 |
15 | ### 转换格式
16 | * excel
17 |
18 | | id | name | num | object | array |
19 | | :-----: |:-----:| :-----:| :-----:| :-----:|
20 | | 0 | "名字0" | 0 | {a:1,b:2} | [0,1,2] |
21 | | 1 | "名字1" | 1 | {a:1,b:2} | [0,1,2] |
22 | | 2 | "名字2" | 2 | {a:"对象1",b:"对象1"} | ["数组1","数组2"] |
23 | | 3 | "名字3" | 3 | {a:"对象1",b:"对象1"} | ["数组1","数组2"] |
24 |
25 |
26 | * js
27 |
28 | ```javascript
29 | module.exports = [
30 | {id:0, name:"名字0", num:0, object:{a:1,b:2}, array:[0,1,2]},
31 | {id:1, name:"名字1", num:1, object:{a:1,b:2}, array:[0,1,2]},
32 | {id:2, name:"名字2", num:2, object:{a:"对象1",b:"对象1"}, array:["数组1","数组2"]},
33 | {id:3, name:"名字3", num:3, object:{a:"对象1",b:"对象1"}, array:["数组1","数组2"]},
34 | ];
35 | ```
36 |
37 |
--------------------------------------------------------------------------------
/panel/help.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Fs = require('fire-fs');
4 | const Path = require('fire-path');
5 |
6 | Editor.Panel.extend({
7 | style: Fs.readFileSync(
8 | Editor.url('packages://excel2js/panel/index.css'),
9 | 'utf-8'
10 | ),
11 |
12 | template: Fs.readFileSync(
13 | Editor.url('packages://excel2js/panel/help.html'),
14 | 'utf-8'
15 | ),
16 |
17 | ready() {
18 |
19 | },
20 | });
--------------------------------------------------------------------------------
/panel/index.css:
--------------------------------------------------------------------------------
1 | h2 {
2 | color: #f90;
3 | margin-left: 10px;
4 | }
5 |
6 | li {
7 | line-height: 30px;
8 | margin-left:10px;
9 | margin-right:10px;
10 | }
11 |
12 | ui-markdown {
13 | margin-left: 10px;
14 | }
15 |
16 | :host {
17 | display: flex;
18 | flex-direction: column;
19 | }
20 |
21 | h3 {
22 | margin-top: 0;
23 | margin-bottom: 10px;
24 | }
25 |
26 | #view {
27 | flex: 1;
28 | padding: 10px;
29 | padding-top: 0px;
30 | overflow-y: auto;
31 | overflow-x: hidden;
32 | }
33 |
34 | div.section {
35 | border-bottom: 1px solid #666;
36 | padding-bottom: 10px;
37 | margin-bottom: 10px;
38 | margin-left: 10px;
39 | }
40 |
41 | div.section:last-child {
42 | border-bottom: 0px;
43 | }
44 |
45 | div.group {
46 | min-width: 420px;
47 | margin-bottom: 5px;
48 | display: flex;
49 | flex-direction: row;
50 | align-items: center;
51 | flex-wrap: wrap;
52 | }
53 |
54 | span {
55 | margin-right: 0.25em;
56 | }
--------------------------------------------------------------------------------
/panel/index.html:
--------------------------------------------------------------------------------
1 | Excel2js
2 |
3 | {{txtUpdate}}
4 | {{txtConvert}}
5 | {{txtHelp}}
6 |
7 |
22 |
--------------------------------------------------------------------------------
/panel/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Fs = require('fire-fs');
4 | const Path = require('fire-path');
5 |
6 | Editor.Panel.extend({
7 | style: Fs.readFileSync(
8 | Editor.url('packages://excel2js/panel/index.css'),
9 | 'utf-8'
10 | ),
11 |
12 | template: Fs.readFileSync(
13 | Editor.url('packages://excel2js/panel/index.html'),
14 | 'utf-8'
15 | ),
16 |
17 | ready() {
18 | this.v = new window.Vue({
19 | el: this.shadowRoot,
20 | data: {
21 | txtUpdate: '点击更新',
22 | txtConvert: '全部生成',
23 | txtHelp: '查看帮助',
24 | txtConvertOne: '生成',
25 | txtNoExcel: '没有找到Excel',
26 | iconStatus: [
27 | 'icon-record',
28 | 'icon-ok',
29 | 'icon-cancel'
30 | ],
31 | items: [
32 | ]
33 | },
34 | methods: {
35 | onClickUpdate() {
36 | Editor.Ipc.sendToMain('excel2js:update-excel', (err, data) => {
37 | if (err) {
38 | Editor.log(err);
39 | return;
40 | }
41 | this.items = [];
42 |
43 | for (let i = 0; i < data.length; i++) {
44 | if (Path.extname(data[i]) !== '.xlsx') {
45 | continue;
46 | }
47 | if (data[i].indexOf('~') === 0) {
48 | continue;
49 | }
50 | if (data[i].indexOf('!') === 0) {
51 | continue;
52 | }
53 | this.items.push({
54 | name: data[i],
55 | status: 0,
56 | });
57 | }
58 | });
59 | },
60 |
61 | onClickConvert() {
62 | if (this.items.length === 0) {
63 | return;
64 | }
65 | Editor.Ipc.sendToMain('excel2js:convert-js', this.items);
66 | },
67 |
68 | onClickConvertOne(index) {
69 | Editor.Ipc.sendToMain('excel2js:convert-js', this.items[index]);
70 | },
71 |
72 | onClickHelp() {
73 | Editor.Panel.open('excel2js.help');
74 | }
75 | },
76 | });
77 |
78 | this.v.onClickUpdate();
79 | },
80 |
81 | messages: {
82 | 'convert-success'(event, excelFileName) {
83 | for (let i = 0; i < this.v.items.length; i++) {
84 | if (this.v.items[i].name === excelFileName) {
85 | this.v.items[i].status = 1;
86 | break;
87 | }
88 | }
89 | },
90 |
91 | 'convert-failed'(event, excelFileName) {
92 | for (let i = 0; i < this.v.items.length; i++) {
93 | if (this.v.items[i].name === excelFileName) {
94 | this.v.items[i].status = 2;
95 | break;
96 | }
97 | }
98 | },
99 | },
100 | });
--------------------------------------------------------------------------------