Ethscriptions commited on
Commit
79fcf8c
·
verified ·
1 Parent(s): a1d5478

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -71
app.py CHANGED
@@ -12,7 +12,7 @@ from matplotlib.backends.backend_pdf import PdfPages
12
  import matplotlib.gridspec as gridspec
13
  import math
14
 
15
- # --- Constants for the second script ---
16
  SPLIT_TIME = "17:30"
17
  BUSINESS_START = "09:30"
18
  BUSINESS_END = "01:30"
@@ -22,20 +22,20 @@ A5_WIDTH_IN = 5.83
22
  A5_HEIGHT_IN = 8.27
23
  NUM_COLS = 3
24
 
25
- # --- Functions from the first script ---
26
  def get_font(size=14):
27
- """Loads a specific TrueType font, defaulting to a common Chinese font."""
28
  font_path = "simHei.ttc"
29
  if not os.path.exists(font_path):
30
  font_path = "SimHei.ttf"
31
  if os.path.exists(font_path):
32
  return font_manager.FontProperties(fname=font_path, size=size)
33
  else:
34
- st.warning("SimHei font not found. Display may not be correct. Please add simHei.ttc or SimHei.ttf.")
35
  return font_manager.FontProperties(family='sans-serif', size=size)
36
 
37
  def get_pinyin_abbr(text):
38
- """Gets the first letter of the Pinyin for the first two Chinese characters of a text."""
39
  if not text:
40
  return ""
41
  chars = [c for c in text if '\u4e00' <= c <= '\u9fff'][:2]
@@ -45,7 +45,7 @@ def get_pinyin_abbr(text):
45
  return ''.join(pinyin_list).upper()
46
 
47
  def format_seq(n):
48
- """Converts an integer to a circled number string (e.g., 1 -> ①)."""
49
  if not isinstance(n, int) or n <= 0:
50
  return str(n)
51
  circled_chars = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳" \
@@ -55,8 +55,9 @@ def format_seq(n):
55
  return circled_chars[n - 1]
56
  return f'({n})'
57
 
 
58
  def process_schedule_led(file):
59
- """Processes '放映时间核对表.xls'."""
60
  try:
61
  date_df = pd.read_excel(file, header=None, skiprows=7, nrows=1, usecols=[3])
62
  date_str = pd.to_datetime(date_df.iloc[0, 0]).strftime('%Y-%m-%d')
@@ -72,11 +73,9 @@ def process_schedule_led(file):
72
  df.dropna(subset=['StartTime', 'EndTime', 'Movie'], inplace=True)
73
  df['Hall'] = df['Hall'].astype(str).str.extract(r'(\d+号)')
74
  df['StartTime_dt'] = pd.to_datetime(df['StartTime'], format='%H:%M', errors='coerce').apply(
75
- lambda t: t.replace(year=base_date.year, month=base_date.month, day=base_date.day) if pd.notnull(t) else t
76
- )
77
  df['EndTime_dt'] = pd.to_datetime(df['EndTime'], format='%H:%M', errors='coerce').apply(
78
- lambda t: t.replace(year=base_date.year, month=base_date.month, day=base_date.day) if pd.notnull(t) else t
79
- )
80
  df.loc[df['EndTime_dt'] < df['StartTime_dt'], 'EndTime_dt'] += timedelta(days=1)
81
  df = df.sort_values(['Hall', 'StartTime_dt'])
82
  merged_rows = []
@@ -100,11 +99,11 @@ def process_schedule_led(file):
100
  merged_df['EndTime_str'] = merged_df['EndTime_dt'].dt.strftime('%H:%M')
101
  return merged_df[['Hall', 'Seq', 'Movie', 'StartTime_str', 'EndTime_str']], date_str
102
  except Exception as e:
103
- st.error(f"Error processing schedule data: {e}. Please check the file format.")
104
  return None, date_str
105
 
106
  def create_print_layout_led(data, date_str):
107
- """Generates print layouts for '放映时间核对表.xls'."""
108
  if data is None or data.empty:
109
  return None
110
  A4_width_in, A4_height_in = 8.27, 11.69
@@ -123,8 +122,7 @@ def create_print_layout_led(data, date_str):
123
  seq_font_size_pt = (row_height * 0.5) * 72
124
 
125
  def get_col_width_in(series, font_size_pt, is_math=False):
126
- if series.empty:
127
- return 0
128
  font_prop = get_font(font_size_pt)
129
  longest_str_idx = series.astype(str).str.len().idxmax()
