Ethscriptions commited on
Commit
672bd6c
·
verified ·
1 Parent(s): 4bffa9c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -35
app.py CHANGED
@@ -7,12 +7,11 @@ import base64
7
  import matplotlib.gridspec as gridspec
8
  import math
9
 
10
- # [前面的常量定义和 process_schedule 函数保持不变]
11
  SPLIT_TIME = "17:30"
12
  BUSINESS_START = "09:30"
13
  BUSINESS_END = "01:30"
14
  BORDER_COLOR = '#A9A9A9'
15
- DATE_COLOR = '#A9A9A9' # 日期的颜色与单元格边框颜色一致
16
 
17
  def process_schedule(file):
18
  """处理上传的 Excel 文件,生成排序和分组后的打印内容"""
@@ -49,24 +48,19 @@ def process_schedule(file):
49
  # 标准化所有时间到同一天
50
  for idx, row in df.iterrows():
51
  end_time = row['EndTime']
52
- # 如果结束时间在凌晨(0点到9:30之间),认为是第二天
53
  if end_time.hour < 9:
54
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
55
 
56
- # 如果开始时间在晚上9点之后,结束时间在凌晨,也需要调整结束时间
57
  if row['StartTime'].hour >= 21 and end_time.hour < 9:
58
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
59
 
60
  # 筛选营业时间内的场次
61
- # 转换时间为当天的时间点进行比较
62
  df['time_for_comparison'] = df['EndTime'].apply(
63
  lambda x: datetime.combine(base_date, x.time())
64
  )
65
 
66
- # 处理跨天的情况
67
  df.loc[df['time_for_comparison'].dt.hour < 9, 'time_for_comparison'] += timedelta(days=1)
68
 
