智能云柜 报表 SmartReport

# coding=utf-8
import datetime
from os import path, getcwd, system
from sys import exit
from time import sleep

import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objs as go
from plotly.io import write_image
from pandas import read_excel
import PySimpleGUI as sg


def File_choice():
    sg.theme('LightGreen3')
    layout = [sg.Frame('文件选择:', [
        [sg.FileBrowse(' 请选择文件:'), sg.Input('', size=(60, 1), key='_FILEPATH_')],
        [sg.Button(button_text='  确定  ', key='Ok', size=(6, 1), bind_return_key=True),
         sg.Button(button_text='  退出  ', key='Exit', size=(6, 1))],
    ], element_justification='center')]
    window = sg.Window('文件选择', [layout])
    while True:
        event, values = window.read()
        if event in ('Exit', sg.WIN_CLOSED):
            window.close()
            break
        if event == 'Ok':
            FILE_PATH = values['_FILEPATH_']
            if path.exists(FILE_PATH):
                return FILE_PATH
                window.close()
                break
            else:
                sg.popup_auto_close('所选文件不存在!', auto_close_duration=2)

def ReadXLS(PATH='', SheetName=''):
    data = read_excel(PATH, sheet_name=SheetName, header=0, engine='openpyxl')  # 读取excel,Sheetname默认"Table"
    END = data['操作日期'].dt.strftime('%Y/%m/%d').values[0]
    START = data['操作日期'].dt.strftime('%Y/%m/%d').values[-1]
    data['商品规格'].fillna('None', inplace=True)
    data = data.groupby(by=['商品编码', '商品名称', '工单号', '工单数量', '商品规格', '图号'], as_index=False).agg(
        {'每盒数量': 'sum', '刀具已加工产品数量': 'sum', '是否已还': lambda x: x[x == '已还'].count()}, index=False)
    data['寿命'] = (data['刀具已加工产品数量'] / data['是否已还'] / 100).round() * 100  # 100整倍数
    data['工单总数'] = ''
    data = data.groupby(by=['商品编码', '商品名称', '商品规格', '图号'], as_index=False) \
        .agg({'工单号': 'nunique', '工单数量': 'sum', '每盒数量': 'sum', '刀具已加工产品数量': 'sum', '是否已还': 'sum'}, index=False)
    data.sort_values('每盒数量', inplace=True, ascending=False)
    data['占比'] = data['每盒数量'].cumsum() / data['每盒数量'].sum()
    # data['占比'] = data['占比'].apply(lambda x:format(x,'.1%'))
    data['平均寿命'] = (data['刀具已加工产品数量'] / data['是否已还'] / 100).round() * 100

    # dataNew = data.groupby(by=['商品编码', '商品名称', '商品规格'], as_index=False).agg({'每盒数量': 'sum'})
    # dataNew.sort_values('每盒数量', inplace=True, ascending=False)
    # dataNew['占比'] = dataNew['每盒数量'].cumsum() / dataNew['每盒数量'].sum()

    LISTS = []
    for CutterPartNum in data['商品编码']:
        x = data[data['商品编码'] == CutterPartNum]['每盒数量'].sum()
        LISTS.append(x)
    data['刀具领用数2'] = LISTS
    return data,START,END

