Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印 Pyside6版

这图是第2版,

现在发布原型版

 代码:

order_system_pyside6.py

from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,QHBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox,QTableWidget, QTableWidgetItem, QComboBox, QFrame,QHeaderView, QFileDialog, QDialog, QGroupBox, QGridLayout,QRadioButton, QTextBrowser)
from PySide6.QtCore import Qt, QDate
from PySide6.QtGui import QDoubleValidator
import sqlite3
from datetime import datetime
import pandas as pd
import hashlib
import json
import os
import sys
from login_pyside6 import LoginWindowclass OrderSystem(QMainWindow):def __init__(self):super().__init__()self.init_db()self.create_menu()  # 添加菜单栏self.init_ui()self.load_all_orders()def init_db(self):"""初始化数据库"""try:os.makedirs('db', exist_ok=True)self.conn = sqlite3.connect('db/orders.db')self.create_table()except sqlite3.Error as e:QMessageBox.critical(self, "错误", f"数据库连接失败:{str(e)}")sys.exit(1)def create_table(self):"""创建数据表"""cursor = self.conn.cursor()cursor.execute('''CREATE TABLE IF NOT EXISTS orders (order_date TEXT,order_number TEXT,customer TEXT,product TEXT,unit TEXT,quantity REAL,price REAL,discount REAL,final_price REAL,total REAL,remarks TEXT,discount_amount REAL,discount_total REAL,delivery TEXT,payment_received REAL,end_customer TEXT,notes TEXT,business TEXT)''')self.conn.commit()def init_ui(self):"""初始化用户界面"""self.setWindowTitle("智慧记辅助系统")self.setMinimumSize(1200, 800)# 创建中央部件central_widget = QWidget()self.setCentralWidget(central_widget)main_layout = QVBoxLayout(central_widget)# 创建查询区域search_frame = QFrame()search_frame.setFrameStyle(QFrame.StyledPanel)search_layout = QHBoxLayout(search_frame)# 添加查询条件输入框self.search_fields = {}search_items = [('order_number', '单据编号'),('customer', '客户名称'),('product', '品名规格'),('date_from', '开始日期'),('date_to', '结束日期'),('business', '营业员')]for field, label in search_items:field_layout = QVBoxLayout()label_widget = QLabel(label)self.search_fields[field] = QLineEdit()field_layout.addWidget(label_widget)field_layout.addWidget(self.search_fields[field])search_layout.addLayout(field_layout)# 添加查询和重置按钮button_layout = QVBoxLayout()search_button = QPushButton("查询")search_button.clicked.connect(self.search_orders)reset_button = QPushButton("重置")reset_button.clicked.connect(self.reset_search)button_layout.addWidget(search_button)button_layout.addWidget(reset_button)search_layout.addLayout(button_layout)main_layout.addWidget(search_frame)# 创建按钮区域button_layout = QHBoxLayout()self.create_buttons(button_layout)main_layout.addLayout(button_layout)# 创建表格self.create_tables()main_layout.addWidget(self.table)# 居中显示self.center_window()def create_buttons(self, layout):"""创建按钮"""buttons = [("新增", self.add_order),("编辑", self.edit_order),("删除", self.delete_selected),("查看", self.view_order),("导入Excel", self.import_from_excel),("导出Excel", self.export_to_excel),("导出模板", self.export_template),("统计报表", self.show_statistics)]for text, slot in buttons:button = QPushButton(text)button.clicked.connect(slot)layout.addWidget(button)def create_tables(self):"""创建表格"""self.table = QTableWidget()headers = ["单据日期", "单据编号", "客户名称", "品名规格", "单位","数量", "原价", "单行折扣率(%)", "折后价", "金额","备注", "整单折扣率(%)", "折后金额", "运费","本单已收", "结算账户", "说明", "营业员"]self.table.setColumnCount(len(headers))self.table.setHorizontalHeaderLabels(headers)self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Interactive)self.table.horizontalHeader().setStretchLastSection(True)# 设置列宽for i in range(len(headers)):self.table.setColumnWidth(i, 100)def center_window(self):"""居中显示窗口"""screen_geometry = QApplication.primaryScreen().geometry()x = (screen_geometry.width() - self.width()) // 2y = (screen_geometry.height() - self.height()) // 2self.move(x, y)def calculate_total(self):"""计算金额"""try:quantity = float(self.entries['quantity'].text() or 0)price = float(self.entries['price'].text() or 0)discount = float(self.entries['discount'].text() or 100)final_price = price * discount / 100self.entries['final_price'].setText(f"{final_price:.2f}")total = quantity * final_priceself.entries['total'].setText(f"{total:.2f}")except ValueError:passdef validate_data(self):"""数据验证"""errors = []# 验证必填字段required_fields = {'order_date': '单据日期','order_number': '单据编号','customer': '客户名称','product': '品名规格','unit': '单位','quantity': '数量','price': '原价'}for field, name in required_fields.items():if not self.entries[field].text().strip():errors.append(f"{name}不能为空")if errors:QMessageBox.critical(self, "验证错误", "\n".join(errors))return Falsereturn Truedef save_order(self):"""保存订单"""if not self.validate_data():returntry:values = []for field in self.entries:value = self.entries[field].text().strip()if field in ['quantity', 'price', 'discount', 'final_price', 'total', 'discount_amount', 'discount_total', 'payment_received']:try:value = float(value) if value else 0.0except ValueError:value = 0.0values.append(value)cursor = self.conn.cursor()cursor.execute('SELECT COUNT(*) FROM orders WHERE order_number = ?', (values[1],))if cursor.fetchone()[0] > 0:reply = QMessageBox.question(self, "警告", "单据编号已存在,是否继续保存?",QMessageBox.Yes | QMessageBox.No)if reply == QMessageBox.No:returncursor.execute('''INSERT INTO orders VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', values)self.conn.commit()self.load_all_orders()self.set_default_values()QMessageBox.information(self, "成功", "订单保存成功!")except Exception as e:self.conn.rollback()QMessageBox.critical(self, "错误", f"保存失败:{str(e)}")def clear_fields(self):"""清空输入框"""for entry in self.entries.values():entry.clear()self.set_default_values()def edit_selected(self):"""编辑选中的记录"""selected = self.table.selectedItems()if not selected:QMessageBox.warning(self, "提示", "请先选择一条记录")returnrow = selected[0].row()for col, field in enumerate(self.entries):self.entries[field].setText(self.table.item(row, col).text())def delete_selected(self):"""删除选中的记录"""selected = self.table.selectedItems()if not selected:QMessageBox.warning(self, "提示", "请先选择一条记录")returnreply = QMessageBox.question(self, "确认", "确定要删除选中的记录吗?",QMessageBox.Yes | QMessageBox.No)if reply == QMessageBox.Yes:row = selected[0].row()order_number = self.table.item(row, 1).text()cursor = self.conn.cursor()cursor.execute('DELETE FROM orders WHERE order_number = ?', (order_number,))self.conn.commit()self.load_all_orders()def import_from_excel(self):"""从Excel导入数据"""filename, _ = QFileDialog.getOpenFileName(self, "选择Excel文件", "","Excel Files (*.xlsx *.xls);;All Files (*)")if not filename:returntry:df = pd.read_excel(filename)if self.validate_excel_data(df):self.import_excel_data(df)except Exception as e:QMessageBox.critical(self, "错误", f"导入失败:{str(e)}")def export_to_excel(self):"""导出到Excel"""filename, _ = QFileDialog.getSaveFileName(self, "保存Excel文件", "","Excel Files (*.xlsx);;All Files (*)")if not filename:returntry:cursor = self.conn.cursor()cursor.execute('SELECT * FROM orders')data = cursor.fetchall()columns = ["单据日期", "单据编号", "客户名称", "品名规格", "单位","数量", "原价", "单行折扣率(%)", "折后价", "金额","备注", "整单折扣率(%)", "折后金额", "运费","本单已收", "结算账户", "说明", "营业员"]df = pd.DataFrame(data, columns=columns)df.to_excel(filename, index=False, engine='openpyxl')QMessageBox.information(self, "成功", "数据导出成功!")except Exception as e:QMessageBox.critical(self, "错误", f"导出失败:{str(e)}")def export_template(self):"""导出模板"""filename, _ = QFileDialog.getSaveFileName(self, "保存模板", "订单导入模板.xlsx","Excel Files (*.xlsx);;All Files (*)")if not filename:returntry:# 创建示例数据sample_data = {"单据日期": ["2024-01-01"],"单据编号": ["XSD202401001"],"客户名称": ["示例客户"],"品名规格": ["示例产品"],"单位": ["个"],"数量": [1],"原价": [100],"单行折扣率(%)": [100],"折后价": [100],"金额": [100],"备注": ["备注示例"],"整单折扣率(%)": [0],"折后金额": [100],"运费": [0],"本单已收": [0],"结算账户": ["结算账户示例"],"说明": ["说明示例"],"营业员": ["营业员示例"]}# 创建DataFrame并导出到Exceldf = pd.DataFrame(sample_data)df.to_excel(filename, index=False, engine='openpyxl')QMessageBox.information(self, "成功", "模板导出成功!\n请按照模板格式准备数据后再进行导入。")except Exception as e:QMessageBox.critical(self, "错误", f"导出模板失败:{str(e)}")def show_statistics(self):"""显示统计报表"""stats_dialog = StatisticsDialog(self.conn, self)stats_dialog.exec()def load_all_orders(self):"""加载所有订单"""cursor = self.conn.cursor()cursor.execute('SELECT * FROM orders')data = cursor.fetchall()self.table.setRowCount(len(data))for row, record in enumerate(data):for col, value in enumerate(record):item = QTableWidgetItem(str(value))self.table.setItem(row, col, item)def set_default_values(self):"""设置默认值"""today = datetime.now().strftime('%Y-%m-%d')self.entries['order_date'].setText(today)self.entries['discount'].setText('100')# 生成新的单据编号cursor = self.conn.cursor()cursor.execute('''SELECT MAX(order_number) FROM orders WHERE order_number LIKE ?''', [f'XSD{today.replace("-", "")}%'])last_number = cursor.fetchone()[0]if last_number:try:seq = int(last_number[-3:]) + 1new_number = f'XSD{today.replace("-", "")}{seq:03d}'except ValueError:new_number = f'XSD{today.replace("-", "")}001'else:new_number = f'XSD{today.replace("-", "")}001'self.entries['order_number'].setText(new_number)def validate_excel_data(self, df):"""验证Excel数据"""required_columns = ["单据日期", "单据编号", "客户名称", "品名规格", "单位","数量", "原价", "单行折扣率(%)", "折后价", "金额"]missing_columns = [col for col in required_columns if col not in df.columns]if missing_columns:QMessageBox.critical(self, "错误", f"Excel文件缺少以下必需列:\n{', '.join(missing_columns)}")return Falsereturn Truedef import_excel_data(self, df):"""导入Excel数据"""try:cursor = self.conn.cursor()for _, row in df.iterrows():values = []for field in self.entries:excel_field = {'order_date': '单据日期','order_number': '单据编号','customer': '客户名称','product': '品名规格','unit': '单位','quantity': '数量','price': '原价','discount': '单行折扣率(%)','final_price': '折后价','total': '金额','remarks': '备注','discount_amount': '整单折扣率(%)','discount_total': '折后金额','delivery': '运费','payment_received': '本单已收','end_customer': '结算账户','notes': '说明','business': '营业员'}[field]value = row.get(excel_field, '')if pd.isna(value):value = 0 if field in ['quantity', 'price', 'discount', 'final_price','total', 'discount_amount', 'discount_total','payment_received'] else ''values.append(value)cursor.execute('''INSERT INTO orders VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''', values)self.conn.commit()self.load_all_orders()QMessageBox.information(self, "成功", "数据导入成功!")except Exception as e:self.conn.rollback()QMessageBox.critical(self, "错误", f"导入数据失败:{str(e)}")def view_order(self):"""查看订单详情"""selected = self.table.selectedItems()if not selected:QMessageBox.warning(self, "提示", "请先选择一条记录")returnrow = selected[0].row()order_number = self.table.item(row, 1).text()  # 获取单据编号dialog = OrderDetailDialog(self.conn, order_number, self)dialog.exec()def search_orders(self):"""执行订单查询"""try:# 构建查询条件conditions = []params = []# 单据编号查询if self.search_fields['order_number'].text().strip():conditions.append("order_number LIKE ?")params.append(f"%{self.search_fields['order_number'].text().strip()}%")# 客户名称查询if self.search_fields['customer'].text().strip():

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/67869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