69
- # 应用时间筛选
70
  valid_times = (
71
  ((df['time_for_comparison'] >= datetime.combine(base_date, business_start.time())) &
72
  (df['time_for_comparison'] <= datetime.combine(base_date + timedelta(days=1), business_end.time())))
@@ -90,9 +84,24 @@ def process_schedule(file):
90
  for part in [part1, part2]:
91
  part['EndTime'] = part['EndTime'].dt.strftime('%-I:%M')
92
 
93
- # 提取日期
94
- date_df = pd.read_excel(file, skiprows=5, nrows=1, usecols="C")
95
- date_str = date_df.iloc[0, 0].strftime('%Y-%m-%d') if not pd.isna(date_df.iloc[0, 0]) else datetime.today().strftime('%Y-%m-%d')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  return part1[['Hall', 'EndTime']], part2[['Hall', 'EndTime']], date_str
98
 
@@ -111,7 +120,7 @@ def create_print_layout(data, title, date_str):
111
 
112
  # 设置字体
113
  plt.rcParams['font.family'] = 'sans-serif'
114
- plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 使用支持中文的字体
115
 
116
  # 计算行数和总数
117
  total_items = len(data)
@@ -121,46 +130,36 @@ def create_print_layout(data, title, date_str):
121
  # 创建网格
122
  gs = gridspec.GridSpec(num_rows + 1, num_cols, hspace=0.1, wspace=0.1, height_ratios=[1] * num_rows + [0.2])
123
 
124
- # 计算字体大小(核心修改)
125
- base_fontsize = min(30, 265 / num_rows) # 最大字体限制为30
126
 
127
- # 重要改动:正确的竖向排序逻辑
128
  data_values = data.values.tolist()
129
 
130
- # 确保数据长度是3的倍数
131
  while len(data_values) % 3 != 0:
132
  data_values.append(['', ''])
133
 
134
- # 计算每列应该包含的行数
135
  rows_per_col = math.ceil(len(data_values) / 3)
136
 
137
- # 创建一个新的数据列表,用于存储重新排序后的数据
138
  sorted_data = [['', '']] * len(data_values)
139
 
140
- # 正确的竖向排序逻辑
141
  for i, item in enumerate(data_values):
142
- if item[0] and item[1]: # 只处理非空数据
143
- # 计算新的位置
144
  row = i % rows_per_col
145
  col = i // rows_per_col
146
  new_index = row * 3 + col
147
  if new_index < len(sorted_data):
148
  sorted_data[new_index] = item
149
 
150
- # 填充数据
151
  for idx, (hall, end_time) in enumerate(sorted_data):
152
- if hall and end_time: # 只处理非空数据
153
  row = idx // 3
154
  col = idx % 3
155
 
156
  ax = plt.subplot(gs[row, col])
157
 
158
- # 设置边框
159
  for spine in ax.spines.values():
160
  spine.set_color(BORDER_COLOR)
161
  spine.set_linewidth(0.5)
162
 
163
- # 显示文本
164
  display_text = f"{hall}{end_time}"
165
  ax.text(0.5, 0.5, display_text,
166
  fontsize=base_fontsize,
@@ -168,24 +167,21 @@ def create_print_layout(data, title, date_str):
168
  ha='center',
169
  va='center')
170
 
171
- # 设置边距
172
  ax.set_xlim(-0.02, 1.02)
173
  ax.set_ylim(-0.02, 1.02)
174
 
175
- # 移除坐标轴
176
  ax.set_xticks([])
177
  ax.set_yticks([])
178
 
179
- # 在左上角添加日期和班次信息
180
  ax_date = plt.subplot(gs[0, 0])
181
  ax_date.text(0.05, 0.95, f"{date_str} {title}",
182
- fontsize=base_fontsize * 0.4, # 进一步调小日期字体
183
- color=DATE_COLOR, # 设置日期颜色
184
  fontweight='bold',
185
  ha='left',
186
  va='top')
187
 
188
- # 移除日期单元格的边框
189
  for spine in ax_date.spines.values():
190
  spine.set_visible(False)
191
  ax_date.set_xticks([])
@@ -210,11 +206,9 @@ if uploaded_file:
210
  part1, part2, date_str = process_schedule(uploaded_file)
211
 
212
  if part1 is not None and part2 is not None:
213
- # 创建打印布局
214
- part1_image = create_print_layout(part1, "A", date_str) # 白班改为 A
215
- part2_image = create_print_layout(part2, "C", date_str) # 夜班改为 C
216
 
217
- # 显示预览
218
  col1, col2 = st.columns(2)
219
 
220
  with col1:
@@ -229,4 +223,23 @@ if uploaded_file:
229
  if part2_image:
230
  st.image(part2_image)
231
  else:
232
- st.info("夜班部分没有数据")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  import matplotlib.gridspec as gridspec
8
  import math
9
 
 
10
  SPLIT_TIME = "17:30"
11
  BUSINESS_START = "09:30"
12
  BUSINESS_END = "01:30"
13
  BORDER_COLOR = '#A9A9A9'
14
+ DATE_COLOR = '#A9A9A9'
15
 
16
  def process_schedule(file):
17
  """处理上传的 Excel 文件,生成排序和分组后的打印内容"""
 
48
  # 标准化所有时间到同一天
49
  for idx, row in df.iterrows():
50
  end_time = row['EndTime']
 
51
  if end_time.hour < 9:
52
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
53
 
 
54
  if row['StartTime'].hour >= 21 and end_time.hour < 9:
55
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
56
 
57
  # 筛选营业时间内的场次
 
58
  df['time_for_comparison'] = df['EndTime'].apply(
59
  lambda x: datetime.combine(base_date, x.time())
60
  )
61
 
 
62
  df.loc[df['time_for_comparison'].dt.hour < 9, 'time_for_comparison'] += timedelta(days=1)
63
 
 
64
  valid_times = (
65
  ((df['time_for_comparison'] >= datetime.combine(base_date, business_start.time())) &
66
  (df['time_for_comparison'] <= datetime.combine(base_date + timedelta(days=1), business_end.time())))
 
84
  for part in [part1, part2]:
85
  part['EndTime'] = part['EndTime'].dt.strftime('%-I:%M')
86
 
87
+ # 关键修改:精确读取C6单元格
88
+ date_df = pd.read_excel(
89
+ file,
90
+ skiprows=5, # 跳过前5行(0-4)
91
+ nrows=1, # 只读1行
92
+ usecols=[2], # 第三列(C列)
93
+ header=None # 无表头
94
+ )
95
+ date_cell = date_df.iloc[0, 0]
96
+
97
+ try:
98
+ # 处理不同日期格式
99
+ if isinstance(date_cell, str):
100
+ date_str = datetime.strptime(date_cell, '%Y-%m-%d').strftime('%Y-%m-%d')
101
+ else:
102
+ date_str = pd.to_datetime(date_cell).strftime('%Y-%m-%d')
103
+ except:
104
+ date_str = datetime.today().strftime('%Y-%m-%d')
105
 
106
  return part1[['Hall', 'EndTime']], part2[['Hall', 'EndTime']], date_str
107
 
 
120
 
121
  # 设置字体
122
  plt.rcParams['font.family'] = 'sans-serif'
123
+ plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
124
 
125
  # 计算行数和总数
126
  total_items = len(data)
 
130
  # 创建网格
131
  gs = gridspec.GridSpec(num_rows + 1, num_cols, hspace=0.1, wspace=0.1, height_ratios=[1] * num_rows + [0.2])
132
 
133
+ base_fontsize = min(30, 265 / num_rows)
 
134
 
 
135
  data_values = data.values.tolist()
136
 
 
137
  while len(data_values) % 3 != 0:
138
  data_values.append(['', ''])
139
 
 
140
  rows_per_col = math.ceil(len(data_values) / 3)
141
 
 
142
  sorted_data = [['', '']] * len(data_values)
143
 
 
144
  for i, item in enumerate(data_values):
145
+ if item[0] and item[1]:
 
146
  row = i % rows_per_col
147
  col = i // rows_per_col
148
  new_index = row * 3 + col
149
  if new_index < len(sorted_data):
150
  sorted_data[new_index] = item
151
 
 
152
  for idx, (hall, end_time) in enumerate(sorted_data):
153
+ if hall and end_time:
154
  row = idx // 3
155
  col = idx % 3
156
 
157
  ax = plt.subplot(gs[row, col])
158
 
 
159
  for spine in ax.spines.values():
160
  spine.set_color(BORDER_COLOR)
161
  spine.set_linewidth(0.5)
162
 
 
163
  display_text = f"{hall}{end_time}"
164
  ax.text(0.5, 0.5, display_text,
165
  fontsize=base_fontsize,
 
167
  ha='center',
168
  va='center')
169
 
 
170
  ax.set_xlim(-0.02, 1.02)
171
  ax.set_ylim(-0.02, 1.02)
172
 
 
173
  ax.set_xticks([])
174
  ax.set_yticks([])
175
 
176
+ # 添加日期信息
177
  ax_date = plt.subplot(gs[0, 0])
178
  ax_date.text(0.05, 0.95, f"{date_str} {title}",
179
+ fontsize=base_fontsize * 0.4,
180
+ color=DATE_COLOR,
181
  fontweight='bold',
182
  ha='left',
183
  va='top')
184
 
 
185
  for spine in ax_date.spines.values():
186
  spine.set_visible(False)
187
  ax_date.set_xticks([])
 
206
  part1, part2, date_str = process_schedule(uploaded_file)
207
 
208
  if part1 is not None and part2 is not None:
209
+ part1_image = create_print_layout(part1, "A", date_str)
210
+ part2_image = create_print_layout(part2, "C", date_str)
 
211
 
 
212
  col1, col2 = st.columns(2)
213
 
214
  with col1:
 
223
  if part2_image:
224
  st.image(part2_image)
225
  else:
226
+ st.info("夜班部分没有数据")
227
+
228
+ # 添加打印按钮
229
+ if part1_image:
230
+ st.markdown(
231
+ f'<a href="{part1_image}" target="_blank" style="text-decoration: none;">'
232
+ '<button style="padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer;">'
233
+ '打开并打印第一部分'
234
+ '</button></a>',
235
+ unsafe_allow_html=True
236
+ )
237
+
238
+ if part2_image:
239
+ st.markdown(
240
+ f'<a href="{part2_image}" target="_blank" style="text-decoration: none;">'
241
+ '<button style="padding: 10px 20px; background-color: #2196F3; color: white; border: none; border-radius: 5px; cursor: pointer; margin-top: 10px;">'
242
+ '打开并打印第二部分'
243
+ '</button></a>',
244
+ unsafe_allow_html=True
245
+ )