130
  max_content = str(series.loc[longest_str_idx])
@@ -152,8 +150,7 @@ def create_print_layout_led(data, date_str):
152
  for col_name in ['hall', 'seq', 'movie', 'pinyin']:
153
  x_line = col_x_starts[col_name] + col_widths[col_name]
154
  line_top_y, line_bottom_y = A4_height_in - row_height, row_height
155
- ax.add_line(
156
- Line2D([x_line, x_line], [line_bottom_y, line_top_y], color='gray', linestyle=':', linewidth=0.5))
157
  last_hall_drawn = None
158
  for i, row in data.iterrows():
159
  y_bottom = A4_height_in - (i + 2) * row_height
@@ -176,17 +173,14 @@ def create_print_layout_led(data, date_str):
176
  if text_w_in > max_width_in:
177
  movie_font_size *= (max_width_in / text_w_in)
178
  movie_font_prop = get_font(movie_font_size)
179
- ax.text(col_x_starts['movie'] + 0.05, y_center, row['Movie'],
180
- fontproperties=movie_font_prop, ha='left', va='center')
181
  is_last_in_hall = (i == len(data) - 1) or (row['Hall'] != data.loc[i + 1, 'Hall'])
182
  line_start_x = margin_col_width
183
  line_end_x = A4_width_in - margin_col_width
184
  if is_last_in_hall:
185
- ax.add_line(Line2D([line_start_x, line_end_x], [y_bottom, y_bottom], color='black', linestyle='-',
186
- linewidth=0.8))
187
  else:
188
- ax.add_line(Line2D([line_start_x, line_end_x], [y_bottom, y_bottom], color='gray', linestyle=':',
189
- linewidth=0.5))
190
 
191
  outputs = {}
192
  for format_type in ['png', 'pdf']:
@@ -207,16 +201,15 @@ def create_print_layout_led(data, date_str):
207
  plt.close(fig)
208
  return outputs
209
 
210
- # --- Functions from the second script ---
211
  def process_schedule_times(file):
212
- """Processes '放映场次核对表.xls'."""
213
  try:
214
  df = pd.read_excel(file, skiprows=8)
215
  df = df.iloc[:, [6, 7, 9]]
216
  df.columns = ['Hall', 'StartTime', 'EndTime']
217
  df = df.dropna(subset=['Hall', 'StartTime', 'EndTime'])
218
  df['Hall'] = df['Hall'].str.extract(r'(\d+)号').astype(str) + ' '
219
- df['original_end'] = df['EndTime']
220
  base_date = datetime.today().date()
221
  df['StartTime'] = pd.to_datetime(df['StartTime'])
222
  df['EndTime'] = pd.to_datetime(df['EndTime'])
@@ -230,31 +223,19 @@ def process_schedule_times(file):
230
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
231
  if row['StartTime'].hour >= 21 and end_time.hour < 9:
232
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
233
- df['time_for_comparison'] = df['EndTime'].apply(
234
- lambda x: datetime.combine(base_date, x.time())
235
- )
236
  df.loc[df['time_for_comparison'].dt.hour < 9, 'time_for_comparison'] += timedelta(days=1)
237
- valid_times = (
238
- ((df['time_for_comparison'] >= datetime.combine(base_date, business_start.time())) &
239
- (df['time_for_comparison'] <= datetime.combine(base_date + timedelta(days=1), business_end.time())))
240
- )
241
  df = df[valid_times]
242
  df = df.sort_values('EndTime')
243
  split_time = datetime.strptime(f"{base_date} {SPLIT_TIME}", "%Y-%m-%d %H:%M")
244
- split_time_for_comparison = df['time_for_comparison'].apply(
245
- lambda x: datetime.combine(base_date, split_time.time())
246
- )
247
  part1 = df[df['time_for_comparison'] <= split_time_for_comparison].copy()
248
  part2 = df[df['time_for_comparison'] > split_time_for_comparison].copy()
249
  for part in [part1, part2]:
250
  part['EndTime'] = part['EndTime'].dt.strftime('%-H:%M')
251
- date_df = pd.read_excel(
252
- file,
253
- skiprows=5,
254
- nrows=1,
255
- usecols=[2],
256
- header=None
257
- )
258
  date_cell = date_df.iloc[0, 0]
259
  try:
260
  if isinstance(date_cell, str):
@@ -265,11 +246,11 @@ def process_schedule_times(file):
265
  date_str = datetime.today().strftime('%Y-%m-%d')
