- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python建立Map写Excel表实例解析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文主要研究的是用Python语言建立Map写Excel表的相关代码,具体如下.
前言:我们已经能够很熟练的写Excel表相关的脚本了。大致的操作就是,从数据库中取数据,建立Excel模板,然后根据模板建立一个新的Excel表,把数据库中的数据写入。最后发送邮件。之前的一篇记录博客,写的很标准了。这里我们说点遇到的新问题.
我们之前写类似脚本的时候,有个问题没有考虑过,为什么要建立模板然后再写入数据呢?诶…其实也不算是没考虑过,只是懒没有深究罢了。只求快点完成任务。。.
这里对这个问题进行思考阐述! 。
【为什么要建立Excel表模板?】建立Excel模板,是涉及到历史数据才要建立模板的,为什么呢?
如果,我们需要一份数据表,这个表中是本月的数据,每天跑一行出来。到了下个月,就需要新建下一个月的表.
这样以后进行数据统计的时候,我们只需要拿到每个月的最后一天的那份数据表就可以了,因为最后一天的数据表包含了当月的所有数据.
对于这样一个需求,脚本中的代码在月份改变时,肯定要新建一个表,不再将原来的表作为模板来写.
自然,下一个月的表肯定不能把上一个月的数据带进去,所以肯定需要新写表头.
这里往深了思考,就涉及到了另外一个问题.
【建立Excel模板的方法的本质】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
def
createTemplateExcel():
'''创建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,然后将表头写进去了而已。所以建立模板的方法本质上实际上就是写表头.
我们可以return wb,也可以wb.save(tempFileName) 。
即,我们可以把写好的表头直接return,接着下面的写数据的方法用.
也可以,直接保存一个模板Excel表出来放在脚本后台用。每次需要写新表的时候就去调用生成的模板.
这里的问题还可以更加深。。.
【有了写表头的所谓建立模板方法,保存模板文件是否还有必要?】其实又是个平衡问题。我们是每次调方法来写表头,消耗运行时间。还是直接调用已经写好的模板文件呢?直接调用虽然快,但是模板文件会占用脚本后台的空间.
怎么样划算呢?选时间还是空间?
而且有个问题,写一定就比调用慢吗?如果写比调用快,既省时间又省空间,只不过代码中多了个写表头的方法而已.
还方便后期维护.
说到这里,就有一个矛盾的地方了。我们既然已经有了写表头的操作了。还需要把它保存为模板文件放起来吗?
每次运行的时候直接写不就行了吗?为什么还要保存?
保存起来除了占空间,用于调用(实质上完全可以不调用直接写),还有什么用呢?
这是一个值得改进的地方。。。吧 。
【关于建立模板方法相关的个人暂处理办法】目前我自己能够想到的方法是,以后不再额外保存模板文件出来。写表头就是写表头,直接return,和后面的方法串起来就可以了.
每次月份改变的时候,即到了该月第一天写该月的第一张表的时候,去调用这个写表头的方法就可以了.
。
好了,第一个问题过去。接下来阐述第二个问题?
【从数据库取数据,进行处理以后,再写入】我们之前写Excel表的时候,大多数的情况是,直接将取到的数据写入Excel表对应位置.
取数据都是一样的方法模板。数据处理发生在写入的时候。遇到过的,需要处理的情况有两种:
1. 需要调用Excel相关函数,比如SUM等。需要用到这个 。
1
|
xlwt.Formula
|
2. 需要将数据进行除运算外的处理。我们处理本例的需求时遇到的就是这种情况.
【需求】将数据库中每个游戏的成交量、下单量、失败量取出来。写一张如下的表出来:
关键需要处理的问题是:每个游戏的三项数据,每项数据是单独对应一个SQL取出来的,即,每项单独取,排序是不一样的.
如果直接写到Excel表中,是这样子的 。
可以看到,排序是乱的。我们需要把这些数据按名字进行一一对应的处理,生成一张第一个图所示的表出来.
这里就是数据处理需要用什么方法的问题?
【如何进行数据处理?】 。
之前想到的方法是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def
writeInfo0(sht, rs, length, rs2, length2, rs3, length3):
'''写入线上具体数据'''
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)
|
直接进行写入。先写入最多的 ,然后写入较少的。而较少的两项写入时,根据名字的对应,放在对应的位置。 这样写可以,但是有两个问题:
1. 我们需要没有数据的地方显示为零。怎么判断并写入呢?是个问题,而且还挺麻烦的.
2. 我们需要数据完备,即,能够保证最多的那项数据中的游戏就是所有了吗?会不会每项数据对应的数据,都有自己独有的游戏.
如果,最多的游戏条目数据中确实是没有包含所有,这就是致命的错误了。数据缺失不是小事儿.
还不止这个,我们能够保证,这个时候最多的,明天还是最多吗?如果明天变成了最少,就会有很多数据因为名称匹配不到而没有写入.
还是数据缺失,很致命的问题.
所以,这种方法,是有很多漏洞和缺陷的。不可行! 。
【建立字典DICT处理数据】比较理想的处理方法,也是我们最终采用的方法,是将所有数据取出来放入一个字典中.
在放入的过程中,进行数据的整理。即,如果有这个游戏,就直接赋值。如果没有,新建一个key,然后写入.
字典建立好了,包含了所有的数据了,再进行写入。是比较可靠的.
这种方法的关键点有两个:
1. 如何在写入的时候进行处理?
2. DICT建立好后,如何进行写入?
我们一个一个说.
【如何在写入的时候,建立DICT处理数据?】先以比较简单的线下数据写入为例,进行说明.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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数据是list,一个游戏对应一个数据的那种.
我们这样处理,将游戏名赋给key,将数据赋给value。循环遍历,建立一个DICT出来.
接下来是关键的逻辑:如果有,直接赋值;如果没有,新建一个key,再写入.
而这个关键逻辑中更为关键的逻辑是,如何判断原来的key中有没有.
处理方法是这样的 。
1
2
|
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的值,从当前状态的DICT中取.
如果没有的话,value直接取0.
最后,直接 。
1
|
dict
[key2]
=
[value, value2,
0
]
|
即,key都是当下建立的。我们只需要在乎value的值就可以了.
【疑问】这就有个疑问了,不会出现重复建立key的情况吗?
不会。因为 。
1
|
dict
[key2]
=
[value, value2,
0
]
|
这句代码,这个=的符号。本来就有赋值和新建两重用法。如果没有!就是新建,如果有了!就是改变.
只是改变的时候,我们需要把原来的值也带进去罢了。这个原来的值是从已经有DICT中取到的。。。罢了.
接下来,更为复杂的代码也就可以理解了.
1
2
3
4
5
6
7
8
9
10
11
12
|
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
|
第三项数据出现时建立DICT的情况如上所示.
需要顾及到两项已经写好的数据,而已.
【如何将DICT写入Excel表】
1
2
3
4
5
6
7
8
|
def
writeInfo1(sht,
dict
):
'''写入线下具体数据'''
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)
|
其实就是字典的层层剥取的方法.
关键就是拿到数据而已,拿到了直接写入! 。
再稍复杂的DICT,处理线上数据时,我们的键有两个,值有三个.
我们知道,字典这种数据类型,值可以为包含了多个数据的数组,但是键只能够有一个,且不能为数组.
该怎么处理呢?我们只能将多个键合并为一个键,然后在写入的时候拆开.
关键问题,就是合并和拆分.
【键的合并】
1
|
key
=
str
(rs[i][
0
])
+
'--'
+
str
(rs[i][
1
])
|
对,仅此而已。把两个数据连到一起。合并为一个字符串.
【写入时键的拆分】
1
2
|
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函数.
split函数对字符串的拆分,拆分结果是数组。按数组编号来取分开的数据就可以了.
至此,这个需求的关键问题都已经说明完毕.
最后贴一份完整代码如下.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
|
#!/usr/bin/python
# -*- coding: UTF-8 -*-
__author__
=
"$Author: wangxin.xie$"
__version__
=
"$Revision: 1.0 $"
__date__
=
"$Date: 2018$"
###############################################################
#功能: 订单情况相关报表
###############################################################
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():
'''创建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
):
'''写入线上具体数据'''
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):
'''拿到线下具体数据'''
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
):
'''写入线下具体数据'''
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()
|
以上就是本文关于Python建立Map写Excel表实例解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持! 。
原文链接:http://blog.csdn.net/akak714/article/details/50370149 。
最后此篇关于Python建立Map写Excel表实例解析的文章就讲到这里了,如果你想了解更多关于Python建立Map写Excel表实例解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要(我必须)将大量 float 写入 qdatastream 并且我只使用 4 个字节是必要的。setFloatingPointPrecision 或为 float 和 double 写入 4 或
我有一些 C 代码,我用 Python 对其进行了扩展。扩展的 C 代码有一个将一些结构附加到二进制文件的函数: void writefunction(const struct struct1* so
我正在用 C 语言开发一个小软件,用于在布告栏中读取和写入消息。每条消息都是一个以渐进数字命名的 .txt。 软件是多线程的,有很多用户可以并发操作。 用户可以进行的操作有: 阅读整个公告板(所有 .
我有 2 个线程同时访问同一个大文件 (.txt)。 第一个线程正在从文件中读取。第二个线程正在写入文件。 两个线程都访问同一个 block ,例如(开始:0, block 大小:10),但具有不同的
我做了很多谷歌搜索,但我仍然不确定如何继续。 Linux 下最常见的剪贴板读写方式是什么?我想要同时支持 Gnome 和 KDE 桌面。 更新:我是否认为没有简单的解决方案,必须将多个来源(gnome
1. 定义配置文件信息 有时候我们为了统一管理会把一些变量放到 yml 配置文件中 例如 图片 用 @ConfigurationProperties 代替 @Value 使用方法 定义对应字段的实体
在开始之前,我必须先声明我是 FORTRAN 的新手。我正在维护 1978 年的一段遗留代码。它的目的是从文件中读取一些数据值,处理这些值,然后将处理过的值输出到另一个文本文件。 给定以下 FORTR
我正在制作一个应用程序,我需要存储用户提供的一些信息。我尝试使用 .plist 文件来存储信息,我发现: NSString *filePath = @"/Users/Denis/Documents/X
在delphi类中声明属性时是否可能有不同类型的结果? 示例: 属性月份:字符串读取monthGet(字符串)写入monthSet(整数); 在示例中,我希望在属性(property)月份中,当我:读
我正在以二进制形式将文件加载到数组中,这似乎需要一段时间有没有更好更快更有效的方法来做到这一点。我正在使用类似的方法写回文件。 procedure openfile(fname:string); va
我想实现一个运行模拟的C#控制台应用程序。另外,我想给用户机会在控制台上按“+”或“-”来加速/减速模拟的速度。 有没有办法在编写控制台时读取控制台?我相信我可以为此使用多线程,但是我却不怎么做(我对
这是我的代码: use std::fs::File; use std::io::Write; fn main() { let f = File::create("").unwrap();
我有一个应用程序可以访问 csv 文本文件中的单词。由于它们通常不会更改,因此我将它们放置在 .jar 文件中,并使用 .getResourceAsStream 调用读取它们。我真的很喜欢这种方法,因
我使用kubeadm,docker 17.12.1-ce和法兰绒网络安装了Kubernetes 1.13.1集群 但是,我发现Kubernetes主服务器上有许多空文件,权限为666,该文件允许任何用
我的工作区中有一些 java 文件。现在我想编写一个java程序,它可以读取来自不同源的文本文件,一次一个,一行一行,并将这些行插入到工作区中各自的java文件中。 文本文件会告诉我将哪个文件插入到哪
用户A要求系统读取文件foo,同时用户B想要将他或她的数据保存到同一个文件中。在文件系统级别如何处理这种情况? 最佳答案 大多数文件系统(但不是全部)使用锁定来保护对同一文件的并发访问。锁可以是独占的
我对保护移动应用程序的 firebase 数据库有一些疑问。 例如,在反编译Android应用程序后,黑客可以获取firebase api key 然后访问firebase数据库,这是正确的吗? 假设
我想让文件从外部不可删除,并希望使用java从程序对该文件进行读/写操作。 S0,我使用以下代码使用java创建了不可删除的文件: Process pcs = Runtime.getRunti
当 Selector.select() 以阻塞模式等待读/写操作时,是否可以将写消息推送到客户端?如何将选择器从阻塞模式移至写入模式?触发器可以是一个后台线程,用于放置需要写入给定 channel 的
我目前正在学习在 Linux 环境中使用 C 进行套接字编程。作为一个项目,我正在尝试编写一个基本的聊天服务器和客户端。 目的是让服务器为每个连接的客户端派生一个进程。 我遇到的问题是读取一个 chi
我是一名优秀的程序员,十分优秀!