
Python建立Map寫Excel表實(shí)例解析
本文主要研究的是用Python語言建立Map寫Excel表的相關(guān)代碼,具體如下。
前言:我們已經(jīng)能夠很熟練的寫Excel表相關(guān)的腳本了。大致的操作就是,從數(shù)據(jù)庫中取數(shù)據(jù),建立Excel模板,然后根據(jù)模板建立一個(gè)新的Excel表,把數(shù)據(jù)庫中的數(shù)據(jù)寫入。最后發(fā)送郵件。之前的一篇記錄博客,寫的很標(biāo)準(zhǔn)了。這里我們說點(diǎn)遇到的新問題。
我們之前寫類似腳本的時(shí)候,有個(gè)問題沒有考慮過,為什么要建立模板然后再寫入數(shù)據(jù)呢?誒…其實(shí)也不算是沒考慮過,只是懶沒有深究罷了。只求快點(diǎn)完成任務(wù)。。。
這里對(duì)這個(gè)問題進(jìn)行思考闡述!
【為什么要建立Excel表模板?】
建立Excel模板,是涉及到歷史數(shù)據(jù)才要建立模板的,為什么呢?
如果,我們需要一份數(shù)據(jù)表,這個(gè)表中是本月的數(shù)據(jù),每天跑一行出來。到了下個(gè)月,就需要新建下一個(gè)月的表。
這樣以后進(jìn)行數(shù)據(jù)統(tǒng)計(jì)的時(shí)候,我們只需要拿到每個(gè)月的最后一天的那份數(shù)據(jù)表就可以了,因?yàn)樽詈笠惶斓臄?shù)據(jù)表包含了當(dāng)月的所有數(shù)據(jù)。
對(duì)于這樣一個(gè)需求,腳本中的代碼在月份改變時(shí),肯定要新建一個(gè)表,不再將原來的表作為模板來寫。
自然,下一個(gè)月的表肯定不能把上一個(gè)月的數(shù)據(jù)帶進(jìn)去,所以肯定需要新寫表頭。
這里往深了思考,就涉及到了另外一個(gè)問題。
【建立Excel模板的方法的本質(zhì)】
def createTemplateExcel():
'''創(chuàng)建Excel文件模板'''
wb = xlwt.Workbook(encoding = "UTF-8", style_compression = True)
sht0 = wb.add_sheet("線上", cell_overwrite_ok = True)
sht0.col(0).width=4000
sht0.write(0, 0, '游戲名稱', style1)
sht0.write(0, 1, '渠道', style1)
sht0.write(0, 2, '成交量', style1)
sht0.write(0, 3, '下單量', style1)
sht0.write(0, 4, '失敗量', style1)
sht1 = wb.add_sheet("線下", cell_overwrite_ok = True)
sht1.col(0).width=4000
sht1.write(0, 0, '游戲名稱', style1)
sht1.write(0, 1, '成交量', style1)
sht1.write(0, 2, '下單量', style1)
sht1.write(0, 3, '失敗量', style1)
return wb
或者
wb.save(tempFileName)
這個(gè)所謂的建立模板的方法做了什么事情呢?
只是建立了自定義名字的sheet,然后將表頭寫進(jìn)去了而已。所以建立模板的方法本質(zhì)上實(shí)際上就是寫表頭。
我們可以return wb,也可以wb.save(tempFileName)
即,我們可以把寫好的表頭直接return,接著下面的寫數(shù)據(jù)的方法用。
也可以,直接保存一個(gè)模板Excel表出來放在腳本后臺(tái)用。每次需要寫新表的時(shí)候就去調(diào)用生成的模板。
這里的問題還可以更加深。。。
【有了寫表頭的所謂建立模板方法,保存模板文件是否還有必要?】
其實(shí)又是個(gè)平衡問題。我們是每次調(diào)方法來寫表頭,消耗運(yùn)行時(shí)間。還是直接調(diào)用已經(jīng)寫好的模板文件呢?直接調(diào)用雖然快,但是模板文件會(huì)占用腳本后臺(tái)的空間。
怎么樣劃算呢?選時(shí)間還是空間?
而且有個(gè)問題,寫一定就比調(diào)用慢嗎?如果寫比調(diào)用快,既省時(shí)間又省空間,只不過代碼中多了個(gè)寫表頭的方法而已。
還方便后期維護(hù)。
說到這里,就有一個(gè)矛盾的地方了。我們既然已經(jīng)有了寫表頭的操作了。還需要把它保存為模板文件放起來嗎?
每次運(yùn)行的時(shí)候直接寫不就行了嗎?為什么還要保存?
保存起來除了占空間,用于調(diào)用(實(shí)質(zhì)上完全可以不調(diào)用直接寫),還有什么用呢?
這是一個(gè)值得改進(jìn)的地方。。。吧
【關(guān)于建立模板方法相關(guān)的個(gè)人暫處理辦法】
目前我自己能夠想到的方法是,以后不再額外保存模板文件出來。寫表頭就是寫表頭,直接return,和后面的方法串起來就可以了。
每次月份改變的時(shí)候,即到了該月第一天寫該月的第一張表的時(shí)候,去調(diào)用這個(gè)寫表頭的方法就可以了。
好了,第一個(gè)問題過去。接下來闡述第二個(gè)問題?
【從數(shù)據(jù)庫取數(shù)據(jù),進(jìn)行處理以后,再寫入】
我們之前寫Excel表的時(shí)候,大多數(shù)的情況是,直接將取到的數(shù)據(jù)寫入Excel表對(duì)應(yīng)位置。
取數(shù)據(jù)都是一樣的方法模板。數(shù)據(jù)處理發(fā)生在寫入的時(shí)候。遇到過的,需要處理的情況有兩種:
1. 需要調(diào)用Excel相關(guān)函數(shù),比如SUM等。需要用到這個(gè)
xlwt.Formula
2. 需要將數(shù)據(jù)進(jìn)行除運(yùn)算外的處理。我們處理本例的需求時(shí)遇到的就是這種情況。
【需求】
將數(shù)據(jù)庫中每個(gè)游戲的成交量、下單量、失敗量取出來。寫一張如下的表出來:
關(guān)鍵需要處理的問題是:每個(gè)游戲的三項(xiàng)數(shù)據(jù),每項(xiàng)數(shù)據(jù)是單獨(dú)對(duì)應(yīng)一個(gè)SQL取出來的,即,每項(xiàng)單獨(dú)取,排序是不一樣的。
如果直接寫到Excel表中,是這樣子的
可以看到,排序是亂的。我們需要把這些數(shù)據(jù)按名字進(jìn)行一一對(duì)應(yīng)的處理,生成一張第一個(gè)圖所示的表出來。
這里就是數(shù)據(jù)處理需要用什么方法的問題?
【如何進(jìn)行數(shù)據(jù)處理?】
之前想到的方法是:
可以看到,排序是亂的。我們需要把這些數(shù)據(jù)按名字進(jìn)行一一對(duì)應(yīng)的處理,生成一張第一個(gè)圖所示的表出來。
這里就是數(shù)據(jù)處理需要用什么方法的問題?
【如何進(jìn)行數(shù)據(jù)處理?】
之前想到的方法是:
def writeInfo0(sht, rs, length, rs2, length2, rs3, length3):
'''寫入線上具體數(shù)據(jù)'''
for j in range(length2):
sht.write(j+1, 0, str(rs2[j][0]).decode('utf-8'), style1)
sht.write(j+1, 1, str(rs2[j][1]).decode('utf-8'), style1)
sht.write(j+1, 3, rs2[j][2], style1)
for j in range(length2):
for i in range(length):
if (str(rs[i][0])==str(rs2[j][0])) and (str(rs[i][1])==str(rs2[j][1])):
sht.write(j+1, 2, rs[i][2], style1)
for j in range(length2):
for k in range(length3):
if (str(rs3[k][0])==str(rs2[j][0])) and (str(rs3[k][1])==str(rs2[j][1])):
sht.write(j+1, 4, rs3[k][2], style1)
直接進(jìn)行寫入。先寫入最多的 ,然后寫入較少的。而較少的兩項(xiàng)寫入時(shí),根據(jù)名字的對(duì)應(yīng),放在對(duì)應(yīng)的位置。
這樣寫可以,但是有兩個(gè)問題:
1. 我們需要沒有數(shù)據(jù)的地方顯示為零。怎么判斷并寫入呢?是個(gè)問題,而且還挺麻煩的。
2. 我們需要數(shù)據(jù)完備,即,能夠保證最多的那項(xiàng)數(shù)據(jù)中的游戲就是所有了嗎?會(huì)不會(huì)每項(xiàng)數(shù)據(jù)對(duì)應(yīng)的數(shù)據(jù),都有自己獨(dú)有的游戲。
如果,最多的游戲條目數(shù)據(jù)中確實(shí)是沒有包含所有,這就是致命的錯(cuò)誤了。數(shù)據(jù)缺失不是小事兒。
還不止這個(gè),我們能夠保證,這個(gè)時(shí)候最多的,明天還是最多嗎?如果明天變成了最少,就會(huì)有很多數(shù)據(jù)因?yàn)槊Q匹配不到而沒有寫入。
還是數(shù)據(jù)缺失,很致命的問題。
所以,這種方法,是有很多漏洞和缺陷的。不可行!
【建立字典DICT處理數(shù)據(jù)】
比較理想的處理方法,也是我們最終采用的方法,是將所有數(shù)據(jù)取出來放入一個(gè)字典中。
在放入的過程中,進(jìn)行數(shù)據(jù)的整理。即,如果有這個(gè)游戲,就直接賦值。如果沒有,新建一個(gè)key,然后寫入。
字典建立好了,包含了所有的數(shù)據(jù)了,再進(jìn)行寫入。是比較可靠的。
這種方法的關(guān)鍵點(diǎn)有兩個(gè):
1. 如何在寫入的時(shí)候進(jìn)行處理?
2. DICT建立好后,如何進(jìn)行寫入?
我們一個(gè)一個(gè)說。
【如何在寫入的時(shí)候,建立DICT處理數(shù)據(jù)?】
先以比較簡單的線下數(shù)據(jù)寫入為例,進(jìn)行說明。
def getInfo1(rs, rs2, rs3):
dict={}
for i in range(len(rs)):
key=str(rs[i][0])
value=rs[i][1]
dict[key]=[value, 0, 0]
dlist=list(dict.keys())
for i in range(len(rs2)):
key2=str(rs2[i][0])
value2=rs2[i][1]
if key2 in dlist:
value=dict[key2][0]
else:
value=0
dict[key2]=[value, value2, 0]
dlist=list(dict.keys())
for i in range(len(rs3)):
key3=str(rs3[i][0])
value3=rs3[i][1]
if key3 in dlist:
value=dict[key3][0]
value2=dict[key3][1]
else:
value=0
value2=0
dict[key3]=[value, value2, value3]
return dict
接收來的rs數(shù)據(jù)是list,一個(gè)游戲?qū)?yīng)一個(gè)數(shù)據(jù)的那種。
我們這樣處理,將游戲名賦給key,將數(shù)據(jù)賦給value。循環(huán)遍歷,建立一個(gè)DICT出來。
接下來是關(guān)鍵的邏輯:如果有,直接賦值;如果沒有,新建一個(gè)key,再寫入。
而這個(gè)關(guān)鍵邏輯中更為關(guān)鍵的邏輯是,如何判斷原來的key中有沒有。
處理方法是這樣的
dlist=list(dict.keys())
for i in range(len(rs2)):
if key2 in dlist: value=dict[key2][0] else: value=0 dict[key2]=[value, value2, 0] 如果有的話,第一個(gè)value的值,從當(dāng)前狀態(tài)的DICT中取。
如果沒有的話,value直接取0。
最后,直接
dict[key2]=[value, value2, 0]
即,key都是當(dāng)下建立的。我們只需要在乎value的值就可以了。
【疑問】
這就有個(gè)疑問了,不會(huì)出現(xiàn)重復(fù)建立key的情況嗎?
不會(huì)。因?yàn)?nbsp;
dict[key2]=[value, value2, 0]
這句代碼,這個(gè)=的符號(hào)。本來就有賦值和新建兩重用法。如果沒有!就是新建,如果有了!就是改變。
只是改變的時(shí)候,我們需要把原來的值也帶進(jìn)去罷了。這個(gè)原來的值是從已經(jīng)有DICT中取到的。。。罷了。
接下來,更為復(fù)雜的代碼也就可以理解了。
dlist=list(dict.keys())
for i in range(len(rs3)):
key3=str(rs3[i][0])
value3=rs3[i][1]
if key3 in dlist:
value=dict[key3][0]
value2=dict[key3][1]
else:
value=0
value2=0
dict[key3]=[value, value2, value3]
return dict
第三項(xiàng)數(shù)據(jù)出現(xiàn)時(shí)建立DICT的情況如上所示。
需要顧及到兩項(xiàng)已經(jīng)寫好的數(shù)據(jù),而已。
【如何將DICT寫入Excel表】
def writeInfo1(sht, dict):
'''寫入線下具體數(shù)據(jù)'''
dlist=list(dict.keys())
for i in range(len(dlist)):
sht.write(i+1, 0, str(dlist[i]).decode('utf-8'), style1)
sht.write(i+1, 1, dict[dlist[i]][0], style1)
sht.write(i+1, 2, dict[dlist[i]][1], style1)
sht.write(i+1, 3, dict[dlist[i]][2], style1)
其實(shí)就是字典的層層剝?nèi)〉姆椒ā?br />
關(guān)鍵就是拿到數(shù)據(jù)而已,拿到了直接寫入!
再稍復(fù)雜的DICT,處理線上數(shù)據(jù)時(shí),我們的鍵有兩個(gè),值有三個(gè)。
我們知道,字典這種數(shù)據(jù)類型,值可以為包含了多個(gè)數(shù)據(jù)的數(shù)組,但是鍵只能夠有一個(gè),且不能為數(shù)組。
該怎么處理呢?我們只能將多個(gè)鍵合并為一個(gè)鍵,然后在寫入的時(shí)候拆開。
關(guān)鍵問題,就是合并和拆分。
【鍵的合并】
key=str(rs[i][0])+'--'+str(rs[i][1])
對(duì),僅此而已。把兩個(gè)數(shù)據(jù)連到一起。合并為一個(gè)字符串。
【寫入時(shí)鍵的拆分】
sht.write(i+1, 0, str(dlist[i]).decode('utf-8').split('--')[0], style1)
sht.write(i+1, 1, str(dlist[i]).decode('utf-8').split('--')[1], style1)
用split函數(shù)。
split函數(shù)對(duì)字符串的拆分,拆分結(jié)果是數(shù)組。按數(shù)組編號(hào)來取分開的數(shù)據(jù)就可以了。
至此,這個(gè)需求的關(guān)鍵問題都已經(jīng)說明完畢。
最后貼一份完整代碼如下。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
__author__ = "$Author: wangxin.xie$"
__version__ = "$Revision: 1.0 $"
__date__ = "$Date: 2018$"
###############################################################
#功能: 訂單情況相關(guān)報(bào)表
###############################################################
import sys
import datetime
import xlwt
from myyutil.DBUtil import DBUtil
reload(sys)
sys.setdefaultencoding('utf8')
#######################全局變量####################################
orderDBUtil = DBUtil('moyoyo_order')
fileDir = 'D://'
fileName = fileDir+'order_message_test2.xls'
style1 = xlwt.XFStyle()
font1 = xlwt.Font()
font1.height = 220
font1.name = 'SimSun'
style1.font = font1
##################################################################
def createTemplateExcel():
'''創(chuàng)建Excel文件模板'''
wb = xlwt.Workbook(encoding = "UTF-8", style_compression = True)
sht0 = wb.add_sheet("線上", cell_overwrite_ok = True)
sht0.col(0).width=4000
sht0.write(0, 0, '游戲名稱', style1)
sht0.write(0, 1, '渠道', style1)
sht0.write(0, 2, '成交量', style1)
sht0.write(0, 3, '下單量', style1)
sht0.write(0, 4, '失敗量', style1)
sht1 = wb.add_sheet("線下", cell_overwrite_ok = True)
sht1.col(0).width=4000
sht1.write(0, 0, '游戲名稱', style1)
sht1.write(0, 1, '成交量', style1)
sht1.write(0, 2, '下單量', style1)
sht1.write(0, 3, '失敗量', style1)
return wb
def genSuccessOrderOnline():
sql = '''
SELECT A.GAME_NAME,
A.GOODS_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.COMPLETE_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.COMPLETE_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 0
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TRADE_STATUS = 4
AND B.TYPE = 1
GROUP BY A.GAME_ID, G.GOODS_CHANNEL_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def genGenerateOrderOnline():
sql = '''
SELECT A.GAME_NAME,
A.GOODS_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.CREATED_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.CREATED_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 0
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TYPE = 1
GROUP BY A.GAME_ID, G.GOODS_CHANNEL_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def genFailOrderOnline():
sql = '''
SELECT A.GAME_NAME,
A.GOODS_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.COMPLETE_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.COMPLETE_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 0
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TRADE_STATUS = 5
AND B.TYPE = 1
GROUP BY A.GAME_ID, G.GOODS_CHANNEL_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def genSuccessOrderOffline():
sql = '''
SELECT A.GAME_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.COMPLETE_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.COMPLETE_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 1
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TRADE_STATUS = 4
AND B.TYPE = 1
GROUP BY A.GAME_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def genGenerateOrderOffline():
sql = '''
SELECT A.GAME_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.CREATED_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.CREATED_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 1
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TYPE = 1
GROUP BY A.GAME_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def genFailOrderOffline():
sql = '''
SELECT A.GAME_NAME,
COUNT(B.ORDER_ID)
FROM moyoyo_order.BASE_INFO B
INNER JOIN moyoyo_order.ACCOUNT_INFO A ON B.ORDER_ID = A.ORDER_ID
INNER JOIN netgame_trade.GOODS G ON A.GOODS_ID = G.ID
LEFT JOIN moyoyo_order.RELATION_INFO R ON B.ORDER_ID = R.PARENT_ORDER_ID
WHERE B.COMPLETE_DATE >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND B.COMPLETE_DATE < NOW()
AND A.CS_ADMIN_ID != 241
AND A.GOODS_ID != 1213
AND G.GOODS_TYPE_ID != 6
AND A.GOODS_IS_OFFLINE = 1
AND A.IS_B2C IS NULL
AND (
(
A.GOODS_ID IN (1240, 1241, 1608)
AND B.SELLER_ID IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
) OR (
B.SELLER_ID NOT IN (
SELECT MEMBER_ID
FROM netgame_trade.B2C_MEMBER
)
)
)
AND R.PARENT_ORDER_ID IS NULL
AND B.SELLER_ID NOT IN (693356, 14791127)
AND B.STATUS = 1
AND B.TRADE_STATUS = 5
AND B.TYPE = 1
GROUP BY A.GAME_ID
ORDER BY COUNT(B.ORDER_ID) DESC;
'''
rs = orderDBUtil.queryList(sql, ())
if not rs: return None
return rs
def getInfo0(rs, rs2, rs3):
dict={}
for i in range(len(rs)):
key=str(rs[i][0])+'--'+str(rs[i][1])
value=rs[i][2]
dict[key]=[value, 0, 0]
dlist=list(dict.keys())
for i in range(len(rs2)):
key2=str(rs2[i][0])+'--'+str(rs2[i][1])
value2=rs2[i][2]
if key2 in dlist:
value=dict[key2][0]
else:
value=0
dict[key2]=[value, value2, 0]
dlist=list(dict.keys())
for i in range(len(rs3)):
key3=str(rs3[i][0])+'--'+str(rs3[i][1])
value3=rs3[i][2]
if key3 in dlist:
value=dict[key3][0]
value2=dict[key3][1]
else:
value=0
value2=0
dict[key3]=[value, value2, value3]
return dict
def writeInfo0(sht, dict):
'''寫入線上具體數(shù)據(jù)'''
dlist=list(dict.keys())
for i in range(len(dlist)):
sht.write(i+1, 0, str(dlist[i]).decode('utf-8').split('--')[0], style1)
sht.write(i+1, 1, str(dlist[i]).decode('utf-8').split('--')[1], style1)
sht.write(i+1, 2, dict[dlist[i]][0], style1)
sht.write(i+1, 3, dict[dlist[i]][1], style1)
sht.write(i+1, 4, dict[dlist[i]][2], style1)
def getInfo1(rs, rs2, rs3):
'''拿到線下具體數(shù)據(jù)'''
dict={}
for i in range(len(rs)):
key=str(rs[i][0])
value=rs[i][1]
dict[key]=[value, 0, 0]
dlist=list(dict.keys())
for i in range(len(rs2)):
key2=str(rs2[i][0])
value2=rs2[i][1]
if key2 in dlist:
value=dict[key2][0]
else:
value=0
dict[key2]=[value, value2, 0]
dlist=list(dict.keys())
for i in range(len(rs3)):
key3=str(rs3[i][0])
value3=rs3[i][1]
if key3 in dlist:
value=dict[key3][0]
value2=dict[key3][1]
else:
value=0
value2=0
dict[key3]=[value, value2, value3]
return dict
def writeInfo1(sht, dict):
'''寫入線下具體數(shù)據(jù)'''
dlist=list(dict.keys())
for i in range(len(dlist)):
sht.write(i+1, 0, str(dlist[i]).decode('utf-8'), style1)
sht.write(i+1, 1, dict[dlist[i]][0], style1)
sht.write(i+1, 2, dict[dlist[i]][1], style1)
sht.write(i+1, 3, dict[dlist[i]][2], style1)
def writeExcel():
'''寫報(bào)表'''
wb = createTemplateExcel()
rs=genSuccessOrderOnline()
rs2=genGenerateOrderOnline()
rs3=genFailOrderOnline()
sheet0 = wb.get_sheet(0)
dict0=getInfo0(rs, rs2, rs3)
writeInfo0(sheet0, dict0)
rs4=genSuccessOrderOffline()
rs5=genGenerateOrderOffline()
rs6=genFailOrderOffline()
sheet1 = wb.get_sheet(1)
dict1=getInfo1(rs4, rs5, rs6)
writeInfo1(sheet1, dict1)
wb.save(fileName)
def main():
print "===%s start===%s"%(sys.argv[0], datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S"))
writeExcel()
print "===%s end===%s"%(sys.argv[0], datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S"))
if __name__ == '__main__':
try:
main()
finally:
if orderDBUtil: orderDBUtil.close()
總結(jié)
以上就是本文關(guān)于Python建立Map寫Excel表實(shí)例解析的全部內(nèi)容,希望對(duì)大家有所幫助。
數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼
若不方便掃碼,搜微信號(hào):CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動(dòng)態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時(shí),“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場(chǎng)景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲(chǔ)的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對(duì)象的 text 與 content:區(qū)別、場(chǎng)景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請(qǐng)求開發(fā)時(shí)(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請(qǐng)求工具對(duì)比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請(qǐng)求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時(shí)的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動(dòng)下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動(dòng)決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場(chǎng)景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10