``` def get_5_workdays_back(end_date=None): """计算从结束日期倒推5个工作日的起始日期""" end_date = pd.Timestamp.now().normalize() if end_date is None else end_date count = 0 current_date = end_date # 复用原有节假日配置 holidays = [ # 元旦(不调休) '2025-01-01', # 周三 # 春节(调休2天) '2025-01-28', '2025-01-29', '2025-01-30', '2025-01-31', '2025-02-01', '2025-02-02', '2025-02-03', '2025-02-04', # 1.28(除夕)-2.4 # 清明节(不调休) '2025-04-04', '2025-04-05', '2025-04-06', # 周五-周日 # 劳动节(调休1天) '2025-05-01', '2025-05-02', '2025-05-03', '2025-05-04', '2025-05-05', # 周四-周一 # 端午节(不调休) '2025-05-31', '2025-06-01', '2025-06-02', # 周六-周一 # 中秋节+国庆节(调休2天) '2025-10-01', '2025-10-02', '2025-10-03', '2025-10-04', '2025-10-05', '2025-10-06', '2025-10-07', '2025-10-08' # 周三-下周三 ] holiday_dates = pd.to_datetime(holidays) # 新增调休工作日列表(转换为日期格式) workdays_adjustment = [ '2025-01-26', # 周日补春节 '2025-02-08', # 周六补春节 '2025-04-27', # 周日补劳动节 '2025-09-28', # 周日补国庆 '2025-10-11' # 周六补国庆 ] adjustment_dates = pd.to_datetime(workdays_adjustment) # 转换日期格式 while count < 5: current_date -= pd.Timedelta(days=1) # 判断是否为有效工作日 is_workday = ( (current_date.weekday() < 5 or current_date in adjustment_dates) and current_date not in holiday_dates ) if is_workday: count += 1 return current_date, end_date # 获取处理后的数据 df = getchaoshi() # 计算时间范围 start_date, end_date = get_5_workdays_back() date_mask = (df['收案时间'] >= start_date) & (df['收案时间'] <= end_date) weekly_cases = df[date_mask].copy() # 计算上周时间范围 last_week_start, _ = get_5_workdays_back(start_date) date_mask_last_week = (df['收案时间'] >= last_week_start) & (df['收案时间'] < start_date) last_weekly_cases = df[date_mask_last_week].copy() # 分组统计上周数据 last_week_stats = last_weekly_cases.groupby('组别')['案件状态'].count().reset_index() last_week_stats.columns = ['组别', '上周总案件数'] # 新增:统计上周已完成案件(根据结案时间) date_mask_last_week_closed = (df['结案时间'] >= last_week_start) & (df['结案时间'] < start_date) last_week_closed_cases = df[date_mask_last_week_closed].copy() # 分组统计上周已完成数据 last_week_closed_stats = last_week_closed_cases.groupby('组别')['案件状态'].count().reset_index() last_week_closed_stats.columns = ['组别', '上周已完成情况'] # 添加状态分类列 weekly_cases['状态分类'] = weekly_cases['案件状态'].apply( lambda x: '已完成' if x in ['办结', '发件'] else '正在处理' ) # 分组统计 result = weekly_cases.groupby('组别').agg( 总案件数=('案件状态', 'count'), 已完成=('状态分类', lambda x: (x == '已完成').sum()), 处理中=('状态分类', lambda x: (x == '正在处理').sum()), 超时案件数=('是否超时', lambda x: (x == '是').sum()), 缓办案件数=('是否缓办', lambda x: (x == '是').sum()) # 新增行 ).reset_index() # # 合并上周数据 # result = result.merge(last_week_stats, on='组别', how='left').fillna(0) # 合并三组数据(原代码基础上增加新列) result = result.merge(last_week_stats, on='组别', how='left') result = result.merge(last_week_closed_stats, on='组别', how='left').fillna(0) # 新增:添加总计行(核心修改点) total_row = { '组别': '总计', '总案件数': result['总案件数'].sum(), '已完成': result['已完成'].sum(), '处理中': result['处理中'].sum(), '超时案件数': result['超时案件数'].sum(), '缓办案件数': result['缓办案件数'].sum(), '上周总案件数': result['上周总案件数'].sum(), '上周已完成情况': result['上周已完成情况'].sum() # 新增列 } result = pd.concat([result, pd.DataFrame([total_row])], ignore_index=True) # 结果展示样例 print(result.to_markdown(index=False)) # 创建Excel写入对象(注意:需要安装openpyxl) with ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer: # 将result写入Sheet1 result.to_excel(writer, sheet_name='按周统计情况', index=False) # 将原始数据写入Sheet2 weekly_cases.to_excel(writer, sheet_name='本周案件', index=False) # 将原始数据写入Sheet3 df.to_excel(writer, sheet_name='所有案件', index=False)```输出按周统计情况的表中,增加一列“查询时间”到第一列,输出程序运行的时间,并合并第一列下面的6行,均显示这个时间
时间: 2025-07-13 20:44:31 浏览: 20
<think>嗯,用户让我在他们的Python代码中,在生成的Excel表格的“按周统计情况”工作表里,增加一列“查询时间”到第一列,显示程序运行的时间,并且合并这一列下面的所有行,都显示同一个时间。我需要仔细分析他们的现有代码,找出需要修改的地方。
首先,看用户现有的代码,他们使用pandas的ExcelWriter将result DataFrame写入到Excel的“按周统计情况”sheet中。为了添加新的列“查询时间”,应该在result DataFrame中添加这一列,然后再输出到Excel。
但用户还提到需要合并第一列下面的6行,也就是合并单元格。这里需要注意的是,直接使用pandas的to_excel方法可能无法直接实现合并单元格的操作,通常需要借助openpyxl库的合并单元格功能来处理。
不过,用户可能希望“查询时间”这一列的所有行都显示同一个时间,也就是每个组别和总计行都显示相同的运行时间。因此,首先需要在生成result DataFrame的时候,添加一列“查询时间”,其值为当前时间。然后,在写入Excel时,将这一列的单元格合并。
步骤可能如下:
1. 在生成result DataFrame后,添加“查询时间”列,值为当前时间,比如使用pd.Timestamp.now(),并且确保所有行的这个值相同。
2. 在将result写入Excel后,使用openpyxl的工作表操作来合并单元格。例如,找到“查询时间”所在的列(假设是第一列),然后合并A2到A7(假设有6行数据,包括总计行)。
需要注意的问题:
- 当前时间的获取时机:应该在程序运行时获取一次,而不是每行都获取,否则可能出现时间不一致的情况。比如在开始处理数据前就获取运行时间,存储为一个变量,然后在添加列时使用该变量。
- 合并单元格的操作需要在写入Excel之后,通过操作工作表对象来完成,因为pandas本身不直接支持合并单元格。
现在,具体查看用户的代码:
在代码的最后部分,用户使用ExcelWriter将result写入到'按周统计情况' sheet中。所以,可能的修改点是在生成result之后,添加“查询时间”列,然后在写入Excel后,操作sheet进行合并。
例如:
在生成result之后,添加:
import datetime
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
result.insert(0, '查询时间', current_time)
这样会在第一列插入“查询时间”,所有行的值都是current_time。
然后,在写入Excel后,使用openpyxl来合并单元格。因为to_excel写入之后,需要通过writer.sheets访问具体的sheet对象。例如:
with pd.ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer:
result.to_excel(writer, sheet_name='按周统计情况', index=False)
# 获取sheet
worksheet = writer.sheets['按周统计情况']
# 合并A2到A(n)单元格,假设有5组加上总计共6行数据
# 注意:标题行是第一行,数据从第二行开始
# 例如,如果有6行数据,合并A2到A7
worksheet.merge_cells('A2:A7') # 假设总共有6行数据,包括总计
但这里存在一个问题:result的行数可能不固定,取决于组别数量。例如,原本的代码中,result在添加总计行之前可能有多个组别,然后加上总计。例如,如果有5个组别,加上总计就是6行。所以合并的单元格范围应该是从第二行到第七行(假设数据行从第二行开始)。
但如何动态确定行数?比如,可以通过result的行数来确定。例如,result有n行,那么合并的单元格范围是A2到A(n+1),因为标题行是第一行,数据行从第二行开始,到第n+1行结束。
在openpyxl中,可以使用字符串范围,或者使用行列索引。例如:
start_row = 2 # 数据从第二行开始(标题行是第一行)
end_row = start_row + len(result) - 1 # 因为result的行数等于数据行数
worksheet.merge_cells(start_row=start_row, start_column=1, end_row=end_row, end_column=1)
或者转换为字母,比如列'A'是第一列,所以start_column=1。
所以,代码可能如下:
在写入Excel后:
worksheet = writer.sheets['按周统计情况']
# 合并查询时间列,从第二行到最后一行的数据
start_row = 2
end_row = start_row + len(result) - 1 # 因为result有len(result)行数据,所以行号是2到2 + len(result)-1
worksheet.merge_cells(start_row=start_row, start_column=1, end_row=end_row, end_column=1)
这样就能动态合并所有数据行的查询时间列。
但需要注意的是,当使用result.to_excel时,列的顺序是否正确。因为用户要求“查询时间”是第一列,所以在插入列的时候使用insert(0, ...),确保它在最前面。
此外,时间的格式可能需要处理,比如只显示日期还是包括时间。用户可能需要当前的运行时间,所以应该在添加列的时候获取一次时间,确保所有行的时间一致。
总结步骤:
1. 在生成result DataFrame之后,插入“查询时间”列,值为程序运行时的当前时间,格式化为字符串。
2. 使用openpyxl合并该列的所有数据行的单元格。
可能的代码修改:
在result的生成之后,添加:
import datetime
query_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
result.insert(0, '查询时间', query_time)
然后,在写入Excel时,进行合并:
with pd.ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer:
result.to_excel(writer, sheet_name='按周统计情况', index=False)
# 获取工作表
workbook = writer.book
worksheet = writer.sheets['按周统计情况']
# 合并查询时间列的单元格
# 数据行数:len(result)
start_row = 2 # 数据从第二行开始(第一行是标题)
end_row = start_row + len(result) - 1
worksheet.merge_cells(start_row=start_row, start_column=1, end_row=end_row, end_column=1)
但需要注意,使用openpyxl时,可能需要先加载现有的工作表,或者确保在写入时没有冲突。此外,当使用pd.ExcelWriter时,如果文件已存在,可能需要设置mode='a',但这里用户可能每次都是生成新文件,所以默认的mode='w'应该没问题。
不过,当engine是openpyxl时,ExcelWriter默认会以写入模式打开,如果文件存在会覆盖。所以代码应该是可行的。
测试可能出现的问题:
- 插入列的位置是否正确,确保是第一列。
- 合并的单元格范围是否正确,特别是当result的行数变化时。
- 时间的格式是否正确,是否所有行都显示同一个时间。
这样修改后,输出的Excel表格中的“按周统计情况”工作表的第一列就是“查询时间”,所有数据行的该列都显示运行时间,并且合并单元格,只显示一个时间。</think>在Python代码中添加「查询时间」列并实现单元格合并,可以通过以下步骤实现:
====================
修改后的核心代码部分
====================
```python
# 在result生成后添加时间列(注意要放在最后的总计行生成之后)
query_time = pd.Timestamp.now().strftime("%Y-%m-%d %H:%M") # 统一时间格式
result.insert(0, '查询时间', query_time) # 插入到第一列
# 创建Excel写入对象
with pd.ExcelWriter('GCB案件统计结果t4.xlsx', engine='openpyxl') as writer:
# 写入时关闭自动列宽调整(避免合并单元格报错)
result.to_excel(writer, sheet_name='按周统计情况', index=False, startrow=0)
# 获取工作表对象
workbook = writer.book
worksheet = writer.sheets['按周统计情况']
# 计算合并范围(假设数据行数为n)
start_row = 2 # 数据起始行(标题占第1行)
end_row = start_row + len(result) - 1 # 数据结束行
# 执行合并操作
worksheet.merge_cells(
start_row=start_row,
end_row=end_row,
start_column=1, # 第一列
end_column=1
)
# 调整列宽(可选)
worksheet.column_dimensions['A'].width = 16 # 设置查询时间列宽
```
====================
主要修改点说明
====================
1. **时间获取与插入**
- 使用`pd.Timestamp.now()`获取程序运行时的时间
- 通过`insert(0, ...)`将时间列插入DataFrame第一列
- 示例输出效果:
```
| 查询时间 | 组别 | 总案件数 | 已完成 | ... |
|----------------|------|----------|--------|-----|
| 2024-03-15 14:30 | 一组 | 25 | 20 | ... |
```
2. **单元格合并逻辑**
- `start_row=2`:Excel行号从1开始,数据行从第2行开始
- `end_row`计算:根据DataFrame行数动态确定结束位置
- 合并效果:A2:A7单元格合并显示同一个时间值
3. **注意事项**
- 合并操作必须在数据写入之后执行
- 使用openpyxl引擎时需要预先安装库
- 如果数据行数变化,合并范围会自动适应
====================
完整代码集成建议
====================
在您原有代码的以下位置进行修改:
```python
# 原代码
result = pd.concat([result, pd.DataFrame([total_row])], ignore_index=True)
# 新增代码(插入时间列)
query_time = pd.Timestamp.now().strftime("%Y-%m-%d %H:%M")
result.insert(0, '查询时间', query_time)
# 原Excel输出代码
with pd.ExcelWriter(...) as writer:
# 修改后的输出逻辑(添加合并代码)
```
最终生成的Excel表格样式:
$$
\begin{array}{|c|c|c|c|}
\hline
\text{查询时间} & \text{组别} & \text{总案件数} & ... \\
\hline
\multirow{5}{*}{2024-03-15 14:30} & 一组 & 25 & ... \\
\cline{2-4}
& 二组 & 30 & ... \\
\cline{2-4}
& ... & ... & ... \\
\cline{2-4}
& 总计 & 100 & ... \\
\hline
\end{array}
$$
该方案可以动态适应数据行数变化,确保时间列始终正确显示程序运行时刻并保持单元格合并效果。
阅读全文
相关推荐






