接昨日,将上传至oracle的excel文件下载下来

本文详细介绍了一段C#代码,该代码用于从数据库中读取特定ID的Excel文件,并将其作为二进制数据流输出到HTTP响应中,实现在线下载。文章涵盖了数据库连接、SQL查询、读取BLOB类型数据并进行流处理的全过程。

代码如下
try
        {
            DBHelper db = DBHelper.DBHelperInstance(System.Configuration.ConfigurationSettings.AppSettings["DataBaseType"]); ;
            OracleConnection oconn = new OracleConnection(db.pcsConnectionString);
            oconn.Open();

            string strSQL = "select DOC from exceltodb where fileid='1112'";
            OracleCommand OCMD = new OracleCommand(strSQL, oconn);
            OracleDataReader Ord = OCMD.ExecuteReader(CommandBehavior.SequentialAccess);
            int bufferSize = 100;
            byte[] outbyte = new byte[bufferSize];
            long retval;                            // The bytes returned from GetBytes.
            long startIndex = 0;
            Response.AddHeader("Content-Type", "application/vnd.ms-excel");
            Response.AddHeader("Content-Disposition", "attachment;filename=test.xls");
            if(Ord.Read())
            {
                // Reset the starting byte for the new BLOB.
                startIndex = 0;

                // Read the bytes into outbyte[] and retain the number of bytes returned.
                retval = Ord.GetBytes(0, startIndex, outbyte, 0, bufferSize);

                // Continue reading and writing while there are bytes beyond the size of the buffer.
                while (retval == bufferSize)
                {
                    this.Response.BinaryWrite(outbyte);
                    this.Response.Flush();

                    // Reposition the start index to the end of the last buffer and fill the buffer.
                    startIndex += bufferSize;
                    retval = Ord.GetBytes(0, startIndex, outbyte, 0, bufferSize);
                }

                // Write the remaining buffer.
                this.Response.BinaryWrite(outbyte);
                this.Response.Flush();
             }
             Ord.Close();
             oconn.Close();
                this.Response.End();
           }
           catch(Exception ex)
           {
             this.Response.Write("<b>ex.Message</b>");
           }
           finally
           {
            
            }

参考自优快云相关文档

转载于:https://www.cnblogs.com/yeskele/archive/2006/03/14/349628.html