element upload上传图片,上传完成隐藏组件或者禁用上传

背景: 在项目开发,需要上传图片,一张或者多张。当上传1张图片时,upload组件有一张图片时,组件自带的disabletrue设置为true禁用上传,就不会触发上传接口了,但是还是可以点开图片进行选择&#x…

【2024年华为OD机试】 (A卷,100分)- 二元组个数(Java JS PythonC/C++)

一、问题描述 以下是题目描述的 Markdown 格式: 题目描述 给定两个数组 a 和 b,若 a[i] b[j],则称 [i, j] 为一个二元组。求在给定的两个数组中,二元组的个数。 输入描述 第一行输入 m,表示第一个数组的长度。第二…

Homebrew 【MAC安装软件利器】

1、brew介绍 Homebrew游来: Homebrew 的诞生源于一个年轻程序员的不满和创新。2009 年,Max Howell 当时是一名在苹果公司工作的程序员。他觉得在 Mac 上安装和管理开源软件特别麻烦,常常需要手动下载源代码、解决依赖关系、编译安装,过程繁琐…

AOP实现操作日志记录

文章目录 1.common-log4j2-starter1.目录2.pom.xml 引入依赖3.LogAspect.java4.Log4j2AutoConfiguration.java Log4j2自动配置类条件注入切面类 2.common-log4j2-starter-demo 测试1.目录2.application.yml 启用日志切面3.TraceController.java4.结果 1.common-log4j2-starter …