def CreateCharts(df,START,END,CURR_PATH):
    TOTAL = df['每盒数量'].sum()
    title1 = '未归还\已归还数量'
    title2 = '共领用%s款刀具,合计总数%sEA' % (df['商品编码'].nunique(), TOTAL)
    title4 = '刀具对应平均寿命'
    title5 = '刀具对应领用总数  __共%s款,总数%sEA__' % (df['商品编码'].nunique(), df['每盒数量'].sum())
    RETURNDED = df['是否已还'].sum()
    NOT_RETURN = df['每盒数量'].sum()-RETURNDED

    DATA_PIE_TOTAL = df.groupby(by=['商品编码', '商品名称', '商品规格'], as_index=False).agg({'每盒数量': 'sum'})
    DATA_PIE_TOTAL.sort_values('每盒数量', inplace=True, ascending=False)
    DATA_PIE_TOTAL['占比'] = DATA_PIE_TOTAL['每盒数量'].cumsum() / DATA_PIE_TOTAL['每盒数量'].sum()

    Percant80 = DATA_PIE_TOTAL[DATA_PIE_TOTAL['占比'] < 0.8]
    BOTTOM20 = DATA_PIE_TOTAL[DATA_PIE_TOTAL['占比'] >= 0.8]
    OTHER20_CLASS = BOTTOM20.shape[0]
    OTHER20_PERCANT = 1-Percant80.iloc[-1,-1]
    OTHER20_SUM = BOTTOM20['每盒数量'].sum()

    Percant80 = Percant80.append({'商品编码': '其它%s款' % OTHER20_CLASS, '商品名称': '', '商品规格': '', '每盒数量': OTHER20_SUM, '占比': OTHER20_PERCANT},ignore_index=True)
    # Percant80['占比2'] = Percant80['每盒数量'] / Percant80['每盒数量'].sum()
    df2 = df.groupby(by=['商品编码','商品名称','商品规格'],as_index=False).agg({'每盒数量':'sum'})
    df2.sort_values('每盒数量',inplace=True,ascending=False)
    df2['累积占比'] = df2['每盒数量'].cumsum()/df2['每盒数量'].sum()
    df3 = df2[df2['累积占比']<=0.8]
    if df2.shape[0]>50:
        df2 = df2.iloc[0:50,:]

    LENGTH = df.shape[0]
    if LENGTH > 50:
        TITLE = '每款产品的领刀数量 _Top 50 of %s组_'%LENGTH
        df = df.iloc[0:50,:]
    elif LENGTH <= 50:
        TITLE = '每款产品的领刀数量 _共%s组_'%LENGTH
    title3 = TITLE

    PIE_SUM = go.Pie(values=[RETURNDED, NOT_RETURN],
                     labels=['已归还数量', '未归还数量'],
                     hole=0.5,
                     textinfo='label+value+percent',
                     marker = {'colors': ['#7CCD7C', '#FF4040']},
                     showlegend=False,
                     )

    PIE_TOTAL = go.Pie(
        values=Percant80['每盒数量'],
        labels=Percant80['商品编码'],
        hole=0.5,
        textinfo='label+value+percent',
        sort=False,
        direction='clockwise',
        showlegend=False,
    )

    BAR_CLASS = go.Bar(
        x=df['商品编码']+','+df['图号'].astype('str'),
        y=df['每盒数量'],
        text=df['每盒数量'],
        textfont_size=30,
        textposition='outside',
    )

    BAR_LIFE = go.Bar(
        x=df['商品编码']+','+df['图号'].astype('str'),
        y=df['平均寿命'],
        text=df['平均寿命'],
        textfont=dict(size=30,color='white'),
        textangle=270,
        textposition='inside',
        showlegend=False,
    )

    SCATTER_CLASS = go.Scatter(
        x = df['商品编码'] + ',' + df['图号'].astype('str'),
        y = df['每盒数量'].cumsum()/TOTAL,
        mode='lines',
        showlegend=False,
    )

    BAR_TOTAL = go.Bar(
        x=df2['商品编码']+','+df2['商品名称'],
        y=df2['每盒数量'],
        text=df2['每盒数量'],
        textfont_size=20,
        textposition='outside',
        showlegend=False,
    )

    SCATTER_TOTAL = go.Scatter(
        x=df2['商品编码']+','+df2['商品名称'],
        y = df2['累积占比'],
        marker={'size': 6},
        line={'width': 2},
        mode='lines',
        name='各款刀各图号累积占比',
        # text=df2['累积占比'].apply(lambda x:format(x,'.0%')),
        textposition='top center',
        textfont={'size': 8},
        showlegend=False,
    )

    SCATTER_TOTAL2 = go.Scatter(
        x=[df3.iloc[-1,:]['商品编码']+','+df3.iloc[-1,:]['商品名称']],
        y = [df3.iloc[-1,:]['累积占比']],
        marker={'size': 12,'color':'red','symbol':'circle-dot'},
        text=[format(df3.iloc[-1,:]['累积占比'],'.0%')],
        mode='markers+text',
        name='各款刀各图号累积占比',
        textposition='top center',
        textfont={'size': 12,'color':'red'},
        showlegend=False,
    )

    fig = make_subplots(
        specs=[
            [{'type': 'pie'}, {'type': 'pie'}],
            [{'type': 'xy', 'secondary_y': True, 'colspan': 2}, None],
            [{'type': 'bar', 'colspan': 2}, None],
            [{'type': 'xy', 'secondary_y': True, 'colspan': 2}, None]
        ],
        subplot_titles=[title1,title2,title3,title4,title5],
        rows=4,
        cols=2)
    fig.add_trace(PIE_SUM,row=1,col=1)
    fig.add_trace(PIE_TOTAL,row=1,col=2)
    fig.add_trace(BAR_CLASS,row=2,col=1)
    fig.add_trace(SCATTER_CLASS,secondary_y=True,row=2,col=1)
    fig.add_trace(BAR_LIFE,row=3,col=1)
    fig.add_trace(BAR_TOTAL,row=4,col=1)
    fig.add_trace(SCATTER_TOTAL,secondary_y=True,row=4,col=1)
    fig.add_trace(SCATTER_TOTAL2, secondary_y=True, row=4, col=1)
    fig.update_xaxes({'tickfont': {'size': 15}})
    fig.update_layout(margin=dict(t=60, l=10, r=10, b=40, pad=1),
                      template='ggplot2',
                      title='<b>刀具柜统计报表</b><br>%s~%s'%(START,END),
                      title_font_size=30,#={'size': 22},# 'color': 'rgb(153,51,0)'},
                      showlegend=False,
                      xaxis1_tickangle=45,
                      xaxis2_tickangle=45,
                      xaxis3_tickangle=45,
                      title_x=0.5)
    write_image(fig,r'%s\刀具柜统计_%s~%s.png' % (CURR_PATH, START.replace('/', ''), END.replace('/', '')),width=1360,height=2000,scale=2)
    fig.write_html(r'd:\刀柜统计.html',default_width=1360,default_height=2400)