266
  return part1[['Hall', 'EndTime']], part2[['Hall', 'EndTime']], date_str
267
  except Exception as e:
268
- st.error(f"处理文件时出错: {str(e)}")
269
  return None, None, None
270
 
271
  def create_print_layout_times(data, title, date_str):
272
- """Creates print layouts for '放映场次核对表.xls'."""
273
  if data.empty:
274
  return None
275
 
@@ -289,13 +270,12 @@ def create_print_layout_times(data, title, date_str):
289
  fig = plt.figure(figsize=(A5_WIDTH_IN, A5_HEIGHT_IN), dpi=300)
290
  fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
291
  plt.rcParams['font.family'] = 'sans-serif'
292
- plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
293
  gs = gridspec.GridSpec(
294
  num_rows + 1, NUM_COLS,
295
  hspace=0, wspace=0,
296
  height_ratios=[date_header_height_in] + [cell_height_in] * num_rows,
297
- figure=fig
298
- )
299
  data_values = data.values.tolist()
300
  while len(data_values) % NUM_COLS != 0:
301
  data_values.append(['', ''])
@@ -320,7 +300,7 @@ def create_print_layout_times(data, title, date_str):
320
  spine.set_linewidth(0.75)
321
  display_text = f"{hall}{end_time}"
322
  ax.text(0.5, 0.5, display_text,
323
- fontsize=base_fontsize,
324
  fontweight='bold',
325
  ha='center', va='center',
326
  transform=ax.transAxes)
@@ -329,7 +309,7 @@ def create_print_layout_times(data, title, date_str):
329
  ax.set_facecolor('none')
330
  ax_date = fig.add_subplot(gs[0, :])
331
  ax_date.text(0.01, 0.5, f"{date_str} {title}",
332
- fontsize=base_fontsize * 0.5,
333
  color=DATE_COLOR, fontweight='bold',
334
  ha='left', va='center',
335
  transform=ax_date.transAxes)
@@ -348,61 +328,58 @@ def create_print_layout_times(data, title, date_str):
348
  pdf_buffer.seek(0)
349
  pdf_base64 = base64.b64encode(pdf_buffer.getvalue()).decode()
350
  plt.close(fig_for_output)
351
- return {
352
- 'png': f'data:image/png;base64,{png_base64}',
353
- 'pdf': f'data:application/pdf;base64,{pdf_base64}'
354
- }
355
 
356
  def display_pdf(base64_pdf):
357
- """Generates the HTML to embed a PDF in Streamlit."""
358
  return f'<iframe src="{base64_pdf}" width="100%" height="800" type="application/pdf"></iframe>'
359
 
360
- # --- Streamlit App ---
361
- st.set_page_config(page_title="Schedule Printer", layout="wide")
362
- st.title("Schedule Printer")
363
 
364
- uploaded_file = st.file_uploader("Select '放映时间核对表.xls' or '放映场次核对表.xls'",
365
  type=["xls", "xlsx"])
366
 
367
  if uploaded_file:
 
368
  if "时间" in uploaded_file.name:
369
- st.header("LED Screen Schedule")
370
- with st.spinner("Processing file, please wait..."):
371
  schedule, date_str = process_schedule_led(uploaded_file)
372
  if schedule is not None and not schedule.empty:
373
  output = create_print_layout_led(schedule, date_str)
374
- tab1, tab2 = st.tabs(["PDF Preview", "PNG Preview"])
375
  with tab1:
376
  st.markdown(display_pdf(output['pdf']), unsafe_allow_html=True)
377
  with tab2:
378
  st.image(output['png'], use_container_width=True)
379
  else:
380
- st.error("Could not process the file. Please check if the file format and content are correct.")
381
  elif "场次" in uploaded_file.name:
382
- st.header("Screening Times Quick Print")
383
  part1, part2, date_str = process_schedule_times(uploaded_file)
384
  if part1 is not None and part2 is not None:
385
  part1_output = create_print_layout_times(part1, "A", date_str)
386
  part2_output = create_print_layout_times(part2, "C", date_str)
387
  col1, col2 = st.columns(2)
388
  with col1:
389
- st.subheader("Day Shift (End time <= 17:30)")
390
  if part1_output:
391
- tab1_1, tab1_2 = st.tabs(["PDF Preview", "PNG Preview"])
392
  with tab1_1:
393
  st.markdown(display_pdf(part1_output['pdf']), unsafe_allow_html=True)
394
  with tab1_2:
395
  st.image(part1_output['png'])
396
  else:
397
- st.info("No data for the day shift.")
398
  with col2:
399
- st.subheader("Night Shift (End time > 17:30)")
400
  if part2_output:
401
- tab2_1, tab2_2 = st.tabs(["PDF Preview", "PNG Preview"])
402
  with tab2_1:
403
  st.markdown(display_pdf(part2_output['pdf']), unsafe_allow_html=True)
404
  with tab2_2:
405
  st.image(part2_output['png'])
406
  else:
407
- st.info("No data for the night shift.")
408
-
 
12
  import matplotlib.gridspec as gridspec
13
  import math
14
 
15
+ # --- 常量定义 ---
16
  SPLIT_TIME = "17:30"
17
  BUSINESS_START = "09:30"
18
  BUSINESS_END = "01:30"
 
22
  A5_HEIGHT_IN = 8.27
23
  NUM_COLS = 3
24
 
25
+ # --- 字体加载与文本处理函数 ---
26
  def get_font(size=14):
27
+ """加载中文字体文件"""
28
  font_path = "simHei.ttc"
29
  if not os.path.exists(font_path):
30
  font_path = "SimHei.ttf"
31
  if os.path.exists(font_path):
32
  return font_manager.FontProperties(fname=font_path, size=size)
33
  else:
34
+ st.warning("警告:未找到SimHei字体文件,显示可能不正确。请将 simHei.ttc SimHei.ttf 文件放入项目文件夹。")
35
  return font_manager.FontProperties(family='sans-serif', size=size)
36
 
37
  def get_pinyin_abbr(text):
38
+ """获取中文文本前两个字的拼音首字母"""
39
  if not text:
40
  return ""
41
  chars = [c for c in text if '\u4e00' <= c <= '\u9fff'][:2]
 
45
  return ''.join(pinyin_list).upper()
46
 
47
  def format_seq(n):
48
+ """将数字转换为带圈序号 (①, ②, ③...)"""
49
  if not isinstance(n, int) or n <= 0:
50
  return str(n)
51
  circled_chars = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳" \
 
55
  return circled_chars[n - 1]
56
  return f'({n})'
57
 
58
+ # --- '放映时间核对表' 处理函数 ---
59
  def process_schedule_led(file):
60
+ """处理 '放映时间核对表.xls' 文件"""
61
  try:
62
  date_df = pd.read_excel(file, header=None, skiprows=7, nrows=1, usecols=[3])
63
  date_str = pd.to_datetime(date_df.iloc[0, 0]).strftime('%Y-%m-%d')
 
73
  df.dropna(subset=['StartTime', 'EndTime', 'Movie'], inplace=True)
74
  df['Hall'] = df['Hall'].astype(str).str.extract(r'(\d+号)')
75
  df['StartTime_dt'] = pd.to_datetime(df['StartTime'], format='%H:%M', errors='coerce').apply(
76
+ lambda t: t.replace(year=base_date.year, month=base_date.month, day=base_date.day) if pd.notnull(t) else t)
 
77
  df['EndTime_dt'] = pd.to_datetime(df['EndTime'], format='%H:%M', errors='coerce').apply(
78
+ lambda t: t.replace(year=base_date.year, month=base_date.month, day=base_date.day) if pd.notnull(t) else t)
 
79
  df.loc[df['EndTime_dt'] < df['StartTime_dt'], 'EndTime_dt'] += timedelta(days=1)
80
  df = df.sort_values(['Hall', 'StartTime_dt'])
81
  merged_rows = []
 
99
  merged_df['EndTime_str'] = merged_df['EndTime_dt'].dt.strftime('%H:%M')
100
  return merged_df[['Hall', 'Seq', 'Movie', 'StartTime_str', 'EndTime_str']], date_str
101
  except Exception as e:
102
+ st.error(f"处理数据出错: {e}。请检查文件格式是否正确。")
103
  return None, date_str
104
 
105
  def create_print_layout_led(data, date_str):
106
+ """ '放映时间核对表' 生成打印布局"""
107
  if data is None or data.empty:
108
  return None
109
  A4_width_in, A4_height_in = 8.27, 11.69
 
122
  seq_font_size_pt = (row_height * 0.5) * 72
123
 
124
  def get_col_width_in(series, font_size_pt, is_math=False):
125
+ if series.empty: return 0
 
126
  font_prop = get_font(font_size_pt)
127
  longest_str_idx = series.astype(str).str.len().idxmax()
128
  max_content = str(series.loc[longest_str_idx])
 
150
  for col_name in ['hall', 'seq', 'movie', 'pinyin']:
151
  x_line = col_x_starts[col_name] + col_widths[col_name]
152
  line_top_y, line_bottom_y = A4_height_in - row_height, row_height
153
+ ax.add_line(Line2D([x_line, x_line], [line_bottom_y, line_top_y], color='gray', linestyle=':', linewidth=0.5))
 
154
  last_hall_drawn = None
155
  for i, row in data.iterrows():
156
  y_bottom = A4_height_in - (i + 2) * row_height
 
173
  if text_w_in > max_width_in:
174
  movie_font_size *= (max_width_in / text_w_in)
175
  movie_font_prop = get_font(movie_font_size)
176
+ ax.text(col_x_starts['movie'] + 0.05, y_center, row['Movie'], fontproperties=movie_font_prop, ha='left', va='center')
 
177
  is_last_in_hall = (i == len(data) - 1) or (row['Hall'] != data.loc[i + 1, 'Hall'])
178
  line_start_x = margin_col_width
179
  line_end_x = A4_width_in - margin_col_width
180
  if is_last_in_hall:
181
+ ax.add_line(Line2D([line_start_x, line_end_x], [y_bottom, y_bottom], color='black', linestyle='-', linewidth=0.8))
 
182
  else:
183
+ ax.add_line(Line2D([line_start_x, line_end_x], [y_bottom, y_bottom], color='gray', linestyle=':', linewidth=0.5))
 
184
 
185
  outputs = {}
186
  for format_type in ['png', 'pdf']:
 
201
  plt.close(fig)
202
  return outputs
203
 
204
+ # --- '放映场次核对表' 处理函数 ---
205
  def process_schedule_times(file):
206
+ """处理 '放映场次核对表.xls' 文件"""
207
  try:
208
  df = pd.read_excel(file, skiprows=8)
209
  df = df.iloc[:, [6, 7, 9]]
210
  df.columns = ['Hall', 'StartTime', 'EndTime']
211
  df = df.dropna(subset=['Hall', 'StartTime', 'EndTime'])
212
  df['Hall'] = df['Hall'].str.extract(r'(\d+)号').astype(str) + ' '
 
213
  base_date = datetime.today().date()
214
  df['StartTime'] = pd.to_datetime(df['StartTime'])
215
  df['EndTime'] = pd.to_datetime(df['EndTime'])
 
223
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
224
  if row['StartTime'].hour >= 21 and end_time.hour < 9:
225
  df.at[idx, 'EndTime'] = end_time + timedelta(days=1)
226
+ df['time_for_comparison'] = df['EndTime'].apply(lambda x: datetime.combine(base_date, x.time()))
 
 
227
  df.loc[df['time_for_comparison'].dt.hour < 9, 'time_for_comparison'] += timedelta(days=1)
228
+ valid_times = (((df['time_for_comparison'] >= datetime.combine(base_date, business_start.time())) &
229
+ (df['time_for_comparison'] <= datetime.combine(base_date + timedelta(days=1), business_end.time()))))
 
 
230
  df = df[valid_times]
231
  df = df.sort_values('EndTime')
232
  split_time = datetime.strptime(f"{base_date} {SPLIT_TIME}", "%Y-%m-%d %H:%M")
233
+ split_time_for_comparison = df['time_for_comparison'].apply(lambda x: datetime.combine(base_date, split_time.time()))
 
 
234
  part1 = df[df['time_for_comparison'] <= split_time_for_comparison].copy()
235
  part2 = df[df['time_for_comparison'] > split_time_for_comparison].copy()
236
  for part in [part1, part2]:
237
  part['EndTime'] = part['EndTime'].dt.strftime('%-H:%M')
238
+ date_df = pd.read_excel(file, skiprows=5, nrows=1, usecols=[2], header=None)
 
 
 
 
 
 
239
  date_cell = date_df.iloc[0, 0]
240
  try:
241
  if isinstance(date_cell, str):
 
246
  date_str = datetime.today().strftime('%Y-%m-%d')
247
  return part1[['Hall', 'EndTime']], part2[['Hall', 'EndTime']], date_str
248
  except Exception as e:
249
+ st.error(f"处理文件出错: {str(e)}")
250
  return None, None, None
251
 
252
  def create_print_layout_times(data, title, date_str):
253
+ """ '放映场次核对表' 生成打印布局"""
254
  if data.empty:
255
  return None
256
 
 
270
  fig = plt.figure(figsize=(A5_WIDTH_IN, A5_HEIGHT_IN), dpi=300)
