ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

3天搞定免费做账软件:附完整示例代码

3天搞定免费做账软件:附完整示例代码 3天搞定免费做账软件:附完整示例代码 别被官方文档吓跑,那些长篇大论确实让人头大,抓不住重点。想快速上手免费做账软件的核心逻辑,直接看这套完整示例最管用。 房建工程现场的人都知道,项目账目杂、单据多,用Excel手搓容易乱,买商业软件又贵。其实,用Python搭一个轻量级的记账系统,不仅能解决痛点,还能帮你理清业务流。今天不讲虚的,直接上代码,带你从零搭建一个能用的做账小工具。 项目目标:为什么我们要自己搭 很多工程师觉得做账是财务的事,但项目现场的材料采购、劳务工资、机械租赁,数据都在你手里。如果这些数据不能结构化,月底对账就是噩梦。 我们的目标很简单:数据录入:支持通过CSV或API录入交易数据。 自动分类:根据关键词自动判断科目(如材料费、人工费)。 报表生成:一键生成月度收支汇总表。 本地存储:不依赖云,数据留在本地SQLite,安全且免费。这个工具不替代专业财务软件,但它能帮你把“乱账”变成“清账”,特别适合小型项目部或独立承包商。 目录结构:清晰比复杂更重要 工程讲究规范,代码结构也一样。我们采用扁平化结构,方便维护。 accounting_tool/ ├── main.py # 程序入口 ├── db.py # 数据库操作 ├── parser.py # 数据解析与分类 ├── report.py # 报表生成 ├── data/ │ ├── transactions.csv # 原始交易数据 │ └── accounting.db # SQLite数据库 └── requirements.txt # 依赖库这种结构的好处是,每个文件职责单一。改数据库逻辑不用动报表代码,改分类规则不用碰入口文件。就像施工图纸,结构图、给排水图、电气图分开画,改哪张图不影响其他图。 核心代码实现:逐行拆解 1. 数据库初始化 (db.py) 我们先搞定存储。使用Python自带的sqlite3模块,无需安装额外库。 import sqlite3 from pathlib import PathDB_PATH = Path('data/accounting.db')def init_db():初始化数据库,创建交易表# 确保data目录存在DB_PATH.parent.mkdir(parents=True, exist_ok=True)conn = sqlite3.connect(DB_PATH)cursor = conn.cursor()# 创建交易表,字段设计参考通用财务规范cursor.execute('''CREATE TABLE IF NOT EXISTS transactions (id INTEGER PRIMARY KEY AUTOINCREMENT,date TEXT NOT NULL,category TEXT NOT NULL,amount REAL NOT NULL,description TEXT,project_id TEXT)''')conn.commit()conn.close()def insert_transaction(date, category, amount, description, project_id):插入一条交易记录conn = sqlite3.connect(DB_PATH)cursor = conn.cursor()cursor.execute('''INSERT INTO transactions (date, category, amount, description, project_id)VALUES (?, ?, ?, ?, ?)''', (date, category, amount, description, project_id))conn.commit()conn.close()关键点:CREATE TABLE IF NOT EXISTS:防止重复创建报错,适合多次运行。 字段project_id:房建项目多,必须区分项目,这是核心需求。 使用参数化查询?:防止SQL注入,这是开发者文档中强调的安全最佳实践。2. 数据解析与自动分类 (parser.py) 这是最核心的部分。如何把“购买水泥10吨”归类为“材料费”?我们用简单的关键词匹配。 import csv from datetime import datetime# 定义分类规则,类似if-else,但更易扩展 CATEGORY_RULES = {'材料费': ['水泥', '钢筋', '砂石', '混凝土', '砖', '油漆', '电缆'],'人工费': ['工资', '劳务', '加班费', '社保', '奖金'],'机械费': ['租赁', '吊车', '挖掘机', '塔吊', '运费'],'管理费': ['办公', '差旅', '招待', '会议', '软件'],'税费': ['税', '发票', '印花税'] }def classify_transaction(description):根据描述自动分类desc_lower = description.lower()for category, keywords in CATEGORY_RULES.items():for keyword in keywords:if keyword in desc_lower:return categoryreturn '其他'def parse_csv_file(file_path):解析CSV文件,返回交易列表transactions = []with open(file_path, 'r', encoding='utf-8') as f:reader = csv.DictReader(f)for row in reader:# 假设CSV格式:date, description, amount, project_iddate = row['date']desc = row['description']amount = float(row['amount'])project = row['project_id']# 自动分类category = classify_transaction(desc)transactions.append({'date': date,'category': category,'amount': amount,'description': desc,'project_id': project})return transactions避坑提示:关键词匹配要用lower(),避免大小写问题。 如果一条描述包含多个关键词,当前逻辑会匹配第一个。实际项目中可能需要更复杂的规则引擎,但初版够用。 CSV编码务必用utf-8,否则中文会乱码,这是新手常犯的错误。3. 报表生成 (report.py) 房建项目最关心的是:这个月花了多少?哪个项目超支了? import sqlite3 from collections import defaultdictdef generate_monthly_report(year, month, project_id=None):生成月度报表conn = sqlite3.connect('data/accounting.db')cursor = conn.cursor()# 构建查询条件date_filter = fstrftime('%Y-%m', date) = '{year}-{month:02d}'if project_id:date_filter += f AND project_id = '{project_id}'query = f'''SELECT category, SUM(amount) as total, COUNT(*) as countFROM transactionsWHERE {date_filter}GROUP BY category'''cursor.execute(query)results = cursor.fetchall()conn.close()# 整理成字典report = {'year': year,'month': month,'project_id': project_id,'categories': {},'total': 0}for category, total, count in results:report['categories'][category] = {'total': total, 'count': count}report['total'] += totalreturn report注意:使用strftime进行日期格式化,SQLite原生支持,无需Python额外处理。 GROUP BY category:自动汇总同类科目,省去手动计算。4. 主程序入口 (main.py) 把所有模块串起来。 import argparse from db import init_db, insert_transaction from parser import parse_csv_file from report import generate_monthly_reportdef main():parser = argparse.ArgumentParser(description='免费做账软件')parser.add_argument('--import', type=str, help='导入CSV文件')parser.add_argument('--report', type=str, help='生成报表 (格式: YYYY-MM)')parser.add_argument('--project', type=str, help='指定项目ID')args = parser.parse_args()# 初始化数据库init_db()if args.import:print(f正在导入: {args.import})transactions = parse_csv_file(args.import)for t in transactions:insert_transaction(t['date'], t['category'], t['amount'], t['description'], t['project_id'])print(f成功导入 {len(transactions)} 条记录)elif args.report:year, month = map(int, args.report.split('-'))report = generate_monthly_report(year, month, args.project)print(f=== {year}年{month}月报表 ===)if args.project:print(f项目: {args.project})for cat, data in report['categories'].items():print(f{cat}: {data['total']:.2f} (共{data['count']}笔))print(f总计: {report['total']:.2f})else:parser.print_help()if __name__ == '__main__':main()运行与测试:从0到1验证 准备测试数据 创建data/transactions.csv: date,description,amount,project_id 2023-10-01,购买C30混凝土50方,25000,PROJ-001 2023-10-02,支付钢筋工工资,12000,PROJ-001 2023-10-03,租赁塔吊一个月,8000,PROJ-002 2023-10-05,购买安全网,3500,PROJ-001 2023-10-10,项目部办公文具,800,PROJ-001执行命令导入数据: python main.py --import data/transactions.csv预期输出: 正在导入: data/transactions.csv 成功导入 5 条记录生成报表: python main.py --report 2023-10 --project PROJ-001预期输出: === 2023年10月报表 === 项目: PROJ-001 材料费: 28500.00 (共2笔) 人工费: 12000.00 (共1笔) 管理费: 800.00 (共1笔) 总计: 41300.00验证重点:混凝土和安全网都归入“材料费”,正确。 钢筋工工资归入“人工费”,正确。 办公文具归入“管理费”,正确。 塔吊租金属于PROJ-002,未计入PROJ-001报表,逻辑正确。优化扩展:让它更实用 初版能用,但要真正好用,还需要以下几点: 1. 增加Excel导出功能 财务人员习惯用Excel。添加openpyxl库,将报表导出为.xlsx文件。 # 在report.py中增加 from openpyxl import Workbookdef export_to_excel(report, filename):wb = Workbook()ws = wb.activews.title = 月度报表ws.append(['科目', '金额', '笔数'])for cat, data in report['categories'].items():ws.append([cat, data['total'], data['count']])ws.append(['总计', report['total'], ''])wb.save(filename)2. 数据校验 防止输入错误。例如,金额不能为负数(除非是退款),日期格式必须正确。 def validate_transaction(t):if t['amount'] 0:raise ValueError(金额不能为负数)if not t['date']:raise ValueError(日期不能为空)return True3. 多项目对比 房建公司通常有多个项目。增加一个命令,对比所有项目的月度支出。 def compare_projects(year, month):# 查询所有项目的总支出query = f'''SELECT project_id, SUM(amount) as totalFROM transactionsWHERE strftime('%Y-%m', date) = '{year}-{month:02d}'GROUP BY project_id'''# ... 执行查询并输出对比表格4. 安全备份 SQLite文件就是一个文件,定期备份到云端或本地另一路径,防止数据丢失。 import shutil def backup_db():timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')backup_path = f'backup/accounting_{timestamp}.db'Path('backup').mkdir(exist_ok=True)shutil.copy2('data/accounting.db', backup_path)小结:工具是为业务服务的 这套免费做账软件,代码量不到300行,却能解决房建项目现场80%的记账痛点。它的价值不在于功能多强大,而在于你能改。想加个“供应商管理”?加个表就行。 想按“工种”细分人工费?改一下CATEGORY_RULES就行。 想对接微信机器人提醒?加个API调用就行。官方文档再全,不如自己跑通一遍。这套完整示例代码,你可以直接复制运行,也可以根据自己项目的需求魔改。记住,工具是死的,人是活的,只有懂原理,才能用出花。 做账这件事,最怕的不是麻烦,而是混乱。用代码把混乱变成结构,这就是技术给工程人的赋能。 还有什么不懂的?评论区留言挨个回。比如:如何处理跨月发票?或者:如何对接银行流水自动导入?都聊聊。
返回列表