
Python建立Map寫Excel表實例解析
本文主要研究的是用Python語言建立Map寫Excel表的相關(guān)代碼,具體如下。
前言:我們已經(jīng)能夠很熟練的寫Excel表相關(guān)的腳本了。大致的操作就是,從數(shù)據(jù)庫中取數(shù)據(jù),建立Excel模板,然后根據(jù)模板建立一個新的Excel表,把數(shù)據(jù)庫中的數(shù)據(jù)寫入。最后發(fā)送郵件。之前的一篇記錄博客,寫的很標(biāo)準(zhǔn)了。這里我們說點遇到的新問題。
我們之前寫類似腳本的時候,有個問題沒有考慮過,為什么要建立模板然后再寫入數(shù)據(jù)呢?誒…其實也不算是沒考慮過,只是懶沒有深究罷了。只求快點完成任務(wù)。。。
這里對這個問題進(jìn)行思考闡述!
【為什么要建立Excel表模板?】
建立Excel模板,是涉及到歷史數(shù)據(jù)才要建立模板的,為什么呢?
如果,我們需要一份數(shù)據(jù)表,這個表中是本月的數(shù)據(jù),每天跑一行出來。到了下個月,就需要新建下一個月的表。
這樣以后進(jìn)行數(shù)據(jù)統(tǒng)計的時候,我們只需要拿到每個月的最后一天的那份數(shù)據(jù)表就可以了,因為最后一天的數(shù)據(jù)表包含了當(dāng)月的所有數(shù)據(jù)。
對于這樣一個需求,腳本中的代碼在月份改變時,肯定要新建一個表,不再將原來的表作為模板來寫。
自然,下一個月的表肯定不能把上一個月的數(shù)據(jù)帶進(jìn)去,所以肯定需要新寫表頭。
這里往深了思考,就涉及到了另外一個問題。
【建立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)
這個所謂的建立模板的方法做了什么事情呢?
只是建立了自定義名字的sheet,然后將表頭寫進(jìn)去了而已。所以建立模板的方法本質(zhì)上實際上就是寫表頭。
我們可以return wb,也可以wb.save(tempFileName)
即,我們可以把寫好的表頭直接return,接著下面的寫數(shù)據(jù)的方法用。
也可以,直接保存一個模板Excel表出來放在腳本后臺用。每次需要寫新表的時候就去調(diào)用生成的模板。
這里的問題還可以更加深。。。
【有了寫表頭的所謂建立模板方法,保存模板文件是否還有必要?】
其實又是個平衡問題。我們是每次調(diào)方法來寫表頭,消耗運行時間。還是直接調(diào)用已經(jīng)寫好的模板文件呢?直接調(diào)用雖然快,但是模板文件會占用腳本后臺的空間。
怎么樣劃算呢?選時間還是空間?
而且有個問題,寫一定就比調(diào)用慢嗎?如果寫比調(diào)用快,既省時間又省空間,只不過代碼中多了個寫表頭的方法而已。
還方便后期維護(hù)。
說到這里,就有一個矛盾的地方了。我們既然已經(jīng)有了寫表頭的操作了。還需要把它保存為模板文件放起來嗎?
每次運行的時候直接寫不就行了嗎?為什么還要保存?
保存起來除了占空間,用于調(diào)用(實質(zhì)上完全可以不調(diào)用直接寫),還有什么用呢?
這是一個值得改進(jìn)的地方。。。吧
【關(guān)于建立模板方法相關(guān)的個人暫處理辦法】
目前我自己能夠想到的方法是,以后不再額外保存模板文件出來。寫表頭就是寫表頭,直接return,和后面的方法串起來就可以了。
每次月份改變的時候,即到了該月第一天寫該月的第一張表的時候,去調(diào)用這個寫表頭的方法就可以了。
好了,第一個問題過去。接下來闡述第二個問題?
【從數(shù)據(jù)庫取數(shù)據(jù),進(jìn)行處理以后,再寫入】
我們之前寫Excel表的時候,大多數(shù)的情況是,直接將取到的數(shù)據(jù)寫入Excel表對應(yīng)位置。
取數(shù)據(jù)都是一樣的方法模板。數(shù)據(jù)處理發(fā)生在寫入的時候。遇到過的,需要處理的情況有兩種:
1. 需要調(diào)用Excel相關(guān)函數(shù),比如SUM等。需要用到這個
xlwt.Formula
2. 需要將數(shù)據(jù)進(jìn)行除運算外的處理。我們處理本例的需求時遇到的就是這種情況。
【需求】
將數(shù)據(jù)庫中每個游戲的成交量、下單量、失敗量取出來。寫一張如下的表出來:
關(guān)鍵需要處理的問題是:每個游戲的三項數(shù)據(jù),每項數(shù)據(jù)是單獨對應(yīng)一個SQL取出來的,即,每項單獨取,排序是不一樣的。
如果直接寫到Excel表中,是這樣子的
可以看到,排序是亂的。我們需要把這些數(shù)據(jù)按名字進(jìn)行一一對應(yīng)的處理,生成一張第一個圖所示的表出來。
這里就是數(shù)據(jù)處理需要用什么方法的問題?
【如何進(jìn)行數(shù)據(jù)處理?】
之前想到的方法是:
可以看到,排序是亂的。我們需要把這些數(shù)據(jù)按名字進(jìn)行一一對應(yīng)的處理,生成一張第一個圖所示的表出來。
這里就是數(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)行寫入。先寫入最多的 ,然后寫入較少的。而較少的兩項寫入時,根據(jù)名字的對應(yīng),放在對應(yīng)的位置。
這樣寫可以,但是有兩個問題:
1. 我們需要沒有數(shù)據(jù)的地方顯示為零。怎么判斷并寫入呢?是個問題,而且還挺麻煩的。
2. 我們需要數(shù)據(jù)完備,即,能夠保證最多的那項數(shù)據(jù)中的游戲就是所有了嗎?會不會每項數(shù)據(jù)對應(yīng)的數(shù)據(jù),都有自己獨有的游戲。
如果,最多的游戲條目數(shù)據(jù)中確實是沒有包含所有,這就是致命的錯誤了。數(shù)據(jù)缺失不是小事兒。
還不止這個,我們能夠保證,這個時候最多的,明天還是最多嗎?如果明天變成了最少,就會有很多數(shù)據(jù)因為名稱匹配不到而沒有寫入。
還是數(shù)據(jù)缺失,很致命的問題。
所以,這種方法,是有很多漏洞和缺陷的。不可行!
【建立字典DICT處理數(shù)據(jù)】
比較理想的處理方法,也是我們最終采用的方法,是將所有數(shù)據(jù)取出來放入一個字典中。
在放入的過程中,進(jìn)行數(shù)據(jù)的整理。即,如果有這個游戲,就直接賦值。如果沒有,新建一個key,然后寫入。
字典建立好了,包含了所有的數(shù)據(jù)了,再進(jìn)行寫入。是比較可靠的。
這種方法的關(guān)鍵點有兩個:
1. 如何在寫入的時候進(jìn)行處理?
2. DICT建立好后,如何進(jìn)行寫入?
我們一個一個說。
【如何在寫入的時候,建立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,一個游戲?qū)?yīng)一個數(shù)據(jù)的那種。
我們這樣處理,將游戲名賦給key,將數(shù)據(jù)賦給value。循環(huán)遍歷,建立一個DICT出來。
接下來是關(guān)鍵的邏輯:如果有,直接賦值;如果沒有,新建一個key,再寫入。
而這個關(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] 如果有的話,第一個value的值,從當(dāng)前狀態(tài)的DICT中取。
如果沒有的話,value直接取0。
最后,直接
dict[key2]=[value, value2, 0]
即,key都是當(dāng)下建立的。我們只需要在乎value的值就可以了。
【疑問】
這就有個疑問了,不會出現(xiàn)重復(fù)建立key的情況嗎?
不會。因為
dict[key2]=[value, value2, 0]
這句代碼,這個=的符號。本來就有賦值和新建兩重用法。如果沒有!就是新建,如果有了!就是改變。
只是改變的時候,我們需要把原來的值也帶進(jìn)去罷了。這個原來的值是從已經(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
第三項數(shù)據(jù)出現(xiàn)時建立DICT的情況如上所示。
需要顧及到兩項已經(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)
其實就是字典的層層剝?nèi)〉姆椒ā?br />
關(guān)鍵就是拿到數(shù)據(jù)而已,拿到了直接寫入!
再稍復(fù)雜的DICT,處理線上數(shù)據(jù)時,我們的鍵有兩個,值有三個。
我們知道,字典這種數(shù)據(jù)類型,值可以為包含了多個數(shù)據(jù)的數(shù)組,但是鍵只能夠有一個,且不能為數(shù)組。
該怎么處理呢?我們只能將多個鍵合并為一個鍵,然后在寫入的時候拆開。
關(guān)鍵問題,就是合并和拆分。
【鍵的合并】
key=str(rs[i][0])+'--'+str(rs[i][1])
對,僅此而已。把兩個數(shù)據(jù)連到一起。合并為一個字符串。
【寫入時鍵的拆分】
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ù)對字符串的拆分,拆分結(jié)果是數(shù)組。按數(shù)組編號來取分開的數(shù)據(jù)就可以了。
至此,這個需求的關(guān)鍵問題都已經(jīng)說明完畢。
最后貼一份完整代碼如下。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
__author__ = "$Author: wangxin.xie$"
__version__ = "$Revision: 1.0 $"
__date__ = "$Date: 2018$"
###############################################################
#功能: 訂單情況相關(guān)報表
###############################################################
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():
'''寫報表'''
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表實例解析的全部內(nèi)容,希望對大家有所幫助。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預(yù)測分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢預(yù)判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預(yù)測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點,而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨特的門控機制,在 ...
2025-07-07統(tǒng)計學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費者需求的重要途徑,而統(tǒng)計學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03