@@ -0,0 +1,141 @@ | |||
# Logs | |||
logs | |||
*.log | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
lerna-debug.log* | |||
.pnpm-debug.log* | |||
# Diagnostic reports (https://nodejs.org/api/report.html) | |||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | |||
# Runtime data | |||
pids | |||
*.pid | |||
*.seed | |||
*.pid.lock | |||
# Directory for instrumented libs generated by jscoverage/JSCover | |||
lib-cov | |||
# Coverage directory used by tools like istanbul | |||
coverage | |||
*.lcov | |||
# nyc test coverage | |||
.nyc_output | |||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | |||
.grunt | |||
# Bower dependency directory (https://bower.io/) | |||
bower_components | |||
# node-waf configuration | |||
.lock-wscript | |||
# Compiled binary addons (https://nodejs.org/api/addons.html) | |||
build/Release | |||
# Dependency directories | |||
node_modules/ | |||
jspm_packages/ | |||
__pycache__/ | |||
# Snowpack dependency directory (https://snowpack.dev/) | |||
web_modules/ | |||
# TypeScript cache | |||
*.tsbuildinfo | |||
# Optional npm cache directory | |||
.npm | |||
# Optional eslint cache | |||
.eslintcache | |||
# Optional stylelint cache | |||
.stylelintcache | |||
# Microbundle cache | |||
.rpt2_cache/ | |||
.rts2_cache_cjs/ | |||
.rts2_cache_es/ | |||
.rts2_cache_umd/ | |||
# Optional REPL history | |||
.node_repl_history | |||
# Output of 'npm pack' | |||
*.tgz | |||
# Yarn Integrity file | |||
.yarn-integrity | |||
# dotenv environment variable files | |||
.env | |||
.env.development.local | |||
.env.test.local | |||
.env.production.local | |||
.env.local | |||
# parcel-bundler cache (https://parceljs.org/) | |||
.cache | |||
.parcel-cache | |||
# Next.js build output | |||
.next | |||
out | |||
# Nuxt.js build / generate output | |||
.nuxt | |||
dist | |||
# Gatsby files | |||
.cache/ | |||
# Comment in the public line in if your project uses Gatsby and not Next.js | |||
# https://nextjs.org/blog/next-9-1#public-directory-support | |||
# public | |||
# vuepress build output | |||
.vuepress/dist | |||
# vuepress v2.x temp and cache directory | |||
.temp | |||
.cache | |||
# vitepress build output | |||
**/.vitepress/dist | |||
# vitepress cache directory | |||
**/.vitepress/cache | |||
.venv/ | |||
build/ | |||
# Docusaurus cache and generated files | |||
.docusaurus | |||
# Serverless directories | |||
.serverless/ | |||
# FuseBox cache | |||
.fusebox/ | |||
# DynamoDB Local files | |||
.dynamodb/ | |||
# TernJS port file | |||
.tern-port | |||
# Stores VSCode versions used for testing VSCode extensions | |||
.vscode-test | |||
# yarn v2 | |||
.yarn/cache | |||
.yarn/unplugged | |||
.yarn/build-state.yml | |||
.yarn/install-state.gz | |||
.pnp.* |
@@ -0,0 +1,38 @@ | |||
# -*- mode: python ; coding: utf-8 -*- | |||
a = Analysis( | |||
['app.py'], | |||
pathex=[], | |||
binaries=[], | |||
datas=[('employee_info.json', '.'), ('company_options.json', '.'), ('bank_options.json', '.'), ('template.xlsx', '.'), ('config.py', '.')], | |||
hiddenimports=[], | |||
hookspath=[], | |||
hooksconfig={}, | |||
runtime_hooks=[], | |||
excludes=[], | |||
noarchive=False, | |||
optimize=0, | |||
) | |||
pyz = PYZ(a.pure) | |||
exe = EXE( | |||
pyz, | |||
a.scripts, | |||
a.binaries, | |||
a.datas, | |||
[], | |||
name='ExcelConverter', | |||
debug=False, | |||
bootloader_ignore_signals=False, | |||
strip=False, | |||
upx=True, | |||
upx_exclude=[], | |||
runtime_tmpdir=None, | |||
console=False, | |||
disable_windowed_traceback=False, | |||
argv_emulation=False, | |||
target_arch=None, | |||
codesign_identity=None, | |||
entitlements_file=None, | |||
) |
@@ -0,0 +1,115 @@ | |||
# 工资明细转换工具 | |||
这是一个用于批量转换Excel工资明细表的图形界面工具。 | |||
## 功能特点 | |||
1. 批量导入Excel文件并根据模板进行转换 | |||
2. 自定义设置每个文件的公司、银行和其他信息 | |||
3. 按照指定的单元格映射规则转换数据 | |||
4. 自动生成包含员工姓名和日期的输出文件名 | |||
5. 支持复制和保留原始Excel的格式和样式 | |||
## 环境要求 | |||
- Python 3.7 或更高版本 | |||
- 依赖包:pandas, openpyxl, xlrd, xlwt | |||
## 快速开始 | |||
1. 确保已安装Python环境(3.7或更高版本) | |||
2. 使用uv创建虚拟环境: | |||
```bash | |||
uv venv | |||
``` | |||
3. 激活虚拟环境: | |||
```bash | |||
# Windows | |||
.venv\Scripts\activate | |||
# macOS/Linux | |||
source .venv/bin/activate | |||
``` | |||
4. 安装依赖包: | |||
```bash | |||
uv pip install -r requirements.txt | |||
``` | |||
5. 运行程序: | |||
```bash | |||
# 方法1: 直接运行Python脚本 | |||
python main.py | |||
# 方法2: 使用批处理文件 (Windows) | |||
run.bat | |||
``` | |||
## 使用方法 | |||
1. 在界面上点击"选择Excel文件"按钮选择要转换的Excel文件 | |||
2. 双击列表中的每个文件,设置公司信息(C2)、银行信息(B30)和其他信息(F2) | |||
3. 点击"选择导出位置"按钮选择输出文件保存位置 | |||
4. 点击"开始转换"按钮进行批量转换 | |||
5. 转换完成后会显示成功转换的文件数量 | |||
## 文件命名规则 | |||
输出文件名格式为:`YYYY年M月份給料明細書-姓名.xls` | |||
- 年份(YYYY):从输入文件第二个Sheet页的B4单元格中提取 | |||
- 月份(M):从输入文件第二个Sheet页的B4单元格中提取 | |||
- 姓名:从输入文件第一个Sheet页的C3单元格中提取 | |||
## 配置指南 | |||
### 修改模板路径 | |||
在 `config.py` 文件中修改 `TEMPLATE_PATH` 变量。 | |||
### 修改单元格映射关系 | |||
在 `config.py` 文件中的 `CELL_MAPPINGS` 字典中定义映射关系: | |||
```python | |||
{ | |||
(源文件sheet索引, 行, 列): (目标文件sheet索引, 行, 列) | |||
} | |||
``` | |||
### 修改公司和银行列表 | |||
编辑 `config.py` 文件中的 `COMPANY_OPTIONS` 和 `BANK_OPTIONS` 列表即可添加或删除选项。 | |||
## 常见问题解决 | |||
### 程序启动失败 | |||
- 检查 Python 版本是否兼容 (3.7+) | |||
- 确认所有依赖已正确安装 | |||
- 检查模板文件是否存在于指定路径 | |||
### 转换后的文件格式不正确 | |||
- 确认模板文件格式无误 | |||
- 检查输入文件是否符合要求的格式 | |||
- 确认映射关系配置正确 | |||
### 无法识别日期 | |||
如果程序无法正确识别日期格式,可能需要在 `app.py` 的 `process_file` 方法中添加更多的日期解析逻辑。 | |||
## 项目结构 | |||
``` | |||
excel_converter/ | |||
├── app.py # 主应用程序代码 | |||
├── config.py # 配置文件 | |||
├── main.py # 入口点 | |||
├── requirements.txt # 依赖列表 | |||
├── run.bat # Windows 运行脚本 | |||
├── README.md # 项目说明 | |||
├── template.xlsx # Excel模板文件 | |||
└── test_data/ # 测试数据目录 | |||
``` | |||
## 维护和扩展 | |||
### 添加新功能 | |||
1. 尽量将配置参数放在 `config.py` 文件中 | |||
2. 保持用户界面简洁直观 | |||
3. 添加适当的错误处理和用户反馈 | |||
### 代码维护 | |||
- 定期更新依赖包版本 | |||
- 如果更改了核心功能,请更新文档 | |||
- 考虑添加单元测试以确保功能正常 |
@@ -0,0 +1,86 @@ | |||
[ | |||
{ | |||
"employee_name": "杜云", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "一三八(普通)2192640", | |||
"account_holder": "杜云 ト ウン" | |||
}, | |||
{ | |||
"employee_name": "範慶博", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "新宿通支店661(普通)8324403", | |||
"account_holder": "範慶博 ハン ケイハク" | |||
}, | |||
{ | |||
"employee_name": "龚丽犀", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "武蔵関支店(普通)6992252", | |||
"account_holder": "龚丽犀 キヨウ レイサイ" | |||
}, | |||
{ | |||
"employee_name": "劉紅軍", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "西川口支店(289)(普通)1409435", | |||
"account_holder": "劉紅軍 リュウ コウグン" | |||
}, | |||
{ | |||
"employee_name": "欧阳冠英", | |||
"bank_name": "楽天銀行", | |||
"branch_account": "〇五八(普通)9357044", | |||
"account_holder": "欧阳 冠英 オウヤン グアンイン" | |||
}, | |||
{ | |||
"employee_name": "孙文岱", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "一三八店(普通)1280916", | |||
"account_holder": "孙文岱 ソン ブンタイ" | |||
}, | |||
{ | |||
"employee_name": "王磊", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "町屋支店(228)(普通)6919966", | |||
"account_holder": "王磊 オウ ライ" | |||
}, | |||
{ | |||
"employee_name": "魏强", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "〇一八(普通)8654986", | |||
"account_holder": "魏强 ギ キョウ" | |||
}, | |||
{ | |||
"employee_name": "吴桐宇", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "心斎橋支店(031)(普通)0391875", | |||
"account_holder": "吴桐宇 ゴ トンウ" | |||
}, | |||
{ | |||
"employee_name": "朱文娟", | |||
"bank_name": "楽天銀行", | |||
"branch_account": "フーガ支店(220)(普通)1943194", | |||
"account_holder": "朱文娟 シュ ブンケン" | |||
}, | |||
{ | |||
"employee_name": "查干", | |||
"bank_name": "りそな銀行", | |||
"branch_account": "竹ノ塚支店(605)(普通) 4978660", | |||
"account_holder": "査干 チャ カン" | |||
}, | |||
{ | |||
"employee_name": "徐芮", | |||
"bank_name": "三菱東京UFJ銀行", | |||
"branch_account": "(普通)0314135", | |||
"account_holder": "徐芮 ジョ リ" | |||
}, | |||
{ | |||
"employee_name": "郑博", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "白山支店(228)(普通)6836322", | |||
"account_holder": "鄭博 テイ ハク" | |||
}, | |||
{ | |||
"employee_name": "周喻", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "日暮里之店(180)(普通)0281831", | |||
"account_holder": "周喻 シュウ ユ" | |||
} | |||
] |
@@ -0,0 +1,32 @@ | |||
import os | |||
import subprocess | |||
import sys | |||
def build_executable(): | |||
# Ensure we're in the project root directory | |||
os.chdir(os.path.dirname(os.path.abspath(__file__))) | |||
# Install required packages using uv | |||
print("Installing required packages...") | |||
subprocess.run(["uv", "pip", "install", "-r", "requirements.txt"], check=True) | |||
# Build the executable using PyInstaller | |||
print("Building executable...") | |||
subprocess.run([ | |||
"pyinstaller", | |||
"--name=ExcelConverter", | |||
"--onefile", | |||
"--windowed", | |||
"--add-data=employee_info.json;.", | |||
"--add-data=company_options.json;.", | |||
"--add-data=bank_options.json;.", | |||
"--add-data=template.xlsx;.", | |||
"--add-data=config.py;.", | |||
"app.py" | |||
], check=True) | |||
print("Build completed successfully!") | |||
print("The executable can be found in the 'dist' directory.") | |||
if __name__ == "__main__": | |||
build_executable() |
@@ -0,0 +1 @@ | |||
[] |
@@ -0,0 +1,160 @@ | |||
# Excel 转换工具配置文件 | |||
import os | |||
import json | |||
# 模板文件路径 | |||
TEMPLATE_PATH = "template.xlsx" | |||
# 配置文件路径 | |||
CONFIG_DIR = os.path.dirname(os.path.abspath(__file__)) | |||
EMPLOYEE_CONFIG_PATH = os.path.join(CONFIG_DIR, "employee_info.json") | |||
COMPANY_CONFIG_PATH = os.path.join(CONFIG_DIR, "company_options.json") # 保留兼容性 | |||
BANK_CONFIG_PATH = os.path.join(CONFIG_DIR, "bank_options.json") # 保留兼容性 | |||
# 单元格映射关系(源文件位置 -> 目标文件位置) | |||
# 格式:{(源文件sheet索引, 行, 列): (目标文件sheet索引, 行, 列)} | |||
CELL_MAPPINGS = { | |||
# 第一个Sheet的映射关系 | |||
(0, 3, 3): (0, 2, 5), # C3 -> E2 氏名 | |||
(0, 3, 4): (0, 3, 5), # D3 -> E3 労働日数 | |||
(0, 3, 2): (0, 3, 3), # B3 -> C3 ID | |||
(0, 3, 5): (0, 6, 4), # E3 -> D6 基本給 | |||
(0, 3, 6): (0, 7, 4), # F3 -> D7 職務給 | |||
(0, 3, 7): (0, 8, 4), # G3 -> D8 資格手当 | |||
(0, 3, 8): (0, 9, 4), # H3 -> D9 住宅手当 | |||
(0, 3, 9): (0, 10, 4), # I3 -> D10 能力手当 | |||
(0, 3, 10): (0, 11, 4), # J3 -> D11 通勤手当 | |||
(0, 3, 11): (0, 12, 4), # K3 -> D12 残業(固定) | |||
(0, 3, 12): (0, 13, 4), # L3 -> D13 | |||
(0, 3, 13): (0, 14, 4), # M3 -> D14 | |||
(0, 3, 15): (0, 17, 4), # O3 -> D17 | |||
(0, 3, 16): (0, 18, 4), # P3 -> D18 | |||
(0, 3, 17): (0, 19, 4), # Q3 -> D19 | |||
(0, 3, 18): (0, 20, 4), # R3 -> D20 | |||
(0, 3, 19): (0, 21, 4), # S3 -> D21 | |||
(0, 3, 20): (0, 22, 4), # T3 -> D22 | |||
(0, 3, 25): (0, 25, 5), # Y3 -> E25 | |||
} | |||
# 自定义值的单元格位置 | |||
CUSTOM_CELLS = { | |||
"company": (0, 2, 3), # C2 - 所属公司 | |||
"bank": (0, 29, 2), # B29 - 转账银行 | |||
"other": (0, 2, 6), # F2 - 其他信息 | |||
} | |||
# 文件名提取信息 | |||
FILENAME_CONFIG = { | |||
"name_cell": (0, 3, 3), # Sheet1 的 C3 - 员工姓名 | |||
"year_month_cell": (1, 4, 2), # Sheet2 的 B4 - 年月信息 | |||
} | |||
# 第二个Sheet的命名格式 | |||
SHEET2_NAME_FORMAT = "{month}月勤怠一覧" | |||
# 输出文件名格式 | |||
OUTPUT_FILENAME_FORMAT = "{year}年{month}月份給料明細書-{name}.xlsx" | |||
# 默认选项列表(仅在配置文件不存在时使用) | |||
DEFAULT_COMPANY_OPTIONS = [] | |||
# 银行信息默认结构 - 扩展为字典格式,包含更多字段 | |||
DEFAULT_BANK_OPTIONS = [ | |||
# 银行信息示例: | |||
# { | |||
# "employee_name": "田中太郎", # 员工姓名 | |||
# "bank_name": "三井住友銀行", # 银行名称 | |||
# "branch_account": "新宿通支店661 普通 8324403", # 支店和账号 | |||
# "account_holder": "田中太郎" # 账户持有人 | |||
# } | |||
] | |||
# 员工信息默认结构 - 合并公司和银行信息 | |||
DEFAULT_EMPLOYEE_INFO = [ | |||
# 员工信息示例: | |||
# { | |||
# "employee_name": "田中太郎", # 员工姓名 | |||
# "bank_name": "三井住友銀行", # 银行名称 | |||
# "branch_account": "新宿通支店661 普通 8324403", # 支店和账号 | |||
# "account_holder": "田中太郎", # 账户持有人 | |||
# "company_name": "SPD株式会社" # 所属公司 | |||
# } | |||
] | |||
# 加载员工信息 | |||
def load_employee_info(): | |||
# 检查是否存在员工信息配置 | |||
if os.path.exists(EMPLOYEE_CONFIG_PATH): | |||
try: | |||
with open(EMPLOYEE_CONFIG_PATH, 'r', encoding='utf-8') as f: | |||
employee_info = json.load(f) | |||
except Exception as e: | |||
print(f"加载员工信息出错: {e}") | |||
employee_info = DEFAULT_EMPLOYEE_INFO | |||
else: | |||
# 如果不存在,尝试从旧的配置中导入 | |||
employee_info = [] | |||
company_options = [] | |||
bank_options = [] | |||
# 加载旧的公司配置 | |||
if os.path.exists(COMPANY_CONFIG_PATH): | |||
try: | |||
with open(COMPANY_CONFIG_PATH, 'r', encoding='utf-8') as f: | |||
company_options = json.load(f) | |||
except Exception as e: | |||
print(f"加载公司配置出错: {e}") | |||
# 加载旧的银行配置 | |||
if os.path.exists(BANK_CONFIG_PATH): | |||
try: | |||
with open(BANK_CONFIG_PATH, 'r', encoding='utf-8') as f: | |||
bank_options = json.load(f) | |||
# 兼容旧版本:如果是字符串列表,转换为字典 | |||
if bank_options and isinstance(bank_options[0], str): | |||
new_bank_options = [] | |||
for bank_name in bank_options: | |||
new_bank_options.append({ | |||
"employee_name": "", | |||
"bank_name": bank_name, | |||
"branch_account": "", | |||
"account_holder": "" | |||
}) | |||
bank_options = new_bank_options | |||
except Exception as e: | |||
print(f"加载银行配置出错: {e}") | |||
# 合并旧配置 | |||
if bank_options and isinstance(bank_options[0], dict): | |||
for bank_option in bank_options: | |||
employee_name = bank_option.get("employee_name", "") | |||
if employee_name: # 如果有员工姓名,则添加为一条记录 | |||
employee_info.append({ | |||
"employee_name": employee_name, | |||
"bank_name": bank_option.get("bank_name", ""), | |||
"branch_account": bank_option.get("branch_account", ""), | |||
"account_holder": bank_option.get("account_holder", ""), | |||
"company_name": company_options[0] if company_options else "" | |||
}) | |||
# 保存新的员工信息 | |||
save_options(EMPLOYEE_CONFIG_PATH, employee_info) | |||
return employee_info | |||
# 保存选项 | |||
def save_options(config_path, options): | |||
try: | |||
with open(config_path, 'w', encoding='utf-8') as f: | |||
json.dump(options, f, ensure_ascii=False, indent=4) | |||
return True | |||
except Exception as e: | |||
print(f"保存配置出错: {e}") | |||
return False | |||
# 加载选项 | |||
EMPLOYEE_INFO = load_employee_info() | |||
COMPANY_OPTIONS = [info.get("company_name") for info in EMPLOYEE_INFO if info.get("company_name")] | |||
COMPANY_OPTIONS = list(set(COMPANY_OPTIONS)) # 去重 | |||
BANK_OPTIONS = [info for info in EMPLOYEE_INFO] # 兼容性:旧代码可能仍使用BANK_OPTIONS |
@@ -0,0 +1,156 @@ | |||
[ | |||
{ | |||
"employee_name": "杜云", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "一三八(普通)2192640", | |||
"account_holder": "杜云 ト ウン", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "範慶博", | |||
"company_name": "開元株式会社", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "新宿通支店661(普通)8324403", | |||
"account_holder": "範慶博 ハン ケイハク" | |||
}, | |||
{ | |||
"employee_name": "龚丽犀", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "武蔵関支店(普通)6992252", | |||
"account_holder": "龚丽犀 キヨウ レイサイ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "劉紅軍", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "西川口支店(289)(普通)1409435", | |||
"account_holder": "劉紅軍 リュウ コウグン", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "欧阳冠英", | |||
"bank_name": "楽天銀行", | |||
"branch_account": "〇五八(普通)9357044", | |||
"account_holder": "欧阳 冠英 オウヤン グアンイン", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "孙文岱", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "一三八店(普通)1280916", | |||
"account_holder": "孙文岱 ソン ブンタイ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "王磊", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "町屋支店(228)(普通)6919966", | |||
"account_holder": "王磊 オウ ライ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "魏强", | |||
"bank_name": "ゆうちょ銀行", | |||
"branch_account": "〇一八(普通)8654986", | |||
"account_holder": "魏强 ギ キョウ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "吴桐宇", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "心斎橋支店(031)(普通)0391875", | |||
"account_holder": "吴桐宇 ゴ トンウ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "朱文娟", | |||
"bank_name": "楽天銀行", | |||
"branch_account": "フーガ支店(220)(普通)1943194", | |||
"account_holder": "朱文娟 シュ ブンケン", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "查干", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "りそな銀行", | |||
"branch_account": "竹ノ塚支店(605)(普通) 4978660", | |||
"account_holder": "査干 チャ カン" | |||
}, | |||
{ | |||
"employee_name": "徐芮", | |||
"bank_name": "三菱東京UFJ銀行", | |||
"branch_account": "(普通)0314135", | |||
"account_holder": "徐芮 ジョ リ", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "郑博", | |||
"bank_name": "三井住友銀行", | |||
"branch_account": "白山支店(228)(普通)6836322", | |||
"account_holder": "鄭博 テイ ハク", | |||
"company_name": "SPD株式会社" | |||
}, | |||
{ | |||
"employee_name": "周喻", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "三菱UFJ銀行", | |||
"branch_account": "日暮里之店(180)(普通)0281831", | |||
"account_holder": "周喻 シュウ ユ" | |||
}, | |||
{ | |||
"employee_name": "呉恵宜", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "西本真衣", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "柳顺子", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "宓存行", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "盖雪梅", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "王玥倩", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "周锋", | |||
"company_name": "嘉年華株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
}, | |||
{ | |||
"employee_name": "西本智子", | |||
"company_name": "SPD株式会社", | |||
"bank_name": "", | |||
"branch_account": "", | |||
"account_holder": "" | |||
} | |||
] |
@@ -0,0 +1,36 @@ | |||
import os | |||
import sys | |||
import tkinter as tk | |||
from app import ExcelConverterApp | |||
import openpyxl | |||
from copy import copy | |||
def main(): | |||
""" | |||
Main entry point for the Excel Converter application. | |||
""" | |||
# Create the main window | |||
root = tk.Tk() | |||
root.title("日本工资明细转换工具") | |||
# Set window icon if available | |||
if os.path.exists("icon.ico"): | |||
root.iconbitmap("icon.ico") | |||
# Create and run the application | |||
app = ExcelConverterApp(root) | |||
# Center window on screen | |||
window_width = 800 | |||
window_height = 600 | |||
screen_width = root.winfo_screenwidth() | |||
screen_height = root.winfo_screenheight() | |||
x = (screen_width - window_width) // 2 | |||
y = (screen_height - window_height) // 2 | |||
root.geometry(f"{window_width}x{window_height}+{x}+{y}") | |||
# Run the application | |||
root.mainloop() | |||
if __name__ == "__main__": | |||
main() |
@@ -0,0 +1,5 @@ | |||
pandas>=2.0.0 | |||
openpyxl>=3.1.0 | |||
xlrd>=2.0.0 | |||
xlwings>=0.30.0 | |||
pyinstaller>=6.0.0 |
@@ -0,0 +1,4 @@ | |||
@echo off | |||
echo 启动工资明细转换工具... | |||
python app.py | |||
pause |