JavaEE之线程池

前面我们了解了多个任务可以通过创建多个线程去处理,达到节约时间的效果,但是每一次的线程创建和销毁也是会消耗计算机资源的,那么我们是否可以将线程进阶一下,让消耗计算机的资源尽可能缩小呢?线程池可以达到此效果&a…

YOLOv11改进,YOLOv11添加HAttention注意机制用于图像修复的混合注意力转换器,CVPR2023,超分辨率重建

摘要 基于Transformer的方法在低层视觉任务中表现出色,例如图像超分辨率。然而,作者通过归因分析发现,这些网络只能利用有限的空间范围的输入信息。这意味着现有网络尚未充分发挥Transformer的潜力。为了激活更多的输入像素以获得更好的重建效果,作者提出了一种新型的混合…

Shader -> SweepGradient扫描渐变着色器详解

XML文件 <com.example.myapplication.MyViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_gravity"center"android:layout_height"400dp"/>自定义View代码 c…

LabVIEW调用不定长数组 DLL数组

在使用 LabVIEW 调用 DLL 库函数时&#xff0c;如果函数中的结构体包含不定长数组&#xff0c;直接通过 调用库函数节点&#xff08;Call Library Function Node&#xff09; 调用通常会遇到问题。这是因为 LabVIEW 需要与 DLL 中的数据结构完全匹配&#xff0c;而包含不定长数…

