news 2026/9/22 1:15:26

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
3天搞定免费做账软件:附完整示例代码

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

别被官方文档吓跑,那些长篇大论确实让人头大,抓不住重点。想快速上手免费做账软件的核心逻辑,直接看这套完整示例最管用。

房建工程现场的人都知道,项目账目杂、单据多,用Excel手搓容易乱,买商业软件又贵。其实,用Python搭一个轻量级的记账系统,不仅能解决痛点,还能帮你理清业务流。今天不讲虚的,直接上代码,带你从零搭建一个能用的做账小工具。

项目目标:为什么我们要自己搭

很多工程师觉得做账是财务的事,但项目现场的材料采购、劳务工资、机械租赁,数据都在你手里。如果这些数据不能结构化,月底对账就是噩梦。

我们的目标很简单:

  1. 数据录入:支持通过CSV或API录入交易数据。
  2. 自动分类:根据关键词自动判断科目(如材料费、人工费)。
  3. 报表生成:一键生成月度收支汇总表。
  4. 本地存储:不依赖云,数据留在本地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 = f"strftime('%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

执行命令

  1. 导入数据

    python main.py --import data/transactions.csv
    

    预期输出:

    正在导入: data/transactions.csv
    成功导入 5 条记录
    
  2. 生成报表

    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 True

3. 多项目对比

房建公司通常有多个项目。增加一个命令,对比所有项目的月度支出。

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调用就行。

官方文档再全,不如自己跑通一遍。这套完整示例代码,你可以直接复制运行,也可以根据自己项目的需求魔改。记住,工具是死的,人是活的,只有懂原理,才能用出花。

做账这件事,最怕的不是麻烦,而是混乱。用代码把混乱变成结构,这就是技术给工程人的赋能。

还有什么不懂的?评论区留言挨个回。比如:如何处理跨月发票?或者:如何对接银行流水自动导入?都聊聊。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/22 1:15:22

搞定苹果7红色环境卡壳:3步最佳实践救急

搞定苹果7红色环境卡壳:3步最佳实践救急 配置环境就卡半天?别急,这坑我踩过无数次。很多老手都在苹果7红色这类特定场景下翻过车,最后发现是版本兼容没对上。今天直接上 最佳实践 ,帮你把时间抢回来。 项目目标与痛点拆解 咱们先对齐一下,为啥苹果7红色这个看似简单的需求,能卡住你一下午?…

作者头像 李华
网站建设 2026/9/22 1:15:05

金融是什么工作图解原理:3招搞定量化笔试性能瓶颈

金融是什么工作图解原理:3招搞定量化笔试性能瓶颈 刚拿到量化金融岗位的笔试邀请,是不是感觉脑子要炸了?官方文档和算法题解动辄几百页,翻半天抓不住重点,手心全是汗。别慌,今天直接用 图解原理 把“金融是什么工作”背后的代码性能逻辑拆透,专治你这种“题会做但跑不完”的急性子。…

作者头像 李华
网站建设 2026/9/22 1:15:02

3个关键源码解析带你吃透实习概况面试考点

3个关键源码解析带你吃透实习概况面试考点 翻遍官方文档和招聘JD,关于“实习概况”的描述总是语焉不详,要么全是正确的废话,要么藏着让你当场懵逼的隐性要求。官方文档太长抓不住重点,导致很多转岗的开发者在面试时,明明代码写得溜,却因为没搞懂“实习概况”背后的考察逻辑而被刷掉。…

作者头像 李华
网站建设 2026/9/22 1:14:52

5个维度拆解可乐要加冰最佳实践 告别教程依赖

5个维度拆解可乐要加冰最佳实践 告别教程依赖 看了一堆教程还是不会写项目?别急着怪自己,90%的卡壳是因为你在用“玩具代码”思维处理“生产环境”问题。很多开发者陷入一个误区:以为把语法跑通就是懂了,结果一到实际业务场景,面对并发、异常、数据一致性这些“脏活累活”时,瞬间大脑空白。这时候需要的不是更多…

作者头像 李华
网站建设 2026/9/22 1:14:36

3步搞定奔驰新闻系统:小白也能跑通的完整示例

3步搞定奔驰新闻系统:小白也能跑通的完整示例 刚学完Python语法,对着屏幕发呆?别慌,我懂你的痛。 很多兄弟跟我一样,刷完几十节课,代码能敲,但一让搭个像样的项目,脑子直接死机。这时候最缺的不是更多语法,而是一个能跑起来的 完整示例 。…

作者头像 李华
网站建设 2026/9/22 1:14:27

换手机软件总报错?3个完整示例帮你彻底搞定代码移植难题

换手机软件总报错?3个完整示例帮你彻底搞定代码移植难题 复制来的代码跑不通不知道怎么调,这是很多开发者换设备或迁移项目时的噩梦。明明在旧电脑上跑得飞起,换个手机软件环境或者新笔记本就疯狂抛异常。别慌,这通常不是代码逻辑错了,而是环境差异、依赖冲突或配置陷阱在作祟。 今天咱们不整虚的,直接上…

作者头像 李华