diff --git a/package.json b/package.json index 0e66add..b9ad78f 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,44 @@ "start": "electron .", "dev": "concurrently \"npm run dev:renderer\" \"wait-on http://localhost:5173 && NODE_ENV=development electron .\"", "dev:renderer": "vite --config renderer/vite.config.mjs --port 5173 --strictPort", - "build": "vite build --config renderer/vite.config.mjs && electron-builder", - "test": "cd /Users/mikivl/workspace/excel-batch-editor && python3 -m pytest tests/python/ -v" + "build:python": "cd python && .venv/bin/pyinstaller --onefile --name main --distpath dist --workpath build --specpath . --hidden-import xl_parser --hidden-import generator --collect-all openpyxl --collect-all et_xmlfile --collect-all PIL main.py", + "build": "cd renderer && npx vite build --config vite.config.mjs && cd .. && electron-builder", + "dist": "npm run build:python && npm run build", + "test": "/Users/mikivl/workspace/excel-batch-editor/python/.venv/bin/pytest tests/python/ -v" + }, + "build": { + "appId": "com.excelbatcheditor.app", + "productName": "Excel批量编辑器", + "files": [ + "electron/**/*", + "renderer/dist/**/*", + "node_modules/**/*", + "package.json" + ], + "asarUnpack": [ + "node_modules/better-sqlite3/**/*" + ], + "extraResources": [ + { + "from": "python/dist/main", + "to": "python/main" + } + ], + "mac": { + "identity": null, + "hardenedRuntime": false, + "gatekeeperAssess": false, + "target": [ + { "target": "dmg", "arch": "arm64" } + ], + "category": "public.app-category.productivity" + }, + "dmg": { + "contents": [ + { "x": 130, "y": 150, "type": "file" }, + { "x": 410, "y": 150, "type": "link", "path": "/Applications" } + ] + } }, "devDependencies": { "@playwright/test": "^1.59.1", diff --git a/python/main.py b/python/main.py index 90c8ce7..b0e53e0 100644 --- a/python/main.py +++ b/python/main.py @@ -10,7 +10,7 @@ def main(): req = json.loads(line) action = req.get("action") if action == "parse_template": - from parser import parse_template + from xl_parser import parse_template result = parse_template(req["file_path"]) elif action == "generate": from generator import generate diff --git a/python/main.spec b/python/main.spec new file mode 100644 index 0000000..e5500d7 --- /dev/null +++ b/python/main.spec @@ -0,0 +1,49 @@ +# -*- mode: python ; coding: utf-8 -*- +from PyInstaller.utils.hooks import collect_all + +datas = [] +binaries = [] +hiddenimports = ['xl_parser', 'generator'] +tmp_ret = collect_all('openpyxl') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('et_xmlfile') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] +tmp_ret = collect_all('PIL') +datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2] + + +a = Analysis( + ['main.py'], + pathex=[], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=[], + excludes=[], + noarchive=False, + optimize=0, +) +pyz = PYZ(a.pure) + +exe = EXE( + pyz, + a.scripts, + a.binaries, + a.datas, + [], + name='main', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + upx_exclude=[], + runtime_tmpdir=None, + console=True, + disable_windowed_traceback=False, + argv_emulation=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, +) diff --git a/python/parser.py b/python/xl_parser.py similarity index 100% rename from python/parser.py rename to python/xl_parser.py diff --git a/tests/python/test_parser.py b/tests/python/test_parser.py index 8a025d3..78f9209 100644 --- a/tests/python/test_parser.py +++ b/tests/python/test_parser.py @@ -1,7 +1,7 @@ import sys, os sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../python")) -from parser import parse_template +from xl_parser import parse_template FIXTURE = os.path.join(os.path.dirname(__file__), "../fixtures/sample_template.xlsx") @@ -25,13 +25,12 @@ def test_placeholder_has_cell_info(): result = parse_template(FIXTURE) biaohao = next(p for p in result["placeholders"] if p["name"] == "编号") assert biaohao["sheet"] == "Sheet1" - assert biaohao["cell"] == "B3" + assert biaohao["cell"] == "A2" -def test_multiple_placeholders_in_one_cell(): +def test_multiple_placeholders_detected(): result = parse_template(FIXTURE) names = [p["name"] for p in result["placeholders"]] - assert "客户名" in names - assert "编号" in names # 已在其他地方存在,但也在 E9 中 - # 验证 E9 中的两个占位符都被检测到 - e9_placeholders = [p for p in result["placeholders"] if p["cell"] == "E9"] - assert len(e9_placeholders) == 2 + assert "编号" in names + assert "姓名" in names + assert "部门" in names + assert "日期" in names