IOS开发如何从入门进阶到高级

针对iOS开发的学习&#xff0c;不同阶段应采取不同的学习方式&#xff0c;以实现高效提升.本文将iOS开发的学习分为入门、实战、进阶三个阶段&#xff0c;下面分别详细介绍. 一、学习社区 iOS开源中国社区 这个社区专注于iOS开发的开源项目分享与协作&#xff0c;汇集了大量开…

Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式

业务场景 在目前常见的中后台管理系统中&#xff0c;比较常见的是固定的布局方式包裹页面&#xff0c;但一些特殊页面&#xff0c;比如&#xff1a;登录页面、注册页面、忘记密码页面这些页面是不需要布局包裹的。 但在 Next.js AppRouter 中&#xff0c;必须包含一个根布局文…

基于 Python 和 OpenCV 的人脸识别上课考勤管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

人工智能与物联网:智慧城市的未来

引言 清晨6点&#xff0c;智能闹钟根据你的睡眠状态和天气情况&#xff0c;自动调整叫醒时间&#xff1b;窗帘缓缓打开&#xff0c;阳光洒满房间&#xff1b;厨房里的咖啡机已经为你准备好热饮&#xff0c;而无人驾驶公交车正按时抵达楼下站点。这不是科幻电影的场景&#xff…