# -*- coding: utf-8 -*- import os import cx_Oracle as cx import pandas as pd import datetime as dt import warnings import time from threading import Thread import schedule from openpyxl import load_workbook from openpyxl.utils.dataframe import dataframe_to_rows import requests import base64 import hashlib from PIL import ImageGrab import win32com.client as win32 import pythoncom warnings.filterwarnings('ignore') class Wechat: def __init__(self, secret): self.secret = secret def access_token(self): """获取企业微信access_token""" url = f'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wwed5e7f3fd1a3a553&corpsecret={self.secret}' response = requests.get(url).json() return response['access_token'] def oracle_connect(sql): """Oracle数据库查询""" con = cx.connect("admin/xxb20140415@192.168.3.16:1521/zzjdata") cursor = con.cursor() cursor.execute(sql) column_s = [col[0] for col in cursor.description] data = cursor.fetchall() cursor.close() con.close() return data, column_s def generate_g3_monthly_sql(): """生成月度G3阶段销售数据查询SQL""" sql = """ ------阶段销售查询表(按门店)(月度) with hzxs as (select a.subbh,a.hedgehh,a.sl,a.lsh,a.jshj,a.ml,a.hh,a.ph1_xq,a.posguid,a.xsr from subfhd a left join gl_custom b on a.subbh=b.tjbh where a.kdrq between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and nvl(a.bz,' ')<>'会员礼品成本调整单' and nvl(a.bz,' ')<>'¥' and nvl(a.bm,' ')<>'积分兑换' and b.tj_tag<>'40'), abc as (select b.tjbh,f.hh,a.PRODUCTTYPE,a.PRODUCTSUBTYPE,a.FEETYPE1,a.productid,sum(a.amount) jshj from abc_feedetail a left join gl_custom b on a.CLINICID=b.C_ABCID left join yw_kck f on a.productid=f.c_abcgoodsid where to_date(substr(a.created,1,10),'yyyy-mm-dd') between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by b.tjbh,f.hh,a.PRODUCTTYPE,a.PRODUCTSUBTYPE,a.FEETYPE1,a.productid), xs as (select subbh,sum(jshj) jshj,sum(ml) ml,count(distinct lsh) kds from hzxs group by subbh union select a.tjbh,nvl(a.jshj,0)-nvl(d.jshj,0) jshj,nvl(c.ml,0)+nvl(b.ml,0) ml,a.kds from (select b.tjbh,sum(a.amount) jshj,count(distinct TRANSACTIONID) kds from abc_feebill a left join gl_custom b on a.CLINICID=b.C_ABCID where to_date(substr(a.created,1,10),'yyyy-mm-dd') between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by b.tjbh) a left join (select c.tjbh,sum(case when a.action='退药' then -a.saleprice else a.saleprice end)+sum(a.costprice) ml from ABC_INOUTSTOCK a left join gl_custom c on a.clinicid=c.c_abcid where a.action in ('发药','退药') and to_date(substr(a.fdate,1,10),'yyyy-mm-dd') between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by c.tjbh) c on a.tjbh=c.tjbh left join (select tjbh,sum(jshj) ml from abc where producttype not in ('1','2','7') and productid not in ('00000000000000000000000000000007','00000000000000000000000000000003','00000000000000000000000000000004','00000000000000000000000000000008', '00000000000000000000000000000010') group by tjbh) b on a.tjbh=b.tjbh left join (select tjbh,sum(jshj) jshj from abc where FEETYPE1 like '%充值%' group by tjbh) d on a.tjbh=d.tjbh ), zyy as (select a.subbh,sum(a.jshj) jshj from hzxs a inner join yw_kck b on a.hedgehh=b.hh left join gl_ryk c on a.xsr=c.dh where b.fzflsx1='08'group by a.subbh union select tjbh,sum(jshj) jshj from abc where FEETYPE1<>'西药' and FEETYPE1<>'中成药'and FEETYPE1<>'卡项充值本金' and FEETYPE1<>'会员充值本金' group by tjbh ), --zyml as (select subbh,abs(sum(ml)) ml from hzxs where ml<0 and sl>0 and hedgehh in (select hh from c_zkmdbmlpzmx) group by subbh), rw as (select a.subbh,round(nvl(a.yxse*(b.xsxs/100),0),0) xsrw,round(a.ymle*(d.xsxs/100),0) mlrw,round(nvl(a.ybbxse*(c.xsxs/100),0),0) tyrw from (select subbh,yxse,ybbxse,ymle from c_mdjyys where nd='0' and yf='0') a left join (select a.rwlb,sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='绩效销售额任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by a.rwlb) b on 1=1 left join (select a.rwlb,sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='月毛利额任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by a.rwlb) d on 1=1 left join (select a.rwlb,sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='特药任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by a.rwlb) c on 1=1), zyrw as (select a.subbh,a.pzlb,a.rwje*(b.xsxs/100) rwje from (select * from c_zbjlrwzk where nd='0' and yf='0' and pzlb='中药任务') a left join (select sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='中药任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1)) b on 1=1), nfrw as (select a.subbh,a.pzlb,a.rwje*(b.xsxs/100) rwje from (select * from c_zbjlrwzk where nd='0' and yf='0' and pzlb='膏方任务') a left join (select sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='膏方任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1)) b on 1=1), gfrw as (select a.subbh,a.pzlb,a.rwje*(b.xsxs/100) rwje from (select * from c_zbjlrwzk where nd='0' and yf='0' and pzlb='内方基础任务') a left join (select sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='内方任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1)) b on 1=1), zdpzrw as (select a.subbh,a.pzlb,a.rwje*(b.xsxs/100) rwje from (select * from c_zbjlrwzk where nd='0' and yf='0' and pzlb='重点品种任务') a left join (select sum(b.xsxs) xsxs from C_ZKMTXSSCB a left join C_ZKMTXSSCBDETAIL b on a.guid=b.mainguid where a.rwlb='重点品种任务' and trunc(b.ksrq) between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1)) b on 1=1), zdpz as (select b.subbh,sum(b.jshj) jshj from (select a.code,b.hh,b.sx from organization a left join spjxlbz b on a.SPJXFLZ=b.lbz where b.sx='A+' OR b.sx='B' OR b.sx='A'OR b.sx='D+') a inner join (select subbh,hedgehh,jshj,lsh from hzxs union all select tjbh,hh,jshj,' ' from abc ) b on a.code=b.subbh and a.hh=b.hedgehh group by b.subbh), gfxs as (select a.subbh,sum(a.jshj) jshj from hzxs a left join yw_kck b on a.hedgehh=b.hh where nvl(a.posguid,' ')='10001' or b.fzflsx2='08042' group by a.subbh), xsfl as (select a.*,c.sx from (select subbh,hedgehh,jshj,ml,lsh from hzxs union all select tjbh,hh,jshj,0,' ' from abc ) a left join(select * from spjxlbz where lbz='1') c on a.hedgehh=c.hh) select a.c_mdfq 大区,a.c_mdfq1 地区,a.tjbh 门店编号,a.mc 门店名称,nvl(b.xsrw,0)+nvl(b.tyrw,0) 总销售任务,c.jshj 总销售额,b.mlrw 毛利任务,nvl(c.ml,0)-nvl(y6.ml,0) 毛利额,k.rwje 重点品种任务,nvl(e.jshj,0)+nvl(i.jshj,0) 重点品种销售, j.jshj 中医药销售,to_char(a.c_kykdrq,'yyyy-mm-dd') 开业日期,case when t1.SPJXFLZ='1' then '郑州市' when t1.SPJXFLZ='2' then '外地市' when t1.SPJXFLZ='3' then '县乡镇' else ' ' end 地域类型,round((nvl(f.rwje,0)+nvl(g.rwje,0)+nvl(h.rwje,0)),2) 中医药任务, case when nvl(b.mlrw,0)<>0 then round( (nvl(c.ml,0)-nvl(y6.ml,0))*100/b.mlrw,2) else 0 end 毛利进度,nvl(x.jshj,0) 线下销售额,nvl(x.kds,0) 线下客单,nvl(c.kds,0) 总客流, case when nvl(k.rwje,0)<>0 then round((nvl(e.jshj,0)+nvl(i.jshj,0))*100/k.rwje,2) else 0 end 重点品种进度,case when nvl(b.tyrw,0)=0 then 0 else nvl(y6.jshj,0) end 特药销售,b.tyrw 特药任务, case when nvl(b.tyrw,0)<>0 then round((case when nvl(b.tyrw,0)=0 then 0 else nvl(y6.jshj,0) end)*100/b.tyrw,2) else 0 end 特药完成进度, nvl(b.xsrw,0) 非特药任务, case when nvl(b.tyrw,0)=0 then nvl(c.jshj,0) else nvl(c.jshj,0)-nvl(y6.jshj,0) end 非特药销售,case when nvl(b.xsrw,0)<>0 then round((case when nvl(b.tyrw,0)=0 then nvl(c.jshj,0) else nvl(c.jshj,0)-nvl(y6.jshj,0) end)*100/nvl(b.xsrw,0),2) else 0 end 非特药完成进度 from gl_custom a left join rw b on a.tjbh=b.subbh left join xs c on a.tjbh=c.subbh left join zyrw f on a.tjbh=f.subbh left join nfrw g on a.tjbh=g.subbh left join gfrw h on a.tjbh=h.subbh left join zyy j on a.tjbh=j.subbh left join zdpz e on a.tjbh=e.subbh left join gfxs i on a.tjbh=i.subbh left join zdpzrw k on a.tjbh=k.subbh left join organization t1 on a.tjbh=t1.code left join (select subbh,sum(jshj) jshj,sum(ml) ml,count(distinct lsh) kds from hzxs where nvl(posguid,' ')<>'10000' group by subbh) x on a.tjbh=x.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'A+' group by subbh) y1 on a.tjbh=y1.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'C+' group by subbh) y2 on a.tjbh=y2.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'A' group by subbh) y3 on a.tjbh=y3.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'B' group by subbh) y4 on a.tjbh=y4.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'C' OR sx = 'C ' group by subbh) y5 on a.tjbh=y5.subbh left join (select subbh,sum(jshj) jshj,sum(ml) ml from xsfl where sx = 'D' group by subbh) y6 on a.tjbh=y6.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'E' group by subbh) y7 on a.tjbh=y7.subbh left join (select subbh,sum(jshj) jshj from xsfl where sx = 'F' OR sx = 'f' group by subbh) y8 on a.tjbh=y8.subbh where a.c_mdfq is not null and (a.tj_tag='14' or a.tj_tag='40') --and a.mc like '%仲景生活%' and nvl(a.C_STORETYPE, '0') = '1' """ return sql def generate_g3_weekly_sql(): """生成月度G3周度销售数据查询SQL""" sql = """ ---------仲景生活周度数据通报(月度) select b.TJBH as 门店编号,b.mc as 门店名称,TRUNC(a.kdrq) as 日期,d.name as 零售小类,a.hh as 货号,c.pm as 品名,sum(a.SL) as 数量 ,sum(a.jshj) as 销售额,case when nvl(sum(SL),0)<>0 then round(sum(cbe) / sum(SL), 2) else 0 end as 成本价, sum(a.ML) as 毛利, case when nvl(sum(a.JSHJ),0)<>0 then round(sum(ml) / sum(JSHJ), 2) else 0 end as 毛利率,c.hyj as 会员价,c.lsj as 零售价 from subfhd a left join gl_custom b on a.subbh=b.tjbh left join yw_kck c on a.hh = c.HH left join dataitem d on c.FZFLSX3 = d.CODE where a.kdrq between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and nvl(a.bz,' ')<>'会员礼品成本调整单' and nvl(a.bz,' ')<>'¥' and nvl(a.bm,' ')<>'积分兑换' and b.tj_tag<>'40' and nvl(b.C_STORETYPE, '0') = '1' group by b.TJBH, b.mc, TRUNC(a.kdrq), d.name, a.hh, c.pm, c.lsj, c.hyj order by b.tjbh, TRUNC(a.kdrq) """ return sql def generate_g3_daily_monthly_sql(): """生成月度G3每日销售数据查询SQL""" sql = """ ------门店每日总销售额(月度) select a.kdrq 日期,a.subbh 门店编码,a.mc 门店名称,a.jshj 价税合计,nvl(a.jshj-dx.dxje,a.jshj) 总销售额,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/j.xxkl,2) 线下客单价,nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0) 线下价税合计, (case when nvl(a.jshj,0)=0 then 0 else round(a.hsmle/a.jshj,4) end) 毛利率,sum(a.khs) 客户数,sum(a.hykds) 会员客单数,sum((case when nvl(a.khs,0)=0 then 0 else round(nvl(a.jshj,0)/a.khs,4) end)) 客单价,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) 线上销售额占比, a.hsmle 毛利额,a.hyxse 会员销售额,dx.dxje 积分抵现金额,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/i.xskl,2) 线上客单价,nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0) 线上价税合计, (case when nvl(a.jshj,0)=0 then 0 else 100*round(nvl(a.hyxse,0)/a.jshj,4) end) 会员销售占比,b.hyqb 会员钱包销售额,xs.fkje 惜食小程序,d.fkje 饿了么,c.fkje 美团外卖,f.fkje 美团点评,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) 线下销售额占比, h.fkje 收钱吧,g.fkje 抖音团购,i.xskl 线上客单数,j.xxkl 线下客单数 from ( select a.kdrq kdrq,b.mc mc,a.subbh subbh,ROUND(sum(a.jshj),2) jshj,sum(c.sj1) sj1, count(distinct a.lsh) as khs,count(distinct case when nvl(a.YHKH,' ')<>' ' then a.lsh else ' ' end) hykds, sum(case when nvl(a.yhkh,' ')<>' ' then a.jshj else 0 end) hyxse, sum(a.ml) hsmle,sum(a.ml) ml from subfhd a right join (select * from gl_custom where nvl(c_storetype,0)=1) b on a.subbh=b.tjbh right join (select * from yw_kck ) c on a.hh=c.hh where a.Kdrq between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and nvl(a.bz,' ')<>'会员礼品成本调整单' and nvl(a.bz,' ')<>'¥' group by a.subbh,a.kdrq,b.mc ) a left join (select kdrq,subbh,sum(jshj) dxje from subfhd where kdrq between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and hh='JFDX' group by subbh, kdrq ) dx on (a.subbh=dx.subbh and a.kdrq=dx.kdrq) left join ( select a.KDRQ,a.subbh,sum(a.fkje) hyqb from subdfkfs a inner join (select tjbh from gl_custom where nvl(c_storetype,0)=1) b on a.subbh=b.tjbh where a.fkfsid='hyqb' and KDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) group by a.subbh,a.KDRQ ) b on (a.subbh=b.subbh and a.kdrq=b.kdrq) left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('SY-MTWM') group by SUBBH, KDRQ) c on a.subbh=c.subbh and a.kdrq=c.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('SYELM') group by SUBBH, KDRQ) d on a.subbh=d.subbh and a.kdrq=d.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('197') group by SUBBH, KDRQ) f on a.subbh=f.subbh and a.kdrq=f.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('801') group by SUBBH, KDRQ) g on a.subbh=g.subbh and a.kdrq=g.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('806') group by SUBBH, KDRQ) h on a.subbh=h.subbh and a.kdrq=h.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('215') group by SUBBH, KDRQ) xs on a.subbh=xs.subbh and a.kdrq=xs.kdrq left join (select SUBBH, KDRQ,count(distinct xhlsh) xskl from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid in ('SY-MTWM','SYELM','197','801','808','215') group by SUBBH, KDRQ) i on a.subbh=i.subbh and a.kdrq=i.kdrq left join (select SUBBH, KDRQ,count(distinct xhlsh) xxkl from subdfkfs where kDRQ between TRUNC(SYSDATE-1,'MONTH') and TRUNC(SYSDATE-1) and fkfsid not in ('SY-MTWM','SYELM','197','801','808','215') group by SUBBH, KDRQ) j on a.subbh=j.subbh and a.kdrq=j.kdrq group by a.subbh, a.mc, a.kdrq, a.jshj, a.hsmle,a.ml,b.hyqb,a.hyxse, (case when nvl(a.jshj,0)=0 then 0 else round(a.hsmle/a.jshj,4) end), dx.dxje, nvl(a.jshj-dx.dxje,a.jshj), (case when nvl(a.jshj,0)=0 then 0 else 100*round(nvl(a.hyxse,0)/a.jshj,4) end),c.fkje,d.fkje,f.fkje,g.fkje,h.fkje,xs.fkje,nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0) ,nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0) ,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) ,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) ,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/i.xskl,2) ,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/j.xxkl,2),i.xskl,j.xxkl order by a.subbh """ return sql def generate_g3_daily_yesterday_sql(): """生成昨日G3每日销售数据查询SQL""" sql = """ ------门店每日总销售额(昨日) select a.kdrq 日期,a.subbh 门店编码,a.mc 门店名称,a.jshj 价税合计,nvl(a.jshj-dx.dxje,a.jshj) 总销售额,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/j.xxkl,2) 线下客单价,nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0) 线下价税合计, (case when nvl(a.jshj,0)=0 then 0 else round(a.hsmle/a.jshj,4) end) 毛利率,sum(a.khs) 客户数,sum(a.hykds) 会员客单数,sum((case when nvl(a.khs,0)=0 then 0 else round(nvl(a.jshj,0)/a.khs,4) end)) 客单价,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) 线上销售额占比, a.hsmle 毛利额,a.hyxse 会员销售额,dx.dxje 积分抵现金额,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/i.xskl,2) 线上客单价,nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0) 线上价税合计, (case when nvl(a.jshj,0)=0 then 0 else 100*round(nvl(a.hyxse,0)/a.jshj,4) end) 会员销售占比,b.hyqb 会员钱包销售额,xs.fkje 惜食小程序,d.fkje 饿了么,c.fkje 美团外卖,f.fkje 美团点评,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) 线下销售额占比, h.fkje 收钱吧,g.fkje 抖音团购,i.xskl 线上客单数,j.xxkl 线下客单数 from ( select a.kdrq kdrq,b.mc mc,a.subbh subbh,ROUND(sum(a.jshj),2) jshj,sum(c.sj1) sj1, count(distinct a.lsh) as khs,count(distinct case when nvl(a.YHKH,' ')<>' ' then a.lsh else ' ' end) hykds, sum(case when nvl(a.yhkh,' ')<>' ' then a.jshj else 0 end) hyxse, sum(a.ml) hsmle,sum(a.ml) ml from subfhd a right join (select * from gl_custom where nvl(c_storetype,0)=1) b on a.subbh=b.tjbh right join (select * from yw_kck ) c on a.hh=c.hh where a.Kdrq = TRUNC(SYSDATE-1) and nvl(a.bz,' ')<>'会员礼品成本调整单' and nvl(a.bz,' ')<>'¥' group by a.subbh,a.kdrq,b.mc ) a left join (select kdrq,subbh,sum(jshj) dxje from subfhd where kdrq = TRUNC(SYSDATE-1) and hh='JFDX' group by subbh, kdrq ) dx on (a.subbh=dx.subbh and a.kdrq=dx.kdrq) left join ( select a.KDRQ,a.subbh,sum(a.fkje) hyqb from subdfkfs a inner join (select tjbh from gl_custom where nvl(c_storetype,0)=1) b on a.subbh=b.tjbh where a.fkfsid='hyqb' and KDRQ = TRUNC(SYSDATE-1) group by a.subbh,a.KDRQ ) b on (a.subbh=b.subbh and a.kdrq=b.kdrq) left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('SY-MTWM') group by SUBBH, KDRQ) c on a.subbh=c.subbh and a.kdrq=c.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('SYELM') group by SUBBH, KDRQ) d on a.subbh=d.subbh and a.kdrq=d.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('197') group by SUBBH, KDRQ) f on a.subbh=f.subbh and a.kdrq=f.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('801') group by SUBBH, KDRQ) g on a.subbh=g.subbh and a.kdrq=g.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('806') group by SUBBH, KDRQ) h on a.subbh=h.subbh and a.kdrq=h.kdrq left join (select SUBBH, KDRQ,sum(fkje) fkje from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('215') group by SUBBH, KDRQ) xs on a.subbh=xs.subbh and a.kdrq=xs.kdrq left join (select SUBBH, KDRQ,count(distinct xhlsh) xskl from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid in ('SY-MTWM','SYELM','197','801','808','215') group by SUBBH, KDRQ) i on a.subbh=i.subbh and a.kdrq=i.kdrq left join (select SUBBH, KDRQ,count(distinct xhlsh) xxkl from subdfkfs where kDRQ = TRUNC(SYSDATE-1) and fkfsid not in ('SY-MTWM','SYELM','197','801','808','215') group by SUBBH, KDRQ) j on a.subbh=j.subbh and a.kdrq=j.kdrq group by a.subbh, a.mc, a.kdrq, a.jshj, a.hsmle,a.ml,b.hyqb,a.hyxse, (case when nvl(a.jshj,0)=0 then 0 else round(a.hsmle/a.jshj,4) end), dx.dxje, nvl(a.jshj-dx.dxje,a.jshj), (case when nvl(a.jshj,0)=0 then 0 else 100*round(nvl(a.hyxse,0)/a.jshj,4) end),c.fkje,d.fkje,f.fkje,g.fkje,h.fkje,xs.fkje,nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0) ,nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0) ,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) ,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/NULLIF(nvl(a.jshj, 0), 0)*100,2) ,round((nvl(c.fkje,0)+nvl(d.fkje,0)+nvl(f.fkje,0)+nvl(g.fkje,0)+nvl(xs.fkje,0))/i.xskl,2) ,round((nvl(a.jshj,0)-nvl(c.fkje,0)-nvl(d.fkje,0)-nvl(f.fkje,0)-nvl(g.fkje,0)-nvl(xs.fkje,0))/j.xxkl,2),i.xskl,j.xxkl order by a.subbh """ return sql def update_excel_sheet(excel_path, sheet_name, data, columns): """更新Excel指定sheet的数据 - 清空整个sheet后放入数据(包括标题行)""" try: # 加载工作簿 wb = load_workbook(excel_path) # 选择指定sheet if sheet_name in wb.sheetnames: ws = wb[sheet_name] else: ws = wb.create_sheet(sheet_name) # 清空整个工作表的所有数据 ws.delete_rows(1, ws.max_row) # 创建DataFrame(包含标题行) df = pd.DataFrame(data, columns=columns) # 将数据写入sheet(包括标题行) for r_idx, row in enumerate(dataframe_to_rows(df, index=False, header=True), 1): for c_idx, value in enumerate(row, 1): ws.cell(row=r_idx, column=c_idx, value=value) # 保存工作簿 wb.save(excel_path) print(f"成功更新 {sheet_name} 工作表,共 {len(data)} 行数据") return True except Exception as e: print(f"更新Excel失败: {str(e)}") return False def update_excel_data(excel_path): """更新Excel文件中的所有G3销售数据""" try: print("开始更新Excel数据...") # 更新月度G3阶段数据 print("正在查询月度G3阶段数据...") sql1 = generate_g3_monthly_sql() data1, columns1 = oracle_connect(sql1) if data1: print(f"查询到月度G3阶段数据 {len(data1)} 行") update_excel_sheet(excel_path, "月度G3阶段", data1, columns1) else: print("未查询到月度G3阶段数据") # 更新月度G3周度销售数据 print("正在查询月度G3周度销售数据...") sql2 = generate_g3_weekly_sql() data2, columns2 = oracle_connect(sql2) if data2: print(f"查询到月度G3周度销售数据 {len(data2)} 行") update_excel_sheet(excel_path, "月度G3周度销售", data2, columns2) else: print("未查询到月度G3周度销售数据") # 更新月度G3每日销售数据 print("正在查询月度G3每日销售数据...") sql3 = generate_g3_daily_monthly_sql() data3, columns3 = oracle_connect(sql3) if data3: print(f"查询到月度G3每日销售数据 {len(data3)} 行") update_excel_sheet(excel_path, "月度G3每日销售", data3, columns3) else: print("未查询到月度G3每日销售数据") # 更新昨日G3每日销售数据 print("正在查询昨日G3每日销售数据...") sql4 = generate_g3_daily_yesterday_sql() data4, columns4 = oracle_connect(sql4) if data4: print(f"查询到昨日G3每日销售数据 {len(data4)} 行") update_excel_sheet(excel_path, "昨日G3每日销售", data4, columns4) else: print("未查询到昨日G3每日销售数据") print("Excel数据更新完成") return True except Exception as e: print(f"更新Excel数据失败: {str(e)}") return False class ExcelScreenshot: """Excel截图类,处理COM初始化问题""" def __init__(self): self.excel_app = None self.workbook = None def initialize_com(self): """初始化COM对象""" try: pythoncom.CoInitialize() self.excel_app = win32.gencache.EnsureDispatch('Excel.Application') self.excel_app.Visible = True self.excel_app.DisplayAlerts = False return True except Exception as e: print(f"COM初始化失败: {str(e)}") return False def open_workbook(self, excel_path): """打开工作簿""" try: if not self.excel_app: if not self.initialize_com(): return False self.workbook = self.excel_app.Workbooks.Open(excel_path) return True except Exception as e: print(f"打开工作簿失败: {str(e)}") return False def capture_sheet(self, sheet_name, screenshot_path): """截图指定工作表""" try: if not self.workbook: return False # 选择工作表 worksheet = self.workbook.Sheets(sheet_name) self.workbook.Windows(1).Activate() worksheet.Activate() # 获取有数据的区域 used_range = worksheet.UsedRange if used_range is None: print(f"{sheet_name} 工作表没有数据") return False used_range.Select() # 等待Excel刷新 time.sleep(2) # 复制选中的区域 worksheet.Range(used_range.Address).CopyPicture(Appearance=1, Format=2) # 从剪贴板获取图片并保存 time.sleep(1) image = ImageGrab.grabclipboard() if image: image.save(screenshot_path) return True else: return False except Exception as e: print(f"截图 {sheet_name} 失败: {str(e)}") return False def close(self): """关闭Excel应用""" try: if self.workbook: self.workbook.Close(SaveChanges=False) if self.excel_app: self.excel_app.Quit() pythoncom.CoUninitialize() except Exception as e: print(f"关闭Excel失败: {str(e)}") def capture_excel_screenshots(excel_path): """截图Excel的四个sheet表有数据的区域""" screenshot = ExcelScreenshot() screenshot_paths = [] try: print("开始截图Excel工作表...") # 初始化并打开工作簿 if not screenshot.open_workbook(excel_path): raise Exception("无法打开Excel文件") sheet_names = ["销售", "品类", "主推品", "昨日销售"] for sheet_name in sheet_names: try: print(f"正在截图 {sheet_name} 工作表...") screenshot_path = f"D:\\仲景生活\\{sheet_name}_截图_{dt.datetime.now().strftime('%Y%m%d%H%M%S')}.png" if screenshot.capture_sheet(sheet_name, screenshot_path): screenshot_paths.append(screenshot_path) print(f"成功截图 {sheet_name} 工作表,保存为: {screenshot_path}") else: print(f"截图失败 {sheet_name} 工作表") except Exception as e: print(f"截图 {sheet_name} 失败: {str(e)}") continue print(f"截图完成,共生成 {len(screenshot_paths)} 张截图") return screenshot_paths except Exception as e: print(f"截图Excel失败: {str(e)}") return [] finally: screenshot.close() def application_push_image(access_token, image_path, user_id="037565", agent_id="1000077"): """推送图片到企业微信应用""" try: # 上传图片获取media_id with open(image_path, 'rb') as f: files = {'media': f} upload_url = f'https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}&type=image' upload_response = requests.post(upload_url, files=files).json() if 'media_id' not in upload_response: print(f"图片上传失败: {upload_response}") return None media_id = upload_response['media_id'] # 发送图片消息 send_url = f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={access_token}' payload = { "touser": user_id, "msgtype": "image", "agentid": agent_id, "image": {"media_id": media_id}, "safe": 0 } response = requests.post(send_url, json=payload).json() return response except Exception as e: print(f"图片发送失败: {str(e)}") return None def webhook_push_image(image_path, webhook_url): """通过webhook推送图片到企业微信群""" try: # 读取图片并转换为base64 with open(image_path, 'rb') as f: image_data = f.read() # 上传到临时位置或直使用base64 image_base64 = base64.b64encode(image_data).decode('utf-8') # 构建消息内容 payload = { "msgtype": "image", "image": { "base64": image_base64, "md5": hashlib.md5(image_data).hexdigest() } } response = requests.post(webhook_url, json=payload) return response.json() except Exception as e: print(f"Webhook图片发送失败: {str(e)}") return None def send_excel_report(): """发送Excel报表截图""" try: print(f"{dt.datetime.now()} - 开始执行Excel报表推送任务") # 初始化微信 wechat = Wechat('tXNMrgcTgeV3IAqJhWB7mOe_bcKe9EtdCDze_75mGeY') access_token = wechat.access_token() # 群webhook地址 webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=3cb06b7e-3658-4fbd-9676-54fc25fea470" excel_path = r"D:\仲景生活\月度销售汇总.xlsx" # 检查文件是否存在 if not os.path.exists(excel_path): print(f"Excel文件不存在: {excel_path}") # 创建空的Excel文件 wb = load_workbook() wb.save(excel_path) print("已创建新的Excel文件") # 更新Excel数据 if not update_excel_data(excel_path): raise Exception("Excel数据更新失败") # 截图四个sheet表 screenshot_paths = capture_excel_screenshots(excel_path) if not screenshot_paths: print("Excel截图失败,尝试使用备用截图方法...") # 备用方案:使用pyautogui截图 screenshot_paths = capture_with_pyautogui(excel_path) if not screenshot_paths: raise Exception("所有截图方法都失败了") # 推送所有截图到个人 success_count_personal = 0 for image_path in screenshot_paths: if os.path.exists(image_path): print(f"正在推送图片到个人: {os.path.basename(image_path)}") result = application_push_image(access_token, image_path, "037565") if result and result.get('errcode') == 0: success_count_personal += 1 print(f"成功发送到个人: {os.path.basename(image_path)}") else: print(f"发送到个人失败: {os.path.basename(image_path)} - {result}") # 推送所有截图到群 success_count_group = 0 for image_path in screenshot_paths: if os.path.exists(image_path): print(f"正在推送图片到群: {os.path.basename(image_path)}") result = webhook_push_image(image_path, webhook_url) if result and result.get('errcode') == 0: success_count_group += 1 print(f"成功发送到群: {os.path.basename(image_path)}") else: print(f"发送到群失败: {os.path.basename(image_path)} - {result}") # 删除已发送的截图 for image_path in screenshot_paths: if os.path.exists(image_path): os.remove(image_path) print(f"已删除截图文件: {os.path.basename(image_path)}") print(f"{dt.datetime.now()} - Excel报表推送完成") print(f"个人成功发送: {success_count_personal}/{len(screenshot_paths)}") print(f"群成功发送: {success_count_group}/{len(screenshot_paths)}") return success_count_personal > 0 or success_count_group > 0 except Exception as e: print(f"{dt.datetime.now()} - Excel报表推送失败: {str(e)}") import traceback traceback.print_exc() return False def capture_with_pyautogui(excel_path): """备用截图方法:使用pyautogui""" try: import pyautogui import subprocess import time # 使用Excel打开文件 subprocess.Popen([excel_path], shell=True) time.sleep(5) screenshot_paths = [] sheet_names = ["销售", "品类", "主推品", "昨日销售"] for sheet_name in sheet_names: try: # 这里需要根据实际情况调整截图区域 screenshot_path = f"D:\\仲景生活\\{sheet_name}_截图_{dt.datetime.now().strftime('%Y%m%d%H%M%S')}.png" # 全屏截图(需要手动调整) screenshot = pyautogui.screenshot() screenshot.save(screenshot_path) screenshot_paths.append(screenshot_path) print(f"使用pyautogui截图: {screenshot_path}") except Exception as e: print(f"pyautogui截图失败: {str(e)}") continue return screenshot_paths except Exception as e: print(f"备用截图方法失败: {str(e)}") return [] def run_scheduler(): """运行定时任务""" # 每天早上8:30执行 schedule.every().day.at("08:30").do(send_excel_report) # 立即测试一次 print(f"{dt.datetime.now()} - 正在执行首次测试...") send_excel_report() while True: schedule.run_pending() time.sleep(60) if __name__ == '__main__': print(f'程序启动时间: {dt.datetime.now()}') # 确保目录存在 output_dir = r'D:\仲景生活' if not os.path.exists(output_dir): os.makedirs(output_dir) print(f"已创建目录: {output_dir}") # 启动定时任务线程 scheduler_thread = Thread(target=run_scheduler) scheduler_thread.daemon = True scheduler_thread.start() try: while True: time.sleep(60) except KeyboardInterrupt: print("程序已停止") 推送的截图中销售的图右侧有过多无数据区域,品类下侧有部分无数据区域,昨日销售右侧有部分无数据区域,修正代码,自动精确截图区域 只写出需要修改部分代码
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值