qrpa 1.0.22__py3-none-any.whl → 1.0.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of qrpa might be problematic. Click here for more details.
- qrpa/__init__.py +5 -1
- qrpa/fun_base.py +38 -0
- qrpa/fun_excel.py +50 -10
- qrpa/shein_daily_report_model.py +1 -1
- qrpa/shein_excel.py +444 -243
- qrpa/shein_lib.py +155 -0
- qrpa/temu_chrome.py +56 -0
- qrpa/temu_excel.py +109 -0
- qrpa/temu_lib.py +154 -0
- qrpa/wxwork.py +6 -0
- {qrpa-1.0.22.dist-info → qrpa-1.0.24.dist-info}/METADATA +1 -1
- qrpa-1.0.24.dist-info/RECORD +23 -0
- qrpa-1.0.22.dist-info/RECORD +0 -20
- {qrpa-1.0.22.dist-info → qrpa-1.0.24.dist-info}/WHEEL +0 -0
- {qrpa-1.0.22.dist-info → qrpa-1.0.24.dist-info}/top_level.txt +0 -0
qrpa/shein_excel.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .fun_excel import *
|
|
2
|
-
from .fun_base import log
|
|
2
|
+
from .fun_base import log, calculate_star_symbols
|
|
3
3
|
from .fun_file import read_dict_from_file, read_dict_from_file_ex, write_dict_to_file, write_dict_to_file_ex, delete_file
|
|
4
4
|
from .time_utils import TimeUtils
|
|
5
5
|
from .wxwork import WxWorkBot
|
|
@@ -11,6 +11,192 @@ class SheinExcel:
|
|
|
11
11
|
self.config = config
|
|
12
12
|
pass
|
|
13
13
|
|
|
14
|
+
def format_funds(self, sheet):
|
|
15
|
+
beautify_title(sheet)
|
|
16
|
+
column_to_right(sheet, ['金额', '汇总'])
|
|
17
|
+
format_to_money(sheet, ['金额', '汇总'])
|
|
18
|
+
add_sum_for_cell(sheet, ['在途商品金额', '在仓商品金额', '待结算金额', '可提现金额', '销售出库金额', '汇总'])
|
|
19
|
+
add_formula_for_column(sheet, '汇总', '=SUM(D3:G3)', 3)
|
|
20
|
+
sheet.autofit()
|
|
21
|
+
|
|
22
|
+
def format_bad_comment(self, sheet):
|
|
23
|
+
beautify_title(sheet)
|
|
24
|
+
column_to_left(sheet, ['商品信息'])
|
|
25
|
+
autofit_column(sheet, ['买家评价', '时间信息', '标签关键词'])
|
|
26
|
+
specify_column_width(sheet, ['买家评价', '商品信息'], 150 / 6)
|
|
27
|
+
color_for_column(sheet, ['买家评分'], '红色')
|
|
28
|
+
colorize_by_field(sheet, 'skc')
|
|
29
|
+
add_borders(sheet)
|
|
30
|
+
InsertImageV2(sheet, ['商品图片', '图1', '图2', '图3', '图4', '图5'])
|
|
31
|
+
|
|
32
|
+
def write_bad_comment(self):
|
|
33
|
+
excel_path = create_file_path(self.config.excel_bad_comment)
|
|
34
|
+
header = ['评价ID', '商品图片', '商品信息', '买家评分', '买家评价', '标签关键词', '区域', '时间信息', '有图', '图1',
|
|
35
|
+
'图2', '图3', '图4', '图5', 'skc']
|
|
36
|
+
summary_excel_data = [header]
|
|
37
|
+
|
|
38
|
+
cache_file = f'{self.config.auto_dir}/shein/dict/comment_list_{TimeUtils.today_date()}.json'
|
|
39
|
+
dict = read_dict_from_file(cache_file)
|
|
40
|
+
dict_store = read_dict_from_file(self.config.shein_store_alias)
|
|
41
|
+
|
|
42
|
+
for store_username, comment_list in dict.items():
|
|
43
|
+
store_name = dict_store.get(store_username)
|
|
44
|
+
sheet_name = store_name
|
|
45
|
+
|
|
46
|
+
store_excel_data = [header]
|
|
47
|
+
for comment in comment_list:
|
|
48
|
+
row_item = []
|
|
49
|
+
row_item.append(comment['commentId'])
|
|
50
|
+
row_item.append(comment['goodsThumb'])
|
|
51
|
+
product_info = f'属性:{comment["goodsAttribute"]}\n货号:{comment["goodSn"]}\nSPU:{comment["spu"]}\nSKC:{comment["skc"]}\nSKU:{comment["sku"]}'
|
|
52
|
+
row_item.append(product_info)
|
|
53
|
+
row_item.append(calculate_star_symbols(comment['goodsCommentStar']))
|
|
54
|
+
row_item.append(comment['goodsCommentContent'])
|
|
55
|
+
qualityLabel = '存在质量问题\n' if comment['isQualityLabel'] == 1 else ''
|
|
56
|
+
bad_comment_label = qualityLabel + '\n'.join([item['labelName'] for item in comment['badCommentLabelList']])
|
|
57
|
+
|
|
58
|
+
row_item.append(bad_comment_label)
|
|
59
|
+
row_item.append(comment['dataCenterName'])
|
|
60
|
+
time_info = f'下单时间:{comment["orderTime"]}\n评论时间:{comment["commentTime"]}'
|
|
61
|
+
row_item.append(time_info)
|
|
62
|
+
|
|
63
|
+
# 获取图片数量
|
|
64
|
+
image_num = len(comment.get('goodsCommentImages', []))
|
|
65
|
+
# 设置imgFlag值(如果comment中没有imgFlag字段,默认设为0)
|
|
66
|
+
imgFlag = image_num if comment.get('imgFlag') == 1 else 0
|
|
67
|
+
row_item.append(imgFlag)
|
|
68
|
+
|
|
69
|
+
images = comment.get('goodsCommentImages', [])
|
|
70
|
+
for i in range(5):
|
|
71
|
+
row_item.append(images[i] if i < len(images) else '')
|
|
72
|
+
|
|
73
|
+
row_item.append(comment['skc'])
|
|
74
|
+
|
|
75
|
+
store_excel_data.append(row_item)
|
|
76
|
+
summary_excel_data.append(row_item)
|
|
77
|
+
|
|
78
|
+
# write_data(excel_path, sheet_name, store_excel_data)
|
|
79
|
+
# format_bad_comment(excel_path, sheet_name)
|
|
80
|
+
|
|
81
|
+
sheet_name = 'Sheet1'
|
|
82
|
+
|
|
83
|
+
batch_excel_operations(excel_path, [
|
|
84
|
+
(sheet_name, 'write', summary_excel_data),
|
|
85
|
+
(sheet_name, 'format', self.format_bad_comment),
|
|
86
|
+
])
|
|
87
|
+
|
|
88
|
+
def write_funds(self):
|
|
89
|
+
cache_file = f'{self.config.auto_dir}/shein/cache/stat_fund_{TimeUtils.today_date()}.json'
|
|
90
|
+
dict = read_dict_from_file(cache_file)
|
|
91
|
+
data = []
|
|
92
|
+
for key, val in dict.items():
|
|
93
|
+
data.append(val)
|
|
94
|
+
|
|
95
|
+
excel_path = create_file_path(self.config.excel_shein_fund)
|
|
96
|
+
sheet_name = 'Sheet1'
|
|
97
|
+
data.insert(0, ['汇总', '', '', '', '', '', '', '', '', ''])
|
|
98
|
+
data.insert(0, ['店铺名称', '店铺账号', '店长', '在途商品金额', '在仓商品金额', '待结算金额', '可提现金额',
|
|
99
|
+
'销售出库金额', '汇总', '导出时间'])
|
|
100
|
+
batch_excel_operations(excel_path, [
|
|
101
|
+
('Sheet1', 'write', sort_by_column(data, 7, 2)),
|
|
102
|
+
('Sheet1', 'format', self.format_funds),
|
|
103
|
+
])
|
|
104
|
+
WxWorkBot('b30aaa8d-1a1f-4378-841a-8b0f8295f2d9').send_file(excel_path)
|
|
105
|
+
|
|
106
|
+
def format_skc_quality(self, sheet):
|
|
107
|
+
beautify_title(sheet)
|
|
108
|
+
colorize_by_field(sheet, 'skc')
|
|
109
|
+
add_borders(sheet)
|
|
110
|
+
InsertImageV2(sheet, ['商品图片'])
|
|
111
|
+
|
|
112
|
+
def sort_site_desc_by_sale_cnt_14d(self, data, reverse=True):
|
|
113
|
+
"""
|
|
114
|
+
对data中的site_desc_vo_list按照skc_site_sale_cnt_14d进行排序
|
|
115
|
+
|
|
116
|
+
参数:
|
|
117
|
+
data: 包含site_desc_vo_list的字典
|
|
118
|
+
reverse: 是否倒序排序,默认为True(从大到小)
|
|
119
|
+
|
|
120
|
+
返回:
|
|
121
|
+
排序后的data(原数据会被修改)
|
|
122
|
+
"""
|
|
123
|
+
if 'site_desc_vo_list' in data and isinstance(data['site_desc_vo_list'], list):
|
|
124
|
+
# 处理None值,将它们放在排序结果的最后
|
|
125
|
+
data['site_desc_vo_list'].sort(
|
|
126
|
+
key=lambda x: float('-inf') if x.get('skc_site_sale_cnt_14d') is None else x['skc_site_sale_cnt_14d'],
|
|
127
|
+
reverse=reverse
|
|
128
|
+
)
|
|
129
|
+
return data
|
|
130
|
+
|
|
131
|
+
def write_skc_quality_estimate(self):
|
|
132
|
+
excel_path = create_file_path(self.config.excel_skc_quality_estimate)
|
|
133
|
+
header = ['店铺信息', '商品图片', '统计日期', '国家', '当日销量', '14日销量', '14日销量占比', '质量等级',
|
|
134
|
+
'客评数/客评分', '差评数/差评率', '退货数/退货率', 'skc', 'skc当日销量', 'skc14日销量', 'skc14日销量占比']
|
|
135
|
+
summary_excel_data = [header]
|
|
136
|
+
|
|
137
|
+
stat_date = TimeUtils.before_yesterday()
|
|
138
|
+
cache_file = f'{self.config.auto_dir}/shein/dict/googs_estimate_{stat_date}.json'
|
|
139
|
+
dict = read_dict_from_file(cache_file)
|
|
140
|
+
if len(dict) == 0:
|
|
141
|
+
log('昨日质量评估数据不存在')
|
|
142
|
+
return
|
|
143
|
+
|
|
144
|
+
dict_store = read_dict_from_file(self.config.shein_store_alias)
|
|
145
|
+
|
|
146
|
+
operations = []
|
|
147
|
+
for store_username, skc_list in dict.items():
|
|
148
|
+
store_name = dict_store.get(store_username)
|
|
149
|
+
sheet_name = store_name
|
|
150
|
+
|
|
151
|
+
store_excel_data = [header]
|
|
152
|
+
for skc_item in skc_list:
|
|
153
|
+
sorted_skc_item = self.sort_site_desc_by_sale_cnt_14d(skc_item, True)
|
|
154
|
+
# for site in sorted_skc_item['site_desc_vo_list']:
|
|
155
|
+
# print(f"{site['country_site']}: {site['skc_site_sale_cnt_14d']}")
|
|
156
|
+
# continue
|
|
157
|
+
store_info = f'{store_name}'
|
|
158
|
+
skc = sorted_skc_item['skc']
|
|
159
|
+
sites = sorted_skc_item['site_desc_vo_list']
|
|
160
|
+
skc_sale_cnt = sorted_skc_item['skc_sale_cnt']
|
|
161
|
+
skc_sale_cnt_14d = sorted_skc_item['skc_sale_cnt_14d']
|
|
162
|
+
skc_sale_rate_14d = sorted_skc_item['skc_sale_rate_14d']
|
|
163
|
+
for site in sites:
|
|
164
|
+
row_item = []
|
|
165
|
+
row_item.append(store_info)
|
|
166
|
+
row_item.append(skc_item['goods_image'])
|
|
167
|
+
row_item.append(stat_date)
|
|
168
|
+
row_item.append(site['country_site'])
|
|
169
|
+
row_item.append(site['skc_site_sale_cnt'])
|
|
170
|
+
cnt_14d = site['skc_site_sale_cnt_14d']
|
|
171
|
+
if cnt_14d is None or cnt_14d <= 0:
|
|
172
|
+
continue
|
|
173
|
+
row_item.append(cnt_14d)
|
|
174
|
+
row_item.append(site['skc_site_sale_rate_14d'])
|
|
175
|
+
row_item.append(site['quality_level'])
|
|
176
|
+
customer_info = f'{site["customer_evaluate_num"]}/{site["customer_evaluate_score"][:-1]}'
|
|
177
|
+
row_item.append(customer_info)
|
|
178
|
+
negative_info = f'{site["negative_quantity"]}/{site["negative_percent"]}'
|
|
179
|
+
row_item.append(negative_info)
|
|
180
|
+
return_info = f'{site["goods_return_quantity"]}/{site["goods_return_percent"]}'
|
|
181
|
+
row_item.append(return_info)
|
|
182
|
+
row_item.append(skc)
|
|
183
|
+
row_item.append(skc_sale_cnt)
|
|
184
|
+
row_item.append(skc_sale_cnt_14d)
|
|
185
|
+
row_item.append(skc_sale_rate_14d)
|
|
186
|
+
store_excel_data.append(row_item)
|
|
187
|
+
summary_excel_data.append(row_item)
|
|
188
|
+
|
|
189
|
+
operations.append((
|
|
190
|
+
sheet_name, 'write', store_excel_data
|
|
191
|
+
))
|
|
192
|
+
operations.append((
|
|
193
|
+
sheet_name, 'format', self.format_skc_quality
|
|
194
|
+
))
|
|
195
|
+
operations.append((
|
|
196
|
+
'Sheet1', 'delete'
|
|
197
|
+
))
|
|
198
|
+
batch_excel_operations(excel_path, operations)
|
|
199
|
+
|
|
14
200
|
def write_sales_data(self):
|
|
15
201
|
yesterday = TimeUtils.get_yesterday()
|
|
16
202
|
model = SheinStoreSalesDetailManager(self.config.database_url)
|
|
@@ -18,12 +204,12 @@ class SheinExcel:
|
|
|
18
204
|
data_day = []
|
|
19
205
|
dict_store_manager_shein = self.config.shein_store_manager
|
|
20
206
|
dict_store_name = read_dict_from_file(self.config.shein_store_alias)
|
|
207
|
+
|
|
208
|
+
# 准备每日汇总数据
|
|
21
209
|
for record in records:
|
|
22
210
|
store_data = []
|
|
23
|
-
# store_data.append(record.store_name)
|
|
24
211
|
store_data.append(dict_store_name.get(record.store_username))
|
|
25
212
|
store_data.append(dict_store_manager_shein.get(str(record.store_username).lower(), '-'))
|
|
26
|
-
# log(dict_store_manager_shein.get(str(record.store_username).lower(),'-'))
|
|
27
213
|
store_data.append(record.sales_num)
|
|
28
214
|
store_data.append(record.sales_num_inc)
|
|
29
215
|
store_data.append(record.sales_amount)
|
|
@@ -42,148 +228,36 @@ class SheinExcel:
|
|
|
42
228
|
store_data.append(record.upload_product_num_inc)
|
|
43
229
|
store_data.append(record.sold_out_product_num)
|
|
44
230
|
store_data.append(record.shelf_off_product_num)
|
|
45
|
-
# store_data.append(record.remark) # 不要了
|
|
46
231
|
data_day.append(store_data)
|
|
47
232
|
|
|
48
233
|
excel_path = create_file_path(self.config.excel_daily_report)
|
|
49
234
|
delete_file(excel_path)
|
|
50
235
|
sheet_name_first = 'SHEIN销售部每日店铺情况'
|
|
51
|
-
# write_json_to_excel('excel_daily.json',excel_path,sheet_name_first)
|
|
52
|
-
app, wb, sheet = open_excel(excel_path, sheet_name_first)
|
|
53
|
-
delete_sheet_if_exists(wb, 'Sheet1')
|
|
54
|
-
|
|
55
|
-
las_row = len(data_day) + 4
|
|
56
|
-
log('len(las_row)', las_row)
|
|
57
|
-
sheet.range('B5').value = data_day
|
|
58
|
-
# sheet.range('3:3').api.WrapText = True
|
|
59
|
-
sheet.range(f'A5:U{las_row}').api.Font.Color = 0x000000 # 红色
|
|
60
|
-
sheet.range(f'A5:U{las_row}').api.Font.Bold = False
|
|
61
|
-
sheet.range('A1').value = f'销售部SHEIN{TimeUtils.get_current_month()}月店铺数据'
|
|
62
|
-
sheet.range('A4').value = f'{TimeUtils.format_date_cross_platform(yesterday)}\n({TimeUtils.get_chinese_weekday(yesterday)})'
|
|
63
|
-
sheet.range('A4').column_width = 16
|
|
64
|
-
sheet.range('A4').api.VerticalAlignment = -4160 # 垂直顶部对齐
|
|
65
|
-
sheet.range(f'A4:A{las_row}').merge()
|
|
66
|
-
|
|
67
|
-
# 获取列数据范围
|
|
68
|
-
column_range = sheet.range(f'E5:E{las_row}')
|
|
69
|
-
# 遍历列中的每个单元格
|
|
70
|
-
for cell in column_range:
|
|
71
|
-
# 检查单元格是否有值且为负数
|
|
72
|
-
if cell.value is not None and isinstance(cell.value, (int, float)) and cell.value < 0:
|
|
73
|
-
# 设置字体颜色为红色
|
|
74
|
-
cell.font.color = (255, 0, 0) # RGB值表示红色
|
|
75
|
-
|
|
76
|
-
# 获取列数据范围
|
|
77
|
-
column_range = sheet.range(f'G5:G{las_row}')
|
|
78
|
-
# 遍历列中的每个单元格
|
|
79
|
-
for cell in column_range:
|
|
80
|
-
# 检查单元格是否有值且为负数
|
|
81
|
-
if cell.value is not None and cell.value < 0:
|
|
82
|
-
# 设置字体颜色为红色
|
|
83
|
-
cell.font.color = (255, 0, 0) # RGB值表示红色
|
|
84
|
-
|
|
85
|
-
# 获取列数据范围
|
|
86
|
-
column_range = sheet.range(f'I5:I{las_row}')
|
|
87
|
-
# 遍历列中的每个单元格
|
|
88
|
-
for cell in column_range:
|
|
89
|
-
# 检查单元格是否有值且为负数
|
|
90
|
-
if cell.value is not None and isinstance(cell.value, (int, float)) and cell.value < 0:
|
|
91
|
-
# 设置字体颜色为红色
|
|
92
|
-
cell.font.color = (255, 0, 0) # RGB值表示红色
|
|
93
|
-
|
|
94
|
-
# 获取列数据范围
|
|
95
|
-
column_range = sheet.range(f'K5:K{las_row}')
|
|
96
|
-
# 遍历列中的每个单元格
|
|
97
|
-
for cell in column_range:
|
|
98
|
-
# 检查单元格是否有值且为负数
|
|
99
|
-
if cell.value is not None and isinstance(cell.value, (int, float)) and cell.value < 0:
|
|
100
|
-
# 设置字体颜色为红色
|
|
101
|
-
cell.font.color = (255, 0, 0) # RGB值表示红色
|
|
102
|
-
|
|
103
|
-
# 处理表头
|
|
104
|
-
# 处理第一行
|
|
105
|
-
rangeOne = f'A1:U1'
|
|
106
|
-
sheet.range(rangeOne).merge()
|
|
107
|
-
sheet.range(rangeOne).api.Font.Size = 24
|
|
108
|
-
sheet.range(rangeOne).api.Font.Bold = True
|
|
109
|
-
sheet.range(rangeOne).api.HorizontalAlignment = -4108
|
|
110
|
-
sheet.range(rangeOne).api.VerticalAlignment = -4108
|
|
111
|
-
|
|
112
|
-
# 处理第二行
|
|
113
|
-
rangeTwo_part_1 = f'A2:C2'
|
|
114
|
-
rangeTwo_part_2 = f'D2:O2'
|
|
115
|
-
rangeTwo_part_3 = f'P2:U2'
|
|
116
|
-
sheet.range(rangeTwo_part_1).merge()
|
|
117
|
-
sheet.range(rangeTwo_part_2).merge()
|
|
118
|
-
sheet.range(rangeTwo_part_3).merge()
|
|
119
236
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
sheet.range('D2').value = f'店铺的结果和稳定性'
|
|
123
|
-
sheet.range(rangeTwo_part_2).api.Font.Size = 16
|
|
124
|
-
sheet.range(rangeTwo_part_2).api.Font.Color = 0xFFFFFF
|
|
125
|
-
sheet.range(rangeTwo_part_2).api.Font.Bold = True
|
|
126
|
-
sheet.range(rangeTwo_part_2).api.HorizontalAlignment = -4108
|
|
127
|
-
sheet.range(rangeTwo_part_2).api.VerticalAlignment = -4108
|
|
128
|
-
sheet.range(f'D2:O3').color = 0x0000FF
|
|
129
|
-
|
|
130
|
-
sheet.range('P2').value = f'上新的质量和数量'
|
|
131
|
-
sheet.range(rangeTwo_part_3).api.Font.Size = 16
|
|
132
|
-
sheet.range(rangeTwo_part_3).api.Font.Color = 0xFFFFFF
|
|
133
|
-
sheet.range(rangeTwo_part_3).api.Font.Bold = True
|
|
134
|
-
sheet.range(rangeTwo_part_3).api.HorizontalAlignment = -4108
|
|
135
|
-
sheet.range(rangeTwo_part_3).api.VerticalAlignment = -4108
|
|
136
|
-
sheet.range(f'P2:U3').color = 0x47a100
|
|
137
|
-
|
|
138
|
-
# 处理第三行
|
|
139
|
-
rangeThree = f'A3:U3'
|
|
140
|
-
sheet.range('A3').value = ['日期', '店铺', '店长', '昨日单量', '对比前日', '昨日销售额', '对比前日', '昨日访客',
|
|
141
|
-
'对比前天', '备货款A', '对比前日', '新款A', '对比前日', '在售商品', '对比前日', '待上架',
|
|
142
|
-
'对比前日', '昨日上传', '对比前日', '已售罄', '已下架']
|
|
143
|
-
sheet.range(rangeThree).api.Font.Size = 11
|
|
144
|
-
sheet.range(rangeThree).api.Font.Color = 0xFFFFFF
|
|
145
|
-
sheet.range(rangeThree).api.Font.Bold = True
|
|
146
|
-
sheet.range(rangeThree).api.HorizontalAlignment = -4108
|
|
147
|
-
sheet.range(rangeThree).api.VerticalAlignment = -4108
|
|
148
|
-
|
|
149
|
-
# 处理第4行
|
|
150
|
-
rangeFour = f'B4:U4'
|
|
151
|
-
sheet.range('B4').value = '汇总'
|
|
152
|
-
sheet.range('C4').value = '-'
|
|
153
|
-
sheet.range(rangeFour).api.Font.Size = 11
|
|
154
|
-
sheet.range(rangeThree).api.HorizontalAlignment = -4108
|
|
155
|
-
sheet.range(rangeThree).api.VerticalAlignment = -4108
|
|
156
|
-
sheet.range(f'B4:U4').color = 0x50d092
|
|
157
|
-
|
|
158
|
-
for col in range(2, 22): # 对应 C 列到 J 列
|
|
159
|
-
col_letter = xw.utils.col_name(col)
|
|
160
|
-
if col_letter not in ['A', 'B', 'C']:
|
|
161
|
-
sheet.range(f'{col_letter}4').formula = f'=SUM({col_letter}5:{col_letter}{las_row})'
|
|
162
|
-
# 所有列水平居中和垂直居中
|
|
163
|
-
sheet.range(f'{col_letter}:{col_letter}').api.HorizontalAlignment = -4108
|
|
164
|
-
sheet.range(f'{col_letter}:{col_letter}').api.VerticalAlignment = -4108
|
|
165
|
-
sheet.autofit()
|
|
237
|
+
# 准备批量操作列表
|
|
238
|
+
operations = []
|
|
166
239
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
range_to_border.api.Borders(2).LineStyle = 1 # 内部下边框
|
|
176
|
-
range_to_border.api.Borders(3).LineStyle = 1 # 内部左边框
|
|
177
|
-
range_to_border.api.Borders(4).LineStyle = 1 # 内部右边框
|
|
240
|
+
# 添加每日汇总sheet的操作 - 自定义操作函数
|
|
241
|
+
def write_daily_data(sheet):
|
|
242
|
+
# 写入数据到B5位置,保持原有格式
|
|
243
|
+
sheet.range('B5').value = data_day
|
|
244
|
+
# 设置标题
|
|
245
|
+
sheet.range('A1').value = f'销售部SHEIN{TimeUtils.get_current_month()}月店铺数据'
|
|
246
|
+
# 设置日期和合并
|
|
247
|
+
sheet.range('A4').value = f'{TimeUtils.format_date_cross_platform(yesterday)}\n({TimeUtils.get_chinese_weekday(yesterday)})'
|
|
178
248
|
|
|
179
|
-
|
|
180
|
-
|
|
249
|
+
operations.append((sheet_name_first, 'format', write_daily_data))
|
|
250
|
+
operations.append((sheet_name_first, 'format', self._format_daily_summary_sheet, yesterday, len(data_day)))
|
|
251
|
+
operations.append(('Sheet1', 'delete'))
|
|
252
|
+
operations.append((sheet_name_first, 'move', 1))
|
|
181
253
|
|
|
254
|
+
# 获取店铺列表并准备月度数据
|
|
182
255
|
store_list = model.get_distinct_store_sales_list()
|
|
183
256
|
for store in store_list:
|
|
184
257
|
store_username = store[0]
|
|
185
258
|
store_name = dict_store_name.get(store_username)
|
|
186
259
|
records = model.get_one_month_records(TimeUtils.get_current_year(), TimeUtils.get_current_month(), store_username)
|
|
260
|
+
|
|
187
261
|
data_month = []
|
|
188
262
|
for record in records:
|
|
189
263
|
store_data = []
|
|
@@ -206,101 +280,228 @@ class SheinExcel:
|
|
|
206
280
|
store_data.append(record.upload_product_num_inc)
|
|
207
281
|
store_data.append(record.sold_out_product_num)
|
|
208
282
|
store_data.append(record.shelf_off_product_num)
|
|
209
|
-
store_data.append(record.remark)
|
|
283
|
+
# store_data.append(record.remark) # 月度数据不包含备注列,保持19列
|
|
210
284
|
data_month.append(store_data)
|
|
211
285
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
# 处理第二行
|
|
229
|
-
rangeTwo_part_1 = f'A2'
|
|
230
|
-
rangeTwo_part_2 = f'B2:M2'
|
|
231
|
-
rangeTwo_part_3 = f'N2:S2'
|
|
232
|
-
sheet.range(rangeTwo_part_2).merge()
|
|
233
|
-
sheet.range(rangeTwo_part_3).merge()
|
|
234
|
-
|
|
235
|
-
sheet.range(f'A2:A3').color = 0x47a100
|
|
236
|
-
|
|
237
|
-
sheet.range('B2').value = f'店铺的结果和稳定性'
|
|
238
|
-
sheet.range(rangeTwo_part_2).api.Font.Size = 16
|
|
239
|
-
sheet.range(rangeTwo_part_2).api.Font.Color = 0xFFFFFF
|
|
240
|
-
sheet.range(rangeTwo_part_2).api.Font.Bold = True
|
|
241
|
-
sheet.range(rangeTwo_part_2).api.HorizontalAlignment = -4108
|
|
242
|
-
sheet.range(rangeTwo_part_2).api.VerticalAlignment = -4108
|
|
243
|
-
sheet.range(f'B2:M3').color = 0x0000FF
|
|
244
|
-
|
|
245
|
-
sheet.range('N2').value = f'上新的质量和数量'
|
|
246
|
-
sheet.range(rangeTwo_part_3).api.Font.Size = 16
|
|
247
|
-
sheet.range(rangeTwo_part_3).api.Font.Color = 0xFFFFFF
|
|
248
|
-
sheet.range(rangeTwo_part_3).api.Font.Bold = True
|
|
249
|
-
sheet.range(rangeTwo_part_3).api.HorizontalAlignment = -4108
|
|
250
|
-
sheet.range(rangeTwo_part_3).api.VerticalAlignment = -4108
|
|
251
|
-
sheet.range(f'N2:S3').color = 0x47a100
|
|
252
|
-
|
|
253
|
-
# 处理第三行
|
|
254
|
-
rangeThree = f'A3:S3'
|
|
255
|
-
sheet.range('A3').value = ['日期', '昨日单量', '对比前日', '昨日销售额', '对比前日', '昨日访客', '对比前天',
|
|
256
|
-
'备货款A', '对比前日', '新款A', '对比前日', '在售商品', '对比前日', '待上架',
|
|
257
|
-
'对比前日', '昨日上传', '对比前日', '已售罄', '已下架']
|
|
258
|
-
sheet.range(rangeThree).api.Font.Size = 11
|
|
259
|
-
sheet.range(rangeThree).api.Font.Color = 0xFFFFFF
|
|
260
|
-
sheet.range(rangeThree).api.Font.Bold = True
|
|
261
|
-
sheet.range(rangeThree).api.HorizontalAlignment = -4108
|
|
262
|
-
sheet.range(rangeThree).api.VerticalAlignment = -4108
|
|
263
|
-
|
|
264
|
-
# 处理第4行
|
|
265
|
-
rangeFour = f'A4:S4'
|
|
266
|
-
sheet.range('A4').value = '汇总'
|
|
267
|
-
sheet.range(rangeFour).api.Font.Size = 11
|
|
268
|
-
sheet.range(rangeThree).api.HorizontalAlignment = -4108
|
|
269
|
-
sheet.range(rangeThree).api.VerticalAlignment = -4108
|
|
270
|
-
sheet.range(f'A4:S4').color = 0x50d092
|
|
271
|
-
|
|
272
|
-
# 原逻辑
|
|
273
|
-
sheet.range('A5').value = data_month
|
|
274
|
-
# sheet.range('3:3').api.WrapText = True
|
|
275
|
-
sheet.range('A4:T35').api.Font.Color = 0x000000
|
|
276
|
-
sheet.range('A4:T35').api.Font.Bold = False
|
|
277
|
-
sheet.range('A1').value = f'{store_name}SHEIN{TimeUtils.get_current_month()}月店铺数据'
|
|
278
|
-
|
|
279
|
-
range_to_border = sheet.range(f'A2:S{las_row}') # 定义范围
|
|
280
|
-
# 设置外部边框(所有边都为实线)
|
|
281
|
-
range_to_border.api.Borders(7).LineStyle = 1 # 上边框
|
|
282
|
-
range_to_border.api.Borders(8).LineStyle = 1 # 下边框
|
|
283
|
-
range_to_border.api.Borders(9).LineStyle = 1 # 左边框
|
|
284
|
-
range_to_border.api.Borders(10).LineStyle = 1 # 右边框
|
|
285
|
-
# 设置内部边框
|
|
286
|
-
range_to_border.api.Borders(1).LineStyle = 1 # 内部上边框
|
|
287
|
-
range_to_border.api.Borders(2).LineStyle = 1 # 内部下边框
|
|
288
|
-
range_to_border.api.Borders(3).LineStyle = 1 # 内部左边框
|
|
289
|
-
range_to_border.api.Borders(4).LineStyle = 1 # 内部右边框
|
|
290
|
-
wb.save()
|
|
291
|
-
|
|
292
|
-
for col in range(2, 20): # 对应 C 列到 J 列
|
|
293
|
-
col_letter = xw.utils.col_name(col)
|
|
294
|
-
# 所有列水平居中和垂直居中
|
|
295
|
-
sheet.range(f'{col_letter}:{col_letter}').api.HorizontalAlignment = -4108
|
|
296
|
-
sheet.range(f'{col_letter}:{col_letter}').api.VerticalAlignment = -4108
|
|
297
|
-
sheet.range(f'{col_letter}4').formula = f'=SUM({col_letter}5:{col_letter}36)'
|
|
298
|
-
|
|
299
|
-
if sheet_name_first in [sheet.name for sheet in wb.sheets]:
|
|
300
|
-
wb.sheets[sheet_name_first].activate()
|
|
301
|
-
wb.save()
|
|
302
|
-
close_excel(app, wb)
|
|
286
|
+
# 添加月度sheet操作 - 自定义操作函数
|
|
287
|
+
def write_monthly_data(sheet, data=data_month, name=store_name):
|
|
288
|
+
# 写入数据到A5位置(月度数据从A列开始)
|
|
289
|
+
sheet.range('A5').value = data
|
|
290
|
+
# 设置标题
|
|
291
|
+
sheet.range('A1').value = f'{name}SHEIN{TimeUtils.get_current_month()}月店铺数据'
|
|
292
|
+
|
|
293
|
+
operations.append((store_name, 'format', write_monthly_data))
|
|
294
|
+
operations.append((store_name, 'format', self._format_store_monthly_sheet, store_name, len(data_month)))
|
|
295
|
+
|
|
296
|
+
# 执行批量操作
|
|
297
|
+
operations.append((sheet_name_first, 'active'))
|
|
298
|
+
success = batch_excel_operations(excel_path, operations)
|
|
299
|
+
|
|
300
|
+
if success:
|
|
301
|
+
# 发送文件到企业微信
|
|
303
302
|
WxWorkBot('b30aaa8d-1a1f-4378-841a-8b0f8295f2d9').send_file(excel_path)
|
|
303
|
+
log(f"销售数据写入完成: {excel_path}")
|
|
304
|
+
else:
|
|
305
|
+
log(f"销售数据写入失败: {excel_path}")
|
|
306
|
+
|
|
307
|
+
def _format_daily_summary_sheet(self, sheet, yesterday, data_length):
|
|
308
|
+
"""格式化每日汇总sheet"""
|
|
309
|
+
las_row = data_length + 4 # 数据从第5行开始,4行header
|
|
310
|
+
|
|
311
|
+
# 设置数据区域格式(从B5开始,因为数据写入到B5)
|
|
312
|
+
sheet.range(f'B5:U{las_row}').api.Font.Color = 0x000000
|
|
313
|
+
sheet.range(f'B5:U{las_row}').api.Font.Bold = False
|
|
314
|
+
|
|
315
|
+
# 设置A4日期列的格式和合并
|
|
316
|
+
sheet.range('A4').column_width = 16
|
|
317
|
+
sheet.range('A4').api.VerticalAlignment = -4160 # 垂直顶部对齐
|
|
318
|
+
sheet.range(f'A4:A{las_row}').merge()
|
|
319
|
+
|
|
320
|
+
# 设置负数为红色(E,G,I,K列)
|
|
321
|
+
self._set_negative_numbers_red(sheet, ['E', 'G', 'I', 'K'], 5, las_row)
|
|
322
|
+
|
|
323
|
+
# 格式化表头
|
|
324
|
+
self._format_daily_header(sheet, las_row)
|
|
325
|
+
|
|
326
|
+
# 设置汇总公式和格式
|
|
327
|
+
self._set_summary_formulas(sheet, las_row)
|
|
328
|
+
|
|
329
|
+
# 设置边框
|
|
330
|
+
self._set_borders(sheet, f'A2:U{las_row}')
|
|
331
|
+
|
|
332
|
+
sheet.autofit()
|
|
333
|
+
|
|
334
|
+
def _format_store_monthly_sheet(self, sheet, store_name, data_length):
|
|
335
|
+
"""格式化店铺月度sheet"""
|
|
336
|
+
las_row = data_length + 4 # 数据从第5行开始,4行header
|
|
337
|
+
|
|
338
|
+
# 数据已经写入,现在进行格式化
|
|
339
|
+
# 设置数据区域格式(从A5开始到S列,月度数据是19列)
|
|
340
|
+
sheet.range(f'A5:S{las_row}').api.Font.Color = 0x000000
|
|
341
|
+
sheet.range(f'A5:S{las_row}').api.Font.Bold = False
|
|
342
|
+
|
|
343
|
+
# 格式化表头
|
|
344
|
+
self._format_monthly_header(sheet, las_row)
|
|
345
|
+
|
|
346
|
+
# 设置汇总公式和格式
|
|
347
|
+
self._set_monthly_summary_formulas(sheet, las_row)
|
|
348
|
+
|
|
349
|
+
# 设置边框
|
|
350
|
+
self._set_borders(sheet, f'A2:S{las_row}')
|
|
351
|
+
|
|
352
|
+
sheet.autofit()
|
|
353
|
+
|
|
354
|
+
def _set_negative_numbers_red(self, sheet, columns, start_row, end_row):
|
|
355
|
+
"""设置负数为红色"""
|
|
356
|
+
for col in columns:
|
|
357
|
+
column_range = sheet.range(f'{col}{start_row}:{col}{end_row}')
|
|
358
|
+
for cell in column_range:
|
|
359
|
+
if cell.value is not None and isinstance(cell.value, (int, float)) and cell.value < 0:
|
|
360
|
+
cell.font.color = (255, 0, 0)
|
|
361
|
+
|
|
362
|
+
def _format_daily_header(self, sheet, las_row):
|
|
363
|
+
"""格式化每日汇总表头,完全按照原始格式"""
|
|
364
|
+
# 第一行:标题
|
|
365
|
+
range_one = f'A1:U1'
|
|
366
|
+
sheet.range(range_one).merge()
|
|
367
|
+
sheet.range(range_one).api.Font.Size = 24
|
|
368
|
+
sheet.range(range_one).api.Font.Bold = True
|
|
369
|
+
sheet.range(range_one).api.HorizontalAlignment = -4108
|
|
370
|
+
sheet.range(range_one).api.VerticalAlignment = -4108
|
|
371
|
+
|
|
372
|
+
# 第二行:分类标题
|
|
373
|
+
range_two_part_1 = f'A2:C2'
|
|
374
|
+
range_two_part_2 = f'D2:O2'
|
|
375
|
+
range_two_part_3 = f'P2:U2'
|
|
376
|
+
sheet.range(range_two_part_1).merge()
|
|
377
|
+
sheet.range(range_two_part_2).merge()
|
|
378
|
+
sheet.range(range_two_part_3).merge()
|
|
379
|
+
|
|
380
|
+
sheet.range(f'A2:C3').color = 0x47a100
|
|
381
|
+
|
|
382
|
+
sheet.range('D2').value = '店铺的结果和稳定性'
|
|
383
|
+
sheet.range(range_two_part_2).api.Font.Size = 16
|
|
384
|
+
sheet.range(range_two_part_2).api.Font.Color = 0xFFFFFF
|
|
385
|
+
sheet.range(range_two_part_2).api.Font.Bold = True
|
|
386
|
+
sheet.range(range_two_part_2).api.HorizontalAlignment = -4108
|
|
387
|
+
sheet.range(range_two_part_2).api.VerticalAlignment = -4108
|
|
388
|
+
sheet.range(f'D2:O3').color = 0x0000FF
|
|
389
|
+
|
|
390
|
+
sheet.range('P2').value = '上新的质量和数量'
|
|
391
|
+
sheet.range(range_two_part_3).api.Font.Size = 16
|
|
392
|
+
sheet.range(range_two_part_3).api.Font.Color = 0xFFFFFF
|
|
393
|
+
sheet.range(range_two_part_3).api.Font.Bold = True
|
|
394
|
+
sheet.range(range_two_part_3).api.HorizontalAlignment = -4108
|
|
395
|
+
sheet.range(range_two_part_3).api.VerticalAlignment = -4108
|
|
396
|
+
sheet.range(f'P2:U3').color = 0x47a100
|
|
397
|
+
|
|
398
|
+
# 第三行:列标题
|
|
399
|
+
range_three = f'A3:U3'
|
|
400
|
+
sheet.range('A3').value = ['日期', '店铺', '店长', '昨日单量', '对比前日', '昨日销售额', '对比前日', '昨日访客',
|
|
401
|
+
'对比前天', '备货款A', '对比前日', '新款A', '对比前日', '在售商品', '对比前日', '待上架',
|
|
402
|
+
'对比前日', '昨日上传', '对比前日', '已售罄', '已下架']
|
|
403
|
+
sheet.range(range_three).api.Font.Size = 11
|
|
404
|
+
sheet.range(range_three).api.Font.Color = 0xFFFFFF
|
|
405
|
+
sheet.range(range_three).api.Font.Bold = True
|
|
406
|
+
sheet.range(range_three).api.HorizontalAlignment = -4108
|
|
407
|
+
sheet.range(range_three).api.VerticalAlignment = -4108
|
|
408
|
+
|
|
409
|
+
# 第四行:汇总行
|
|
410
|
+
range_four = f'B4:U4'
|
|
411
|
+
sheet.range('B4').value = '汇总'
|
|
412
|
+
sheet.range('C4').value = '-'
|
|
413
|
+
sheet.range(range_four).api.Font.Size = 11
|
|
414
|
+
sheet.range(range_four).api.HorizontalAlignment = -4108
|
|
415
|
+
sheet.range(range_four).api.VerticalAlignment = -4108
|
|
416
|
+
sheet.range(f'B4:U4').color = 0x50d092
|
|
417
|
+
|
|
418
|
+
def _format_monthly_header(self, sheet, las_row):
|
|
419
|
+
"""格式化月度表头,完全按照原始格式"""
|
|
420
|
+
# 第一行:标题(合并A1:S1)
|
|
421
|
+
range_one = f'A1:S1'
|
|
422
|
+
sheet.range(range_one).merge()
|
|
423
|
+
sheet.range(range_one).api.Font.Size = 24
|
|
424
|
+
sheet.range(range_one).api.Font.Bold = True
|
|
425
|
+
sheet.range(range_one).api.HorizontalAlignment = -4108
|
|
426
|
+
sheet.range(range_one).api.VerticalAlignment = -4108
|
|
427
|
+
|
|
428
|
+
# 第二行:分类标题
|
|
429
|
+
range_two_part_1 = f'A2'
|
|
430
|
+
range_two_part_2 = f'B2:M2'
|
|
431
|
+
range_two_part_3 = f'N2:S2'
|
|
432
|
+
sheet.range(range_two_part_2).merge()
|
|
433
|
+
sheet.range(range_two_part_3).merge()
|
|
434
|
+
|
|
435
|
+
sheet.range(f'A2:A3').color = 0x47a100
|
|
436
|
+
|
|
437
|
+
sheet.range('B2').value = '店铺的结果和稳定性'
|
|
438
|
+
sheet.range(range_two_part_2).api.Font.Size = 16
|
|
439
|
+
sheet.range(range_two_part_2).api.Font.Color = 0xFFFFFF
|
|
440
|
+
sheet.range(range_two_part_2).api.Font.Bold = True
|
|
441
|
+
sheet.range(range_two_part_2).api.HorizontalAlignment = -4108
|
|
442
|
+
sheet.range(range_two_part_2).api.VerticalAlignment = -4108
|
|
443
|
+
sheet.range(f'B2:M3').color = 0x0000FF
|
|
444
|
+
|
|
445
|
+
sheet.range('N2').value = '上新的质量和数量'
|
|
446
|
+
sheet.range(range_two_part_3).api.Font.Size = 16
|
|
447
|
+
sheet.range(range_two_part_3).api.Font.Color = 0xFFFFFF
|
|
448
|
+
sheet.range(range_two_part_3).api.Font.Bold = True
|
|
449
|
+
sheet.range(range_two_part_3).api.HorizontalAlignment = -4108
|
|
450
|
+
sheet.range(range_two_part_3).api.VerticalAlignment = -4108
|
|
451
|
+
sheet.range(f'N2:S3').color = 0x47a100
|
|
452
|
+
|
|
453
|
+
# 第三行:列标题
|
|
454
|
+
range_three = f'A3:S3'
|
|
455
|
+
sheet.range('A3').value = ['日期', '昨日单量', '对比前日', '昨日销售额', '对比前日', '昨日访客', '对比前天',
|
|
456
|
+
'备货款A', '对比前日', '新款A', '对比前日', '在售商品', '对比前日', '待上架',
|
|
457
|
+
'对比前日', '昨日上传', '对比前日', '已售罄', '已下架']
|
|
458
|
+
sheet.range(range_three).api.Font.Size = 11
|
|
459
|
+
sheet.range(range_three).api.Font.Color = 0xFFFFFF
|
|
460
|
+
sheet.range(range_three).api.Font.Bold = True
|
|
461
|
+
sheet.range(range_three).api.HorizontalAlignment = -4108
|
|
462
|
+
sheet.range(range_three).api.VerticalAlignment = -4108
|
|
463
|
+
|
|
464
|
+
# 第四行:汇总行
|
|
465
|
+
range_four = f'A4:S4'
|
|
466
|
+
sheet.range('A4').value = '汇总'
|
|
467
|
+
sheet.range(range_four).api.Font.Size = 11
|
|
468
|
+
sheet.range(range_four).api.HorizontalAlignment = -4108
|
|
469
|
+
sheet.range(range_four).api.VerticalAlignment = -4108
|
|
470
|
+
sheet.range(f'A4:S4').color = 0x50d092
|
|
471
|
+
|
|
472
|
+
def _set_summary_formulas(self, sheet, las_row):
|
|
473
|
+
"""设置汇总公式"""
|
|
474
|
+
for col in range(2, 22): # B列到U列(跳过A列日期)
|
|
475
|
+
col_letter = xw.utils.col_name(col)
|
|
476
|
+
if col_letter not in ['A', 'B', 'C']: # A列是日期,B列是汇总,C列是-
|
|
477
|
+
sheet.range(f'{col_letter}4').formula = f'=SUM({col_letter}5:{col_letter}{las_row})'
|
|
478
|
+
# 所有列水平居中和垂直居中
|
|
479
|
+
sheet.range(f'{col_letter}:{col_letter}').api.HorizontalAlignment = -4108
|
|
480
|
+
sheet.range(f'{col_letter}:{col_letter}').api.VerticalAlignment = -4108
|
|
481
|
+
|
|
482
|
+
def _set_monthly_summary_formulas(self, sheet, las_row):
|
|
483
|
+
"""设置月度汇总公式"""
|
|
484
|
+
for col in range(2, 20): # B列到S列(对应原始代码的 2 到 20)
|
|
485
|
+
col_letter = xw.utils.col_name(col)
|
|
486
|
+
# 所有列水平居中和垂直居中
|
|
487
|
+
sheet.range(f'{col_letter}:{col_letter}').api.HorizontalAlignment = -4108
|
|
488
|
+
sheet.range(f'{col_letter}:{col_letter}').api.VerticalAlignment = -4108
|
|
489
|
+
# 设置汇总公式(原始代码使用固定的36行)
|
|
490
|
+
sheet.range(f'{col_letter}4').formula = f'=SUM({col_letter}5:{col_letter}36)'
|
|
491
|
+
|
|
492
|
+
def _set_borders(self, sheet, range_str):
|
|
493
|
+
"""设置边框"""
|
|
494
|
+
range_to_border = sheet.range(range_str)
|
|
495
|
+
# 设置外部边框
|
|
496
|
+
range_to_border.api.Borders(7).LineStyle = 1 # 上边框
|
|
497
|
+
range_to_border.api.Borders(8).LineStyle = 1 # 下边框
|
|
498
|
+
range_to_border.api.Borders(9).LineStyle = 1 # 左边框
|
|
499
|
+
range_to_border.api.Borders(10).LineStyle = 1 # 右边框
|
|
500
|
+
# 设置内部边框
|
|
501
|
+
range_to_border.api.Borders(1).LineStyle = 1 # 内部上边框
|
|
502
|
+
range_to_border.api.Borders(2).LineStyle = 1 # 内部下边框
|
|
503
|
+
range_to_border.api.Borders(3).LineStyle = 1 # 内部左边框
|
|
504
|
+
range_to_border.api.Borders(4).LineStyle = 1 # 内部右边框
|
|
304
505
|
|
|
305
506
|
def format_bak_advice(self, excel_path, sheet_name, mode):
|
|
306
507
|
app, wb, sheet = open_excel(excel_path, sheet_name)
|
|
@@ -318,9 +519,9 @@ class SheinExcel:
|
|
|
318
519
|
add_formula_for_column(sheet, '本地和采购可售天数', '=IF(H2>0, (F2+G2)/H2,0)')
|
|
319
520
|
add_formula_for_column(sheet, '建议采购', '=IF(I2 > J2,0,E2)')
|
|
320
521
|
|
|
321
|
-
colorize_by_field(
|
|
522
|
+
colorize_by_field(sheet, 'SKC')
|
|
322
523
|
specify_column_width(sheet, ['商品信息'], 180 / 6)
|
|
323
|
-
InsertImageV2(
|
|
524
|
+
InsertImageV2(sheet, ['SKC图片', 'SKU图片'])
|
|
324
525
|
wb.save()
|
|
325
526
|
close_excel(app, wb)
|
|
326
527
|
if mode == 4:
|
|
@@ -357,11 +558,11 @@ class SheinExcel:
|
|
|
357
558
|
new_excel_path_list.append(new_excel_path)
|
|
358
559
|
sheet_name = 'Sheet1'
|
|
359
560
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
561
|
+
log(new_excel_path)
|
|
562
|
+
if mode in [2]:
|
|
563
|
+
excel_data = sort_by_column(excel_data, 4, 1)
|
|
564
|
+
write_data(new_excel_path, sheet_name, excel_data)
|
|
565
|
+
self.format_bak_advice(new_excel_path, sheet_name, mode)
|
|
365
566
|
|
|
366
567
|
# 是否合并表格数据
|
|
367
568
|
if mode in [1, 3]:
|
|
@@ -396,7 +597,7 @@ class SheinExcel:
|
|
|
396
597
|
beautify_title(sheet)
|
|
397
598
|
add_borders(sheet)
|
|
398
599
|
column_to_left(sheet, ['活动信息'])
|
|
399
|
-
colorize_by_field(
|
|
600
|
+
colorize_by_field(sheet, '店铺名称')
|
|
400
601
|
autofit_column(sheet, ['店铺名称', '活动信息'])
|
|
401
602
|
wb.save()
|
|
402
603
|
close_excel(app, wb)
|
|
@@ -411,10 +612,10 @@ class SheinExcel:
|
|
|
411
612
|
|
|
412
613
|
header = []
|
|
413
614
|
for store_username, excel_data in dict_1.items():
|
|
414
|
-
store_name = dict_store.get(store_username)
|
|
415
|
-
sheet_name = store_name
|
|
416
|
-
write_data(excel_path_1, sheet_name, excel_data)
|
|
417
|
-
self.format_jit(excel_path_1, sheet_name)
|
|
615
|
+
# store_name = dict_store.get(store_username)
|
|
616
|
+
# sheet_name = store_name
|
|
617
|
+
# write_data(excel_path_1, sheet_name, excel_data)
|
|
618
|
+
# self.format_jit(excel_path_1, sheet_name)
|
|
418
619
|
header = excel_data[0]
|
|
419
620
|
summary_excel_data_1 += excel_data[1:]
|
|
420
621
|
|
|
@@ -431,10 +632,10 @@ class SheinExcel:
|
|
|
431
632
|
|
|
432
633
|
header = []
|
|
433
634
|
for store_username, excel_data in dict_2.items():
|
|
434
|
-
store_name = dict_store.get(store_username)
|
|
435
|
-
sheet_name = store_name
|
|
436
|
-
write_data(excel_path_2, sheet_name, excel_data)
|
|
437
|
-
self.format_jit(excel_path_2, sheet_name)
|
|
635
|
+
# store_name = dict_store.get(store_username)
|
|
636
|
+
# sheet_name = store_name
|
|
637
|
+
# write_data(excel_path_2, sheet_name, excel_data)
|
|
638
|
+
# self.format_jit(excel_path_2, sheet_name)
|
|
438
639
|
header = excel_data[0]
|
|
439
640
|
summary_excel_data_2 += excel_data[1:]
|
|
440
641
|
|
|
@@ -447,11 +648,11 @@ class SheinExcel:
|
|
|
447
648
|
app, wb, sheet = open_excel(excel_path, sheet_name)
|
|
448
649
|
beautify_title(sheet)
|
|
449
650
|
add_borders(sheet)
|
|
450
|
-
colorize_by_field(
|
|
651
|
+
colorize_by_field(sheet, 'SKC')
|
|
451
652
|
column_to_left(sheet, ["商品信息", "近7天SKU销量/SKC销量/SKC曝光", "SKC点击率/SKC转化率", "自主参与活动"])
|
|
452
653
|
autofit_column(sheet,
|
|
453
654
|
['店铺名称', '商品信息', "近7天SKU销量/SKC销量/SKC曝光", "SKC点击率/SKC转化率", "自主参与活动"])
|
|
454
|
-
InsertImageV2(
|
|
655
|
+
InsertImageV2(sheet, ['SKC图片', 'SKU图片'])
|
|
455
656
|
wb.save()
|
|
456
657
|
close_excel(app, wb)
|
|
457
658
|
WxWorkBot('b30aaa8d-1a1f-4378-841a-8b0f8295f2d9').send_file(excel_path)
|
|
@@ -483,12 +684,12 @@ class SheinExcel:
|
|
|
483
684
|
format_to_money(sheet, ['申报价', '成本价', '毛利润', '利润'])
|
|
484
685
|
format_to_percent(sheet, ['支付率', '点击率', '毛利率'])
|
|
485
686
|
self.dealFormula(sheet) # 有空再封装优化
|
|
486
|
-
colorize_by_field(
|
|
687
|
+
colorize_by_field(sheet, 'SPU')
|
|
487
688
|
autofit_column(sheet, ['商品信息', '店铺名称', 'SKC点击率/SKC转化率', '自主参与活动'])
|
|
488
689
|
column_to_left(sheet, ['店铺名称', 'SKC点击率/SKC转化率', '自主参与活动'])
|
|
489
690
|
specify_column_width(sheet, ['商品标题'], 150 / 6)
|
|
490
691
|
add_borders(sheet)
|
|
491
|
-
InsertImageV2(
|
|
692
|
+
InsertImageV2(sheet, ['SKC图片', 'SKU图片'], 'shein', 120, None, None, True)
|
|
492
693
|
wb.save()
|
|
493
694
|
close_excel(app, wb)
|
|
494
695
|
|