python-leetcode-无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; class Solution:def lengthOfLongestSubstring(self, s: str) -> int:char_set set()left 0max_length 0for right in range(len(s)):while s[right] in char_set:char_set.remove(s[left])left 1char_…

新版本的IDEA如何解决Git分支显示为警告⚠<unknown>的问题

目录 问题再现 解决思路 首先我们要想到 这个分支有没有从远程代码仓库拉去下来 复习一下 git 命令 其次思考 最后思考 问题再现 这边我使用的是 IDEA 2024.3.3.1 Jetbrains 官网的最新版 同时也是官方账号登录 的 今天上 github 去拉项目到 本地 出现了分支不显示的问…

libusb学习——简单介绍

文章目录 libusb 简介libusb 编译libusb 源码目录介绍核心代码文件平台支持例子 API使用libusb初始化和去初始化libusb设备处理和枚举libusb 杂项libusb USB描述符libusb 设备热插拔事件通知libusb 异步设备I/Olibusb 同步设备I/Olibusb 轮询与定时 libusb 涉及技术参考 libusb…

案例解读 | 香港某多元化综合金融企业基础监控+网管平台建设实践

PART01 项目背景 01客户简介案例客户是一家创立20多年的香港某多元化综合金融企业&#xff0c;其业务范围涵盖证券、期货、资产管理、财富管理等&#xff0c;凭借广泛的业务网络和多元化的金融服务产品&#xff0c;在市场中拥有显著的影响力。02痛点分析随着业务版图的持续拓展…

551 灌溉

常规解法&#xff1a; #include<bits/stdc.h> using namespace std; int n,m,k,t; const int N105; bool a[N][N],b[N][N]; int cnt; //设置滚动数组来存贮当前和下一状态的条件 //处理传播扩散问题非常有效int main() {cin>>n>>m>>t;for(int i1;i&l…

【简博士统计学习方法】第1章:4. 模型的评估与选择

4. 模型的评估与选择 4.1 训练误差与测试误差 假如存在样本容量为 N N N的训练集&#xff0c;将训练集送入学习系统可以训练学习得到一个模型&#xff0c;我们将这么模型用决策函数的形式表达&#xff0c;也就是 y f ^ ( x ) y\hat{f}(x) yf^​(x)&#xff0c;关于模型的拟合…

【css】浏览器强制设置元素状态(hover|focus……)

直接上步骤&#xff1a; 打开浏览器控制台 → 找到样式选项 → 找到:hov选项 → 点击:hov选项&#xff0c;会展开【设置元素状态】。 只要选中就会展示出自己写在css里面的该种状态下的样式了。

LabVIEW水轮发电机组振动摆度故障诊断

本文介绍了基于LabVIEW的水轮发电机组振动摆度故障诊断系统的设计与实施过程。系统在通过高效的故障诊断功能&#xff0c;实现水轮发电机组的振动、温度等关键指标的实时监控与智能分析&#xff0c;从而提高电力设备的可靠性和安全性。 ​ 项目背景 随着电力行业对设备稳定性…