271
  fig.subplots_adjust(left=0, right=1, top=1, bottom=0)
272
  plt.rcParams['font.family'] = 'sans-serif'
273
+ plt.rcParams['font.sans-serif'] = ['SimHei']
274
  gs = gridspec.GridSpec(
275
  num_rows + 1, NUM_COLS,
276
  hspace=0, wspace=0,
277
  height_ratios=[date_header_height_in] + [cell_height_in] * num_rows,
278
+ figure=fig)
 
279
  data_values = data.values.tolist()
280
  while len(data_values) % NUM_COLS != 0:
281
  data_values.append(['', ''])
 
300
  spine.set_linewidth(0.75)
301
  display_text = f"{hall}{end_time}"
302
  ax.text(0.5, 0.5, display_text,
303
+ fontproperties=get_font(base_fontsize),
304
  fontweight='bold',
305
  ha='center', va='center',
306
  transform=ax.transAxes)
 
309
  ax.set_facecolor('none')
310
  ax_date = fig.add_subplot(gs[0, :])
311
  ax_date.text(0.01, 0.5, f"{date_str} {title}",
312
+ fontproperties=get_font(base_fontsize * 0.5),
313
  color=DATE_COLOR, fontweight='bold',
314
  ha='left', va='center',
315
  transform=ax_date.transAxes)
 
328
  pdf_buffer.seek(0)
329
  pdf_base64 = base64.b64encode(pdf_buffer.getvalue()).decode()
330
  plt.close(fig_for_output)
331
+ return {'png': f'data:image/png;base64,{png_base64}', 'pdf': f'data:application/pdf;base64,{pdf_base64}'}
 
 
 
332
 
333
  def display_pdf(base64_pdf):
334
+ """在Streamlit中嵌入显示PDF"""
335
  return f'<iframe src="{base64_pdf}" width="100%" height="800" type="application/pdf"></iframe>'
336
 
337
+ # --- Streamlit 主程序 ---
338
+ st.set_page_config(page_title="影院排期打印工具", layout="wide")
339
+ st.title("影院排期打印工具")
340
 
341
+ uploaded_file = st.file_uploader("请上传 '放映时间核对表.xls' '放映场次核对表.xls'",
342
  type=["xls", "xlsx"])
343
 
344
  if uploaded_file:
345
+ # 根据文件名中的关键字判断使用哪个处理流程
346
  if "时间" in uploaded_file.name:
347
+ st.header("LED屏排片表")
348
+ with st.spinner("正在处理文件,请稍候..."):
349
  schedule, date_str = process_schedule_led(uploaded_file)
350
  if schedule is not None and not schedule.empty:
351
  output = create_print_layout_led(schedule, date_str)
352
+ tab1, tab2 = st.tabs(["PDF 预览", "图片预览 (PNG)"])
353
  with tab1:
354
  st.markdown(display_pdf(output['pdf']), unsafe_allow_html=True)
355
  with tab2:
356
  st.image(output['png'], use_container_width=True)
357
  else:
358
+ st.error("无法处理文件。请检查文件内容和格式是否正确。")
359
  elif "场次" in uploaded_file.name:
360
+ st.header("散场时间快捷打印")
361
  part1, part2, date_str = process_schedule_times(uploaded_file)
362
  if part1 is not None and part2 is not None:
363
  part1_output = create_print_layout_times(part1, "A", date_str)
364
  part2_output = create_print_layout_times(part2, "C", date_str)
365
  col1, col2 = st.columns(2)
366
  with col1:
367
+ st.subheader("白班 (散场时间 17:30)")
368
  if part1_output:
369
+ tab1_1, tab1_2 = st.tabs(["PDF 预览 ", "图片预览 (PNG) "]) # 添加空格以区分
370
  with tab1_1:
371
  st.markdown(display_pdf(part1_output['pdf']), unsafe_allow_html=True)
372
  with tab1_2:
373
  st.image(part1_output['png'])
374
  else:
375
+ st.info("白班没有排期数据。")
376
  with col2:
377
+ st.subheader("晚班 (散场时间 > 17:30)")
378
  if part2_output:
379
+ tab2_1, tab2_2 = st.tabs(["PDF 预览 ", "图片预览 (PNG) "]) # 添加空格以区分
380
  with tab2_1:
381
  st.markdown(display_pdf(part2_output['pdf']), unsafe_allow_html=True)
382
  with tab2_2:
383
  st.image(part2_output['png'])
384
  else:
385
+ st.info("晚班没有排期数据。")