销售分析部分包含按月分析的簇状图和按类别分析的饼图,如下:
1 页面设计
设计该页面其实很简单,说白了就是两个也切tab类以及饼图和簇状图。打开QTDesiger,按下图添加控件,并重命名如下:
2 按类别分析
#按类别功能函数
def analyByType(self):
#创建QPieSeries对象,用来存放饼图的数据
pseries=QPieSeries()
for item in typeset.items():
pseries.append(item[0], item[1])
slice=pseries.slices()[0]
slice.setExploded(True)
slice.setLabelVisible(True)
slice.setPen(QPen(Qt.GlobalColor.red,2))
slice.setBrush(Qt.GlobalColor.red)
#创建QChart实例
chart=QChart()
chart.addSeries(pseries)
chart.createDefaultAxes()
#设置图表
chart.setTitle("商品按类别销售数据分析")
#动画效果
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom)
#2显示图表
chartView=QChartView(chart)
#绘制平滑
chartView.setRenderHint(QPainter.RenderHint.Antialiasing)
self.layout1=QGridLayout(self.frmType)
self.layout1.addWidget(chartView)
3 按月分析
#按月份
def analyByMonth(self):
bseries=QBarSeries()
lseries=QLineSeries()
#添加数据
monthset=QBarSet('')
for i in range(0,12):
monthset << money_m[i]
lseries.append(i, money_m[i])
bseries.append(monthset)
lseries.setColor(QColor(255,0,0))
#创建QChart实例
chart=QChart()
#不显示图例
chart.legend().hide()
chart.addSeries(bseries)
chart.addSeries(lseries)
#设置坐标
axis_x=QBarCategoryAxis()
axis_x.setTitleText('月份')
axis_x.append(month)
chart.addAxis(axis_x,Qt.AlignmentFlag.AlignBottom)
lseries.attachAxis(axis_x)
axis_y=QValueAxis()
axis_y.setTitleText('金额(元)')
axis_y.setLabelFormat("%d")
chart.addAxis(axis_y,Qt.AlignmentFlag.AlignLeft)
lseries.attachAxis(axis_y)
#设置图表
chart.setTitle("商品按月份销售数据分析")
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
chart.setTheme(QChart.ChartTheme.ChartThemeLight)
#用chartView显示图表
chartView=QChartView(chart)
chartView.setRenderHint(QPainter.RenderHint.Antialiasing)
self.layout2=QGridLayout(self.frmMonth)
self.layout2.addWidget(chartView)
4 完整代码
# -*- coding:utf-8 -*-
"""
------------------------------------------------
File Name: SaleAnalysis.py
Description:
Author: lzq
date:2024-08-08 11:09
------------------------------------------------
"""
import sys
from datetime import datetime
import openpyxl
from PyQt6.QtCharts import QPieSeries, QChart, QChartView, QBarSeries, QLineSeries, QBarSet, QBarCategoryAxis, \
QValueAxis
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QIcon, QPen, QPainter, QColor
from PyQt6.QtPrintSupport import QPrintPreviewDialog
from PyQt6.QtWidgets import QGridLayout, QApplication
from pyqt6Learn.myNetShop.ui.SaleAnalysis_ui import Ui_MainWindow
saledata=[]
typeset={}
month=['01','02','03','04','05','05','05','08','09','10','11','12']
money_m=[0.00 for i in range(12)] #各月份对应的金额列表
class SaleWindow(Ui_MainWindow):
def __init__(self):
super(SaleWindow, self).__init__()
self.setupUi(self)
self.initUi()
def initUi(self):
self.setWindowIcon(QIcon('image/netshop.png'))
self.setWindowFlag(Qt.WindowType.MSWindowsFixedSizeDialogHint)
self.pbPrint.clicked.connect(self.printFigure)
self.createData()
self.analyByType()
self.analyByMonth()
#构造销售数据功能函数
def createData(self):
global saledata, typeset, money_m
book=openpyxl.load_workbook(r'data/netshop.xlsx')
sheet1=book['订单项表']
sheet2=book['订单表']
sheet3=book['商品表']
sheet4=book['商品分类表']
#1 从订单项表中读取所有状态为结算的记录
r=0
for cell_status in tuple(sheet1.columns)[3][1:]:
r += 1
if cell_status.value == '结算':
orderitem=[cell.value for cell in tuple(sheet1.rows)[r]]
#[订单号,商品号,数量,价格,金额,类别,月份]
saleitem=[orderitem[0],orderitem[1],orderitem[2],0.00,0.00,'','']
saledata.append(saleitem)
#2 由每一项saleitem 的商品号在商品表中查出价格,算出金额,查出类别编号,再根据类别编号到商品分类表中查出大类名称,写入saledata[]
for k, saleitem in enumerate(saledata):
n = 0
for cell_pid in tuple(sheet3.columns)[0][1:]:
n += 1
if cell_pid.value == saleitem[1]:
commodity=[cell.value for cell in tuple(sheet3.rows)[n]]
#写价格、金额
saleitem[3]=commodity[3]
saleitem[4]=saleitem[3]*saleitem[2]
#写类别
tid=commodity[1][0]
i=0
for cell_tid in tuple(sheet4.columns)[0][1:]:
i+=1
if cell_tid.value ==eval(tid):
tname=[cell.value for cell in tuple(sheet4.rows)[i]]
saleitem[5] = tname[1]
break
break
#3 由每一项saleitem的订单号到订单表中查出下单时间,截取月份字段,写入saledata[]
for k, saleitem in enumerate(saledata):
n = 0
for cell_oid in tuple(sheet2.columns)[0][1:]:
n += 1
if cell_oid.value == saleitem[0]:
order = [cell.value for cell in tuple(sheet2.rows)[n]]
#写月份
print(order[3])
saleitem[6]=str(order[3])[5:7]
break
#按类别统计
for saleitem in saledata:
typeset[saleitem[5]] = typeset.get(saleitem[5], 0)+ saleitem[4]
typeset = dict(sorted(typeset.items(), key=lambda x:x[1],reverse=True))
# 按月份统计
for saleitem in saledata:
money_m[eval(saleitem[6].lstrip('0'))-1] += saleitem[4]
#按类别功能函数
def analyByType(self):
#创建QPieSeries对象,用来存放饼图的数据
pseries=QPieSeries()
for item in typeset.items():
pseries.append(item[0], item[1])
slice=pseries.slices()[0]
slice.setExploded(True)
slice.setLabelVisible(True)
slice.setPen(QPen(Qt.GlobalColor.red,2))
slice.setBrush(Qt.GlobalColor.red)
#创建QChart实例
chart=QChart()
chart.addSeries(pseries)
chart.createDefaultAxes()
#设置图表
chart.setTitle("商品按类别销售数据分析")
#动画效果
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom)
#2显示图表
chartView=QChartView(chart)
#绘制平滑
chartView.setRenderHint(QPainter.RenderHint.Antialiasing)
self.layout1=QGridLayout(self.frmType)
self.layout1.addWidget(chartView)
#按月份
def analyByMonth(self):
bseries=QBarSeries()
lseries=QLineSeries()
#添加数据
monthset=QBarSet('')
for i in range(0,12):
monthset << money_m[i]
lseries.append(i, money_m[i])
bseries.append(monthset)
lseries.setColor(QColor(255,0,0))
#创建QChart实例
chart=QChart()
#不显示图例
chart.legend().hide()
chart.addSeries(bseries)
chart.addSeries(lseries)
#设置坐标
axis_x=QBarCategoryAxis()
axis_x.setTitleText('月份')
axis_x.append(month)
chart.addAxis(axis_x,Qt.AlignmentFlag.AlignBottom)
lseries.attachAxis(axis_x)
axis_y=QValueAxis()
axis_y.setTitleText('金额(元)')
axis_y.setLabelFormat("%d")
chart.addAxis(axis_y,Qt.AlignmentFlag.AlignLeft)
lseries.attachAxis(axis_y)
#设置图表
chart.setTitle("商品按月份销售数据分析")
chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)
chart.setTheme(QChart.ChartTheme.ChartThemeLight)
#用chartView显示图表
chartView=QChartView(chart)
chartView.setRenderHint(QPainter.RenderHint.Antialiasing)
self.layout2=QGridLayout(self.frmMonth)
self.layout2.addWidget(chartView)
#打印
def printFigure(self):
dlg=QPrintPreviewDialog()
dlg.paintRequested.connect(self.handlePrint)
dlg.exec()
#执行打印
def handlePrint(self, printer):
painter=QPainter(printer)
if self.tabWidget.currentIndex() == 0:
screen=self.frmType.grab()
else:
screen=self.frmMonth.grab()
painter.drawPixmap(180,50,screen)
time_print = datetime.now()
painter.drawText(100+self.frmType.width() -70, 50 + self.frmType.height()+30, datetime.strftime(time_print,'%Y-%m-%d %H:%M:$S'))
# if __name__=='__main__':
# app=QApplication(sys.argv)
# mainwindow=SaleWindow()
# mainwindow.show()
# sys.exit(app.exec())