# 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.* |
# -*- 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, | |||||
) |
# 工资明细转换工具 | |||||
这是一个用于批量转换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. 添加适当的错误处理和用户反馈 | |||||
### 代码维护 | |||||
- 定期更新依赖包版本 | |||||
- 如果更改了核心功能,请更新文档 | |||||
- 考虑添加单元测试以确保功能正常 |
[ | |||||
{ | |||||
"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": "周喻 シュウ ユ" | |||||
} | |||||
] |
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() |
[] |
# 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 |
[ | |||||
{ | |||||
"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": "" | |||||
} | |||||
] |
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() |
pandas>=2.0.0 | |||||
openpyxl>=3.1.0 | |||||
xlrd>=2.0.0 | |||||
xlwings>=0.30.0 | |||||
pyinstaller>=6.0.0 |
@echo off | |||||
echo 启动工资明细转换工具... | |||||
python app.py | |||||
pause |