def main():
    XLS_PATH = File_choice()
    CURR_PATH = path.dirname(XLS_PATH)
    if XLS_PATH:
        df, START, END = ReadXLS(XLS_PATH, SheetName='Table')
        df.to_excel(r'%s\刀具柜统计_%s~%s.xlsx' % (CURR_PATH, START.replace('/', ''), END.replace('/', '')),engine='openpyxl',encoding='utf-8', index=False)  # 存入excel
        CreateCharts(df, START, END,CURR_PATH)

if __name__ == '__main__':
    main()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Smart-Report报表工具支持常规的BI应用——报表制作(报表、图形),分析与信息发布; 提供强大的开发环境和易于维护的报表; 掌握该工具门槛比较低,通过简单培训就能掌握; 数据安全性的统一控制; 通过开放的API接口与其它业务系统的方便集成。 1、系统所需环境 操作系统:WINDOWS(2000、XP、WINDOWS7) 数据库:MYSQL5.0 WEB服务器:TOMCAT5.5 客户端浏览器:IE6.0及以上版本 由于是基于JAVA的B/S系统,因此是夸平台的,上面列举的环境需求,只是为了接下来更好的介绍本软件。 本软件支持的大部分关系型数据库,如:DB2、ORACLE、SQL SERVER等。WEB服务器支持:TOMCAT、WEBSPHERE、WEBLOGIC等。 2、安装前的准备 在SmartReport部署前,需要有数据库环境及WEB服务器,因此需要安装数据库及WEB服务器。 (1)安装MYSQL5.0数据库 以WINDOWS为例,网上下载MYSQL数据库,然后根据安装向导一步步安装即可完成TOMCAT的安装。 (2)安装MYSQL客户端 为了方便的管理、查看MYSQL,用户可以选择安装MYSQL客户端,如:MySQL-Front (3)安装TOMCAT5.5.27 以安装TOMCAT5.5为例,用户可以下载免安装版本的TOMCAT,解压缩即能使用,前提是需要在环境变量里配置TOMCAT_HOME、JAVA_HOME等信息。运行TOMCAT_HOME/bin下的startup.bat文件,启动TOMCAT,待启动完后,在IE里输入:http://localhost:8080/,如看到下面页面则表示TOMCAT安装成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值