活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

使用pandas轻松将数据输出到Excel文件的完整指南从基础操作到高级技巧全面解析数据处理与导出流程解决实际工作中的数据保存与分享问题

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-17 10:30:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

在当今数据驱动的世界中,数据处理和分析已成为各行各业不可或缺的技能。Python的pandas库作为数据科学领域最强大的工具之一,提供了丰富的数据操作和分析功能。而Excel作为最广泛使用的数据展示和分享工具,在商业环境中占据着重要地位。将这两者结合,可以极大地提高数据处理的效率和成果的可分享性。本指南将全面介绍如何使用pandas将数据输出到Excel文件,从基础操作到高级技巧,帮助您解决实际工作中的数据保存与分享问题。

基础操作

安装必要的库

在开始之前,我们需要确保安装了必要的库。pandas本身不包含写入Excel文件的功能,需要依赖其他库来实现:
  1. # 安装pandas和Excel写入引擎
  2. pip install pandas openpyxl xlsxwriter
复制代码

• pandas: 核心数据处理库
• openpyxl: 用于读写Excel 2010及以上版本的.xlsx文件
• xlsxwriter: 另一个Excel写入引擎,提供更多格式化选项

创建DataFrame并导出到Excel

让我们从最基本的操作开始:创建一个DataFrame并将其导出到Excel文件。
  1. import pandas as pd
  2. # 创建一个简单的DataFrame
  3. data = {
  4.     '姓名': ['张三', '李四', '王五', '赵六'],
  5.     '年龄': [25, 30, 35, 28],
  6.     '城市': ['北京', '上海', '广州', '深圳'],
  7.     '薪资': [8000, 12000, 15000, 10000]
  8. }
  9. df = pd.DataFrame(data)
  10. # 将DataFrame导出到Excel文件
  11. df.to_excel('员工信息.xlsx', index=False)  # index=False表示不写入行索引
复制代码

to_excel()方法是最基本的导出函数,它有几个常用参数:

• excel_writer: 文件路径或ExcelWriter对象
• sheet_name: 工作表名称,默认为’Sheet1’
• na_rep: 用于替换缺失值的字符串,默认为空字符串
• float_format: 浮点数格式字符串,例如’%.2f’表示保留两位小数
• columns: 要写入的列列表
• header: 是否写入列名,默认为True
• index: 是否写入行索引,默认为True
• index_label: 索引列的列标签

控制导出格式

我们可以通过调整参数来控制导出的格式:
  1. # 导出时控制格式
  2. df.to_excel(
  3.     '员工信息_格式化.xlsx',
  4.     sheet_name='员工数据',  # 设置工作表名称
  5.     na_rep='NULL',  # 缺失值替换为NULL
  6.     float_format='%.2f',  # 浮点数保留两位小数
  7.     columns=['姓名', '年龄', '城市'],  # 只导出指定列
  8.     header=True,  # 包含列名
  9.     index=False,  # 不包含行索引
  10.     encoding='utf-8'  # 设置编码
  11. )
复制代码

中级技巧

多工作表操作

在实际工作中,我们经常需要将多个DataFrame导出到同一个Excel文件的不同工作表中。这时,我们需要使用ExcelWriter对象:
  1. import pandas as pd
  2. # 创建两个DataFrame
  3. data1 = {
  4.     '产品ID': ['P001', 'P002', 'P003'],
  5.     '产品名称': ['笔记本电脑', '平板电脑', '智能手机'],
  6.     '价格': [5999, 2999, 3999]
  7. }
  8. df1 = pd.DataFrame(data1)
  9. data2 = {
  10.     '订单ID': ['O001', 'O002', 'O003'],
  11.     '产品ID': ['P001', 'P002', 'P003'],
  12.     '数量': [2, 5, 3],
  13.     '日期': ['2023-01-01', '2023-01-02', '2023-01-03']
  14. }
  15. df2 = pd.DataFrame(data2)
  16. # 使用ExcelWriter将多个DataFrame写入同一个Excel文件
  17. with pd.ExcelWriter('产品与订单.xlsx', engine='openpyxl') as writer:
  18.     df1.to_excel(writer, sheet_name='产品信息', index=False)
  19.     df2.to_excel(writer, sheet_name='订单信息', index=False)
复制代码

设置单元格样式

使用openpyxl引擎,我们可以对Excel文件进行更精细的样式设置:
  1. import pandas as pd
  2. from openpyxl import load_workbook
  3. from openpyxl.styles import Font, PatternFill, Alignment
  4. # 创建DataFrame
  5. data = {
  6.     '学生姓名': ['张三', '李四', '王五', '赵六'],
  7.     '语文': [85, 92, 78, 88],
  8.     '数学': [90, 88, 85, 92],
  9.     '英语': [78, 85, 90, 80]
  10. }
  11. df = pd.DataFrame(data)
  12. # 先导出到Excel
  13. df.to_excel('学生成绩.xlsx', index=False)
  14. # 然后使用openpyxl加载并修改样式
  15. book = load_workbook('学生成绩.xlsx')
  16. sheet = book.active
  17. # 设置标题行样式
  18. header_font = Font(name='Arial', bold=True, color='FFFFFF')
  19. header_fill = PatternFill(start_color='4F81BD', end_color='4F81BD', fill_type='solid')
  20. header_alignment = Alignment(horizontal='center', vertical='center')
  21. for cell in sheet[1]:  # 第一行是标题
  22.     cell.font = header_font
  23.     cell.fill = header_fill
  24.     cell.alignment = header_alignment
  25. # 设置数据行样式
  26. data_font = Font(name='Arial')
  27. data_alignment = Alignment(horizontal='center', vertical='center')
  28. for row in sheet.iter_rows(min_row=2):  # 从第二行开始是数据
  29.     for cell in row:
  30.         cell.font = data_font
  31.         cell.alignment = data_alignment
  32. # 调整列宽
  33. sheet.column_dimensions['A'].width = 12  # 学生姓名列
  34. for col in ['B', 'C', 'D']:  # 成绩列
  35.     sheet.column_dimensions[col].width = 10
  36. # 保存修改
  37. book.save('学生成绩_样式化.xlsx')
复制代码

处理日期时间格式

在处理日期时间数据时,我们需要特别注意格式:
  1. import pandas as pd
  2. from datetime import datetime, timedelta
  3. # 创建包含日期的DataFrame
  4. data = {
  5.     '事件': ['项目启动', '第一阶段完成', '中期评审', '项目完成'],
  6.     '开始日期': [
  7.         datetime(2023, 1, 1),
  8.         datetime(2023, 2, 15),
  9.         datetime(2023, 4, 1),
  10.         datetime(2023, 6, 30)
  11.     ],
  12.     '持续天数': [45, 30, 15, 0]
  13. }
  14. df = pd.DataFrame(data)
  15. # 导出到Excel,并设置日期格式
  16. with pd.ExcelWriter('项目时间表.xlsx', engine='xlsxwriter', datetime_format='yyyy-mm-dd') as writer:
  17.     df.to_excel(writer, sheet_name='项目进度', index=False)
  18.    
  19.     # 获取xlsxwriter对象
  20.     workbook = writer.book
  21.     worksheet = writer.sheets['项目进度']
  22.    
  23.     # 设置列宽
  24.     worksheet.set_column('A:A', 15)  # 事件列
  25.     worksheet.set_column('B:B', 12)  # 开始日期列
  26.     worksheet.set_column('C:C', 10)  # 持续天数列
复制代码

高级应用

添加条件格式

条件格式可以帮助我们突出显示满足特定条件的数据:
  1. import pandas as pd
  2. # 创建销售数据DataFrame
  3. data = {
  4.     '销售员': ['张三', '李四', '王五', '赵六', '钱七'],
  5.     '一月': [12000, 15000, 9000, 18000, 11000],
  6.     '二月': [13000, 14000, 9500, 17000, 12000],
  7.     '三月': [12500, 16000, 10000, 17500, 11500]
  8. }
  9. df = pd.DataFrame(data)
  10. # 计算季度总额
  11. df['季度总额'] = df[['一月', '二月', '三月']].sum(axis=1)
  12. # 导出到Excel并添加条件格式
  13. with pd.ExcelWriter('销售数据_条件格式.xlsx', engine='xlsxwriter') as writer:
  14.     df.to_excel(writer, sheet_name='销售数据', index=False)
  15.    
  16.     # 获取xlsxwriter对象
  17.     workbook = writer.book
  18.     worksheet = writer.sheets['销售数据']
  19.    
  20.     # 添加条件格式:销售额大于15000的单元格背景设为绿色
  21.     green_format = workbook.add_format({'bg_color': '#C6EFCE', 'font_color': '#006100'})
  22.    
  23.     # 为每个月的数据列添加条件格式
  24.     for col in range(2, 5):  # B, C, D列
  25.         worksheet.conditional_format(
  26.             1, col, len(df), col,  # 从第2行到最后一行
  27.             {'type': 'cell', 'criteria': '>', 'value': 15000, 'format': green_format}
  28.         )
  29.    
  30.     # 添加条件格式:季度总额最高的行设为蓝色
  31.     blue_format = workbook.add_format({'bg_color': '#DBEEF4', 'font_color': '#0066CC'})
  32.    
  33.     # 找出季度总额最高的行索引
  34.     max_index = df['季度总额'].idxmax()
  35.    
  36.     # 为该行添加蓝色背景
  37.     for col in range(1, len(df.columns) + 1):  # 所有列
  38.         worksheet.conditional_format(
  39.             max_index + 1, col - 1, max_index + 1, col - 1,  # 特定行
  40.             {'type': 'formula', 'criteria': 'TRUE', 'format': blue_format}
  41.         )
复制代码

创建图表

Excel中的图表是数据可视化的重要工具,我们可以使用xlsxwriter创建各种图表:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建销售数据
  4. np.random.seed(42)
  5. months = ['一月', '二月', '三月', '四月', '五月', '六月']
  6. products = ['产品A', '产品B', '产品C', '产品D']
  7. data = {
  8.     '月份': months * 4,
  9.     '产品': np.repeat(products, 6),
  10.     '销售额': np.random.randint(5000, 20000, 24)
  11. }
  12. df = pd.DataFrame(data)
  13. # 透视表数据,便于图表展示
  14. pivot_df = df.pivot(index='月份', columns='产品', values='销售额')
  15. # 导出到Excel并创建图表
  16. with pd.ExcelWriter('销售数据_图表.xlsx', engine='xlsxwriter') as writer:
  17.     pivot_df.to_excel(writer, sheet_name='销售数据')
  18.    
  19.     # 获取xlsxwriter对象
  20.     workbook = writer.book
  21.     worksheet = writer.sheets['销售数据']
  22.    
  23.     # 创建图表对象
  24.     chart = workbook.add_chart({'type': 'column'})
  25.    
  26.     # 配置图表数据系列
  27.     for i, product in enumerate(products):
  28.         chart.add_series({
  29.             'name':       ['销售数据', 0, i + 1],  # 系列名称
  30.             'categories': ['销售数据', 1, 0, len(months), 0],  # X轴标签
  31.             'values':     ['销售数据', 1, i + 1, len(months), i + 1],  # Y轴值
  32.             'fill':       {'color': ['#4472C4', '#ED7D31', '#A5A5A5', '#FFC000'][i]},  # 柱状图颜色
  33.         })
  34.    
  35.     # 添加图表标题和轴标签
  36.     chart.set_title({'name': '月度产品销售额'})
  37.     chart.set_x_axis({'name': '月份'})
  38.     chart.set_y_axis({'name': '销售额'})
  39.    
  40.     # 将图表插入工作表
  41.     worksheet.insert_chart('G2', chart)
  42.    
  43.     # 创建第二个图表:饼图
  44.     pie_chart = workbook.add_chart({'type': 'pie'})
  45.    
  46.     # 计算各产品总销售额
  47.     total_sales = df.groupby('产品')['销售额'].sum().reset_index()
  48.    
  49.     # 添加饼图数据系列
  50.     pie_chart.add_series({
  51.         'name': '产品销售额占比',
  52.         'categories': [f'销售数据', len(months) + 2, 1, len(months) + 2 + len(products) - 1, 1],
  53.         'values': [f'销售数据', len(months) + 2, 2, len(months) + 2 + len(products) - 1, 2],
  54.         'data_labels': {'percentage': True},
  55.     })
  56.    
  57.     # 设置饼图标题
  58.     pie_chart.set_title({'name': '产品销售额占比'})
  59.    
  60.     # 将饼图插入工作表
  61.     worksheet.insert_chart('G20', pie_chart)
复制代码

添加数据验证

数据验证可以帮助确保输入数据的准确性:
  1. import pandas as pd
  2. # 创建一个简单的员工信息表
  3. data = {
  4.     '员工ID': ['E001', 'E002', 'E003', 'E004'],
  5.     '姓名': ['张三', '李四', '王五', '赵六'],
  6.     '部门': ['技术部', '市场部', '财务部', '技术部'],
  7.     '职级': ['P3', 'P2', 'P4', 'P3'],
  8.     '入职日期': ['2020-01-15', '2019-05-20', '2021-03-10', '2022-06-01']
  9. }
  10. df = pd.DataFrame(data)
  11. # 导出到Excel并添加数据验证
  12. with pd.ExcelWriter('员工信息_数据验证.xlsx', engine='xlsxwriter') as writer:
  13.     df.to_excel(writer, sheet_name='员工信息', index=False)
  14.    
  15.     # 获取xlsxwriter对象
  16.     workbook = writer.book
  17.     worksheet = writer.sheets['员工信息']
  18.    
  19.     # 添加部门下拉列表验证
  20.     department_list = ['技术部', '市场部', '财务部', '人力资源部', '运营部']
  21.     worksheet.data_validation(
  22.         'C2:C100',  # 应用验证的单元格范围
  23.         {
  24.             'validate': 'list',
  25.             'source': department_list,
  26.             'input_title': '选择部门:',
  27.             'input_message': '请从下拉列表中选择部门',
  28.         }
  29.     )
  30.    
  31.     # 添加职级下拉列表验证
  32.     level_list = ['P1', 'P2', 'P3', 'P4', 'P5', 'M1', 'M2', 'M3']
  33.     worksheet.data_validation(
  34.         'D2:D100',  # 应用验证的单元格范围
  35.         {
  36.             'validate': 'list',
  37.             'source': level_list,
  38.             'input_title': '选择职级:',
  39.             'input_message': '请从下拉列表中选择职级',
  40.         }
  41.     )
  42.    
  43.     # 添加入职日期验证(不能晚于今天)
  44.     worksheet.data_validation(
  45.         'E2:E100',  # 应用验证的单元格范围
  46.         {
  47.             'validate': 'date',
  48.             'criteria': 'less than or equal to',
  49.             'value': '=TODAY()',
  50.             'input_title': '入职日期:',
  51.             'input_message': '请输入有效的入职日期(不能晚于今天)',
  52.             'error_title': '输入错误',
  53.             'error_message': '入职日期不能晚于今天'
  54.         }
  55.     )
复制代码

添加公式

我们可以在Excel中添加公式,使数据更加动态和有用:
  1. import pandas as pd
  2. # 创建销售数据
  3. data = {
  4.     '产品': ['产品A', '产品B', '产品C', '产品D'],
  5.     '单价': [100, 150, 200, 120],
  6.     '数量': [50, 30, 25, 40],
  7.     '折扣率': [0.9, 0.85, 0.95, 0.88]
  8. }
  9. df = pd.DataFrame(data)
  10. # 导出到Excel并添加公式
  11. with pd.ExcelWriter('销售数据_公式.xlsx', engine='xlsxwriter') as writer:
  12.     df.to_excel(writer, sheet_name='销售数据', index=False)
  13.    
  14.     # 获取xlsxwriter对象
  15.     workbook = writer.book
  16.     worksheet = writer.sheets['销售数据']
  17.    
  18.     # 添加表头
  19.     worksheet.write(0, 4, '折扣后单价')  # E列
  20.     worksheet.write(0, 5, '小计')  # F列
  21.     worksheet.write(0, 6, '税率')  # G列
  22.     worksheet.write(0, 7, '税额')  # H列
  23.     worksheet.write(0, 8, '总计')  # I列
  24.    
  25.     # 设置税率(所有行相同)
  26.     tax_rate = 0.13
  27.     for row in range(1, len(df) + 1):
  28.         worksheet.write(row, 6, tax_rate)  # 税率列
  29.    
  30.     # 添加公式
  31.     for row in range(1, len(df) + 1):
  32.         # 折扣后单价 = 单价 * 折扣率
  33.         worksheet.write_formula(
  34.             row, 4,  # E列
  35.             f'=B{row+1}*D{row+1}',
  36.             value=df['单价'][row-1] * df['折扣率'][row-1]  # 计算值,用于Excel在未打开时显示
  37.         )
  38.         
  39.         # 小计 = 折扣后单价 * 数量
  40.         worksheet.write_formula(
  41.             row, 5,  # F列
  42.             f'=E{row+1}*C{row+1}',
  43.             value=(df['单价'][row-1] * df['折扣率'][row-1]) * df['数量'][row-1]
  44.         )
  45.         
  46.         # 税额 = 小计 * 税率
  47.         worksheet.write_formula(
  48.             row, 7,  # H列
  49.             f'=F{row+1}*G{row+1}',
  50.             value=((df['单价'][row-1] * df['折扣率'][row-1]) * df['数量'][row-1]) * tax_rate
  51.         )
  52.         
  53.         # 总计 = 小计 + 税额
  54.         worksheet.write_formula(
  55.             row, 8,  # I列
  56.             f'=F{row+1}+H{row+1}',
  57.             value=((df['单价'][row-1] * df['折扣率'][row-1]) * df['数量'][row-1]) +
  58.                   ((df['单价'][row-1] * df['折扣率'][row-1]) * df['数量'][row-1]) * tax_rate
  59.         )
  60.    
  61.     # 添加总计行
  62.     total_row = len(df) + 1
  63.     worksheet.write(total_row, 0, '总计')
  64.    
  65.     # 添加总计公式
  66.     for col in [2, 4, 5, 7, 8]:  # 数量、折扣后单价、小计、税额、总计列
  67.         col_letter = chr(65 + col)  # A=65, B=66, ...
  68.         worksheet.write_formula(
  69.             total_row, col,
  70.             f'=SUM({col_letter}2:{col_letter}{len(df)})'
  71.         )
  72.    
  73.     # 添加平均单价行
  74.     avg_row = len(df) + 2
  75.     worksheet.write(avg_row, 0, '平均单价')
  76.     worksheet.write_formula(
  77.         avg_row, 1,  # B列(单价列)
  78.         f'=AVERAGE(B2:B{len(df)})'
  79.     )
复制代码

性能优化

处理大数据量

当处理大量数据时,直接导出到Excel可能会遇到内存问题。以下是几种优化方法:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建大型DataFrame(100万行)
  4. np.random.seed(42)
  5. large_df = pd.DataFrame({
  6.     'ID': range(1, 1000001),
  7.     '值1': np.random.rand(1000000),
  8.     '值2': np.random.randn(1000000),
  9.     '类别': np.random.choice(['A', 'B', 'C', 'D'], 1000000)
  10. })
  11. # 方法1:分块写入
  12. def chunked_export(df, file_path, chunk_size=100000):
  13.     """
  14.     将大型DataFrame分块写入Excel文件
  15.    
  16.     参数:
  17.         df: 要导出的DataFrame
  18.         file_path: 输出文件路径
  19.         chunk_size: 每块的行数
  20.     """
  21.     writer = pd.ExcelWriter(file_path, engine='openpyxl')
  22.    
  23.     # 写入第一块(包含表头)
  24.     df.iloc[:chunk_size].to_excel(writer, sheet_name='大数据', index=False)
  25.    
  26.     # 追加剩余块
  27.     for i in range(chunk_size, len(df), chunk_size):
  28.         df.iloc[i:i+chunk_size].to_excel(
  29.             writer,
  30.             sheet_name='大数据',
  31.             index=False,
  32.             startrow=i+1,  # +1 因为表头占了一行
  33.             header=False   # 不包含表头
  34.         )
  35.    
  36.     writer.save()
  37. # 使用分块方法导出大型DataFrame
  38. chunked_export(large_df, '大型数据_分块.xlsx')
  39. # 方法2:使用csv格式作为中间格式(对于非常大的数据集)
  40. # 首先导出到CSV
  41. large_df.to_csv('大型数据_中间.csv', index=False)
  42. # 然后使用Excel的数据导入功能(这里用代码模拟)
  43. # 在实际应用中,可以手动在Excel中导入CSV文件,或者使用其他库如pyxlsb处理二进制Excel格式
  44. # 方法3:只导出必要的数据
  45. # 如果只需要部分数据,可以先筛选再导出
  46. filtered_df = large_df[large_df['类别'].isin(['A', 'B'])]  # 只导出类别为A和B的数据
  47. filtered_df.to_excel('大型数据_筛选.xlsx', index=False)
复制代码

优化内存使用

在处理大型数据集时,优化内存使用非常重要:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建大型DataFrame
  4. np.random.seed(42)
  5. large_df = pd.DataFrame({
  6.     'ID': range(1, 1000001),
  7.     '值1': np.random.rand(1000000),
  8.     '值2': np.random.randn(1000000),
  9.     '类别': np.random.choice(['A', 'B', 'C', 'D'], 1000000),
  10.     '日期': pd.date_range('2020-01-01', periods=1000000, freq='D')
  11. })
  12. # 优化数据类型以减少内存使用
  13. def optimize_memory(df):
  14.     """
  15.     优化DataFrame的内存使用
  16.    
  17.     参数:
  18.         df: 要优化的DataFrame
  19.         
  20.     返回:
  21.         优化后的DataFrame
  22.     """
  23.     optimized_df = df.copy()
  24.    
  25.     for col in optimized_df.columns:
  26.         col_type = optimized_df[col].dtype
  27.         
  28.         if col_type == 'object':
  29.             # 对象类型转换为类别类型(如果唯一值较少)
  30.             num_unique_values = len(optimized_df[col].unique())
  31.             num_total_values = len(optimized_df[col])
  32.             if num_unique_values / num_total_values < 0.5:
  33.                 optimized_df[col] = optimized_df[col].astype('category')
  34.         
  35.         elif col_type == 'float64':
  36.             # 64位浮点数转换为32位浮点数
  37.             optimized_df[col] = pd.to_numeric(optimized_df[col], downcast='float')
  38.         
  39.         elif col_type == 'int64':
  40.             # 64位整数转换为更小的整数类型
  41.             optimized_df[col] = pd.to_numeric(optimized_df[col], downcast='integer')
  42.    
  43.     return optimized_df
  44. # 优化DataFrame
  45. optimized_df = optimize_memory(large_df)
  46. # 比较内存使用
  47. print(f"原始DataFrame内存使用: {large_df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
  48. print(f"优化后DataFrame内存使用: {optimized_df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
  49. # 导出优化后的DataFrame
  50. optimized_df.to_excel('大型数据_内存优化.xlsx', index=False)
复制代码

实际案例

案例1:销售报告自动化

假设我们需要每月生成销售报告,包含数据汇总、图表和格式化输出:
  1. import pandas as pd
  2. import numpy as np
  3. from datetime import datetime, timedelta
  4. # 模拟销售数据
  5. np.random.seed(42)
  6. date_range = pd.date_range('2023-01-01', '2023-06-30')
  7. products = ['产品A', '产品B', '产品C', '产品D']
  8. regions = ['华北', '华东', '华南', '华中', '西北', '西南', '东北']
  9. # 生成随机销售数据
  10. sales_data = []
  11. for _ in range(5000):  # 5000条销售记录
  12.     sales_data.append({
  13.         '日期': np.random.choice(date_range),
  14.         '产品': np.random.choice(products),
  15.         '地区': np.random.choice(regions),
  16.         '销售额': np.random.randint(1000, 50000),
  17.         '数量': np.random.randint(1, 100)
  18.     })
  19. sales_df = pd.DataFrame(sales_data)
  20. # 创建报告函数
  21. def create_sales_report(df, report_month, output_file):
  22.     """
  23.     创建月度销售报告
  24.    
  25.     参数:
  26.         df: 包含销售数据的DataFrame
  27.         report_month: 报告月份,格式为'YYYY-MM'
  28.         output_file: 输出文件路径
  29.     """
  30.     # 筛选指定月份的数据
  31.     df['月份'] = df['日期'].dt.strftime('%Y-%m')
  32.     month_df = df[df['月份'] == report_month].copy()
  33.    
  34.     if month_df.empty:
  35.         print(f"没有找到{report_month}的销售数据")
  36.         return
  37.    
  38.     # 计算各种汇总数据
  39.     product_sales = month_df.groupby('产品')['销售额'].sum().reset_index()
  40.     region_sales = month_df.groupby('地区')['销售额'].sum().reset_index()
  41.     daily_sales = month_df.groupby('日期')['销售额'].sum().reset_index()
  42.    
  43.     # 创建Excel写入器
  44.     with pd.ExcelWriter(output_file, engine='xlsxwriter', datetime_format='yyyy-mm-dd') as writer:
  45.         # 写入原始数据
  46.         month_df.to_excel(writer, sheet_name='原始数据', index=False)
  47.         
  48.         # 写入产品销售汇总
  49.         product_sales.to_excel(writer, sheet_name='产品销售汇总', index=False)
  50.         
  51.         # 写入地区销售汇总
  52.         region_sales.to_excel(writer, sheet_name='地区销售汇总', index=False)
  53.         
  54.         # 写入每日销售趋势
  55.         daily_sales.to_excel(writer, sheet_name='每日销售趋势', index=False)
  56.         
  57.         # 获取xlsxwriter对象
  58.         workbook = writer.book
  59.         worksheet = writer.sheets['产品销售汇总']
  60.         
  61.         # 创建产品销售饼图
  62.         pie_chart = workbook.add_chart({'type': 'pie'})
  63.         
  64.         pie_chart.add_series({
  65.             'name': '产品销售占比',
  66.             'categories': ['产品销售汇总', 1, 0, len(product_sales), 0],
  67.             'values': ['产品销售汇总', 1, 1, len(product_sales), 1],
  68.             'data_labels': {'percentage': True, 'category': True},
  69.         })
  70.         
  71.         pie_chart.set_title({'name': f'{report_month} 产品销售占比'})
  72.         worksheet.insert_chart('D2', pie_chart)
  73.         
  74.         # 创建地区销售条形图
  75.         bar_chart = workbook.add_chart({'type': 'bar'})
  76.         
  77.         bar_chart.add_series({
  78.             'name': '地区销售额',
  79.             'categories': ['地区销售汇总', 1, 0, len(region_sales), 0],
  80.             'values': ['地区销售汇总', 1, 1, len(region_sales), 1],
  81.         })
  82.         
  83.         bar_chart.set_title({'name': f'{report_month} 地区销售额'})
  84.         bar_chart.set_x_axis({'name': '销售额'})
  85.         worksheet = writer.sheets['地区销售汇总']
  86.         worksheet.insert_chart('D2', bar_chart)
  87.         
  88.         # 创建每日销售折线图
  89.         line_chart = workbook.add_chart({'type': 'line'})
  90.         
  91.         line_chart.add_series({
  92.             'name': '每日销售额',
  93.             'categories': ['每日销售趋势', 1, 0, len(daily_sales), 0],
  94.             'values': ['每日销售趋势', 1, 1, len(daily_sales), 1],
  95.             'marker': {'type': 'circle', 'size': 4, 'border': {'color': 'black'}, 'fill': {'color': 'red'}},
  96.         })
  97.         
  98.         line_chart.set_title({'name': f'{report_month} 每日销售趋势'})
  99.         line_chart.set_x_axis({'name': '日期'})
  100.         line_chart.set_y_axis({'name': '销售额'})
  101.         worksheet = writer.sheets['每日销售趋势']
  102.         worksheet.insert_chart('D2', line_chart)
  103.         
  104.         # 创建汇总报告工作表
  105.         summary_sheet = workbook.add_worksheet('汇总报告')
  106.         
  107.         # 添加报告标题
  108.         title_format = workbook.add_format({
  109.             'bold': True,
  110.             'font_size': 16,
  111.             'align': 'center',
  112.             'valign': 'vcenter'
  113.         })
  114.         summary_sheet.merge_range('A1:D1', f'{report_month} 销售报告', title_format)
  115.         
  116.         # 添加关键指标
  117.         metrics = [
  118.             ['总销售额', month_df['销售额'].sum()],
  119.             ['平均单笔销售额', month_df['销售额'].mean()],
  120.             ['销售记录数', len(month_df)],
  121.             ['销售产品数', month_df['产品'].nunique()],
  122.             ['覆盖地区数', month_df['地区'].nunique()],
  123.             ['最高单日销售额', daily_sales['销售额'].max()],
  124.             ['最低单日销售额', daily_sales['销售额'].min()]
  125.         ]
  126.         
  127.         # 写入指标
  128.         header_format = workbook.add_format({
  129.             'bold': True,
  130.             'bg_color': '#4F81BD',
  131.             'font_color': 'white',
  132.             'border': 1
  133.         })
  134.         
  135.         cell_format = workbook.add_format({
  136.             'border': 1,
  137.             'num_format': '#,##0.00'
  138.         })
  139.         
  140.         summary_sheet.write(3, 0, '关键指标', header_format)
  141.         summary_sheet.write(3, 1, '数值', header_format)
  142.         
  143.         for i, (metric, value) in enumerate(metrics):
  144.             summary_sheet.write(4 + i, 0, metric, cell_format)
  145.             summary_sheet.write(4 + i, 1, value, cell_format)
  146.         
  147.         # 设置列宽
  148.         summary_sheet.set_column('A:A', 20)
  149.         summary_sheet.set_column('B:B', 15)
  150. # 创建2023年6月的销售报告
  151. create_sales_report(sales_df, '2023-06', '2023年6月销售报告.xlsx')
复制代码

案例2:财务数据导出与分析

在财务工作中,经常需要将数据导出到Excel并进行进一步分析:
  1. import pandas as pd
  2. import numpy as np
  3. from datetime import datetime, timedelta
  4. # 模拟财务数据
  5. np.random.seed(42)
  6. date_range = pd.date_range('2023-01-01', '2023-06-30')
  7. accounts = ['现金', '应收账款', '存货', '固定资产', '应付账款', '短期借款', '长期借款', '实收资本', '未分配利润']
  8. departments = ['销售部', '市场部', '研发部', '行政部', '财务部']
  9. # 生成随机财务数据
  10. financial_data = []
  11. for date in date_range:
  12.     for account in accounts:
  13.         financial_data.append({
  14.             '日期': date,
  15.             '科目': account,
  16.             '借方金额': np.random.uniform(0, 100000) if np.random.random() > 0.5 else 0,
  17.             '贷方金额': np.random.uniform(0, 100000) if np.random.random() > 0.5 else 0,
  18.             '部门': np.random.choice(departments),
  19.             '备注': np.random.choice(['日常业务', '特殊业务', '调整业务', '期末处理'])
  20.         })
  21. financial_df = pd.DataFrame(financial_data)
  22. # 创建财务分析报告
  23. def create_financial_report(df, start_date, end_date, output_file):
  24.     """
  25.     创建财务分析报告
  26.    
  27.     参数:
  28.         df: 包含财务数据的DataFrame
  29.         start_date: 开始日期,格式为'YYYY-MM-DD'
  30.         end_date: 结束日期,格式为'YYYY-MM-DD'
  31.         output_file: 输出文件路径
  32.     """
  33.     # 筛选日期范围
  34.     mask = (df['日期'] >= start_date) & (df['日期'] <= end_date)
  35.     period_df = df.loc[mask].copy()
  36.    
  37.     if period_df.empty:
  38.         print(f"没有找到{start_date}至{end_date}的财务数据")
  39.         return
  40.    
  41.     # 计算科目余额
  42.     balance_df = period_df.groupby('科目').agg({
  43.         '借方金额': 'sum',
  44.         '贷方金额': 'sum'
  45.     }).reset_index()
  46.     balance_df['余额'] = balance_df['借方金额'] - balance_df['贷方金额']
  47.    
  48.     # 计算部门收支
  49.     dept_df = period_df.groupby('部门').agg({
  50.         '借方金额': 'sum',
  51.         '贷方金额': 'sum'
  52.     }).reset_index()
  53.     dept_df['净额'] = dept_df['贷方金额'] - dept_df['借方金额']
  54.    
  55.     # 计算每日收支
  56.     daily_df = period_df.groupby('日期').agg({
  57.         '借方金额': 'sum',
  58.         '贷方金额': 'sum'
  59.     }).reset_index()
  60.     daily_df['净额'] = daily_df['贷方金额'] - daily_df['借方金额']
  61.    
  62.     # 创建Excel写入器
  63.     with pd.ExcelWriter(output_file, engine='xlsxwriter', datetime_format='yyyy-mm-dd') as writer:
  64.         # 写入原始数据
  65.         period_df.to_excel(writer, sheet_name='原始数据', index=False)
  66.         
  67.         # 写入科目余额
  68.         balance_df.to_excel(writer, sheet_name='科目余额', index=False)
  69.         
  70.         # 写入部门收支
  71.         dept_df.to_excel(writer, sheet_name='部门收支', index=False)
  72.         
  73.         # 写入每日收支
  74.         daily_df.to_excel(writer, sheet_name='每日收支', index=False)
  75.         
  76.         # 获取xlsxwriter对象
  77.         workbook = writer.book
  78.         
  79.         # 创建科目余额工作表格式
  80.         worksheet = writer.sheets['科目余额']
  81.         
  82.         # 添加条件格式:借方余额设为红色,贷方余额设为绿色
  83.         red_format = workbook.add_format({'bg_color': '#FFC7CE', 'font_color': '#9C0006'})
  84.         green_format = workbook.add_format({'bg_color': '#C6EFCE', 'font_color': '#006100'})
  85.         
  86.         # 为余额列添加条件格式
  87.         worksheet.conditional_format(
  88.             1, 3, len(balance_df), 3,  # 余额列
  89.             {'type': 'cell', 'criteria': '>', 'value': 0, 'format': red_format}
  90.         )
  91.         worksheet.conditional_format(
  92.             1, 3, len(balance_df), 3,  # 余额列
  93.             {'type': 'cell', 'criteria': '<', 'value': 0, 'format': green_format}
  94.         )
  95.         
  96.         # 创建部门收支条形图
  97.         bar_chart = workbook.add_chart({'type': 'column'})
  98.         
  99.         bar_chart.add_series({
  100.             'name': '支出',
  101.             'categories': ['部门收支', 1, 0, len(dept_df), 0],
  102.             'values': ['部门收支', 1, 1, len(dept_df), 1],
  103.             'fill': {'color': '#FF0000'},
  104.         })
  105.         
  106.         bar_chart.add_series({
  107.             'name': '收入',
  108.             'categories': ['部门收支', 1, 0, len(dept_df), 0],
  109.             'values': ['部门收支', 1, 2, len(dept_df), 2],
  110.             'fill': {'color': '#00FF00'},
  111.         })
  112.         
  113.         bar_chart.set_title({'name': f'{start_date} 至 {end_date} 部门收支对比'})
  114.         bar_chart.set_x_axis({'name': '部门'})
  115.         bar_chart.set_y_axis({'name': '金额'})
  116.         
  117.         worksheet = writer.sheets['部门收支']
  118.         worksheet.insert_chart('F2', bar_chart)
  119.         
  120.         # 创建每日收支折线图
  121.         line_chart = workbook.add_chart({'type': 'line'})
  122.         
  123.         line_chart.add_series({
  124.             'name': '支出',
  125.             'categories': ['每日收支', 1, 0, len(daily_df), 0],
  126.             'values': ['每日收支', 1, 1, len(daily_df), 1],
  127.             'line': {'color': '#FF0000'},
  128.             'marker': {'type': 'circle', 'size': 4, 'border': {'color': 'black'}, 'fill': {'color': 'red'}},
  129.         })
  130.         
  131.         line_chart.add_series({
  132.             'name': '收入',
  133.             'categories': ['每日收支', 1, 0, len(daily_df), 0],
  134.             'values': ['每日收支', 1, 2, len(daily_df), 2],
  135.             'line': {'color': '#00FF00'},
  136.             'marker': {'type': 'square', 'size': 4, 'border': {'color': 'black'}, 'fill': {'color': 'green'}},
  137.         })
  138.         
  139.         line_chart.add_series({
  140.             'name': '净额',
  141.             'categories': ['每日收支', 1, 0, len(daily_df), 0],
  142.             'values': ['每日收支', 1, 3, len(daily_df), 3],
  143.             'line': {'color': '#0000FF'},
  144.             'marker': {'type': 'triangle', 'size': 4, 'border': {'color': 'black'}, 'fill': {'color': 'blue'}},
  145.         })
  146.         
  147.         line_chart.set_title({'name': f'{start_date} 至 {end_date} 每日收支趋势'})
  148.         line_chart.set_x_axis({'name': '日期'})
  149.         line_chart.set_y_axis({'name': '金额'})
  150.         
  151.         worksheet = writer.sheets['每日收支']
  152.         worksheet.insert_chart('F2', line_chart)
  153.         
  154.         # 创建财务汇总工作表
  155.         summary_sheet = workbook.add_worksheet('财务汇总')
  156.         
  157.         # 添加报告标题
  158.         title_format = workbook.add_format({
  159.             'bold': True,
  160.             'font_size': 16,
  161.             'align': 'center',
  162.             'valign': 'vcenter'
  163.         })
  164.         summary_sheet.merge_range('A1:D1', f'{start_date} 至 {end_date} 财务汇总', title_format)
  165.         
  166.         # 添加财务指标
  167.         metrics = [
  168.             ['总收入', period_df['贷方金额'].sum()],
  169.             ['总支出', period_df['借方金额'].sum()],
  170.             ['净收支', period_df['贷方金额'].sum() - period_df['借方金额'].sum()],
  171.             ['平均每日收入', daily_df['贷方金额'].mean()],
  172.             ['平均每日支出', daily_df['借方金额'].mean()],
  173.             ['最高单日收入', daily_df['贷方金额'].max()],
  174.             ['最高单日支出', daily_df['借方金额'].max()],
  175.             ['交易笔数', len(period_df)]
  176.         ]
  177.         
  178.         # 写入指标
  179.         header_format = workbook.add_format({
  180.             'bold': True,
  181.             'bg_color': '#4F81BD',
  182.             'font_color': 'white',
  183.             'border': 1
  184.         })
  185.         
  186.         cell_format = workbook.add_format({
  187.             'border': 1,
  188.             'num_format': '#,##0.00'
  189.         })
  190.         
  191.         summary_sheet.write(3, 0, '财务指标', header_format)
  192.         summary_sheet.write(3, 1, '数值', header_format)
  193.         
  194.         for i, (metric, value) in enumerate(metrics):
  195.             summary_sheet.write(4 + i, 0, metric, cell_format)
  196.             summary_sheet.write(4 + i, 1, value, cell_format)
  197.         
  198.         # 设置列宽
  199.         summary_sheet.set_column('A:A', 20)
  200.         summary_sheet.set_column('B:B', 15)
  201.         
  202.         # 添加科目余额明细
  203.         summary_sheet.write(3, 3, '科目余额明细', header_format)
  204.         summary_sheet.write(4, 3, '科目', header_format)
  205.         summary_sheet.write(4, 4, '余额', header_format)
  206.         
  207.         for i, (_, row) in enumerate(balance_df.iterrows()):
  208.             summary_sheet.write(5 + i, 3, row['科目'], cell_format)
  209.             summary_sheet.write(5 + i, 4, row['余额'], cell_format)
  210.         
  211.         summary_sheet.set_column('D:D', 15)
  212.         summary_sheet.set_column('E:E', 15)
  213. # 创建2023年第二季度的财务报告
  214. create_financial_report(financial_df, '2023-04-01', '2023-06-30', '2023年Q2财务报告.xlsx')
复制代码

常见问题与解决方案

问题1:导出的Excel文件打不开或损坏

原因:可能是由于数据量过大、格式不兼容或写入过程中出错导致的。

解决方案:
  1. import pandas as pd
  2. # 创建一个简单的DataFrame
  3. data = {
  4.     '姓名': ['张三', '李四', '王五'],
  5.     '年龄': [25, 30, 35],
  6.     '城市': ['北京', '上海', '广州']
  7. }
  8. df = pd.DataFrame(data)
  9. # 方法1:使用不同的引擎
  10. try:
  11.     # 尝试使用openpyxl引擎
  12.     df.to_excel('测试_openpyxl.xlsx', index=False, engine='openpyxl')
  13.     print("使用openpyxl引擎导出成功")
  14. except Exception as e:
  15.     print(f"openpyxl引擎导出失败: {e}")
  16.    
  17.     try:
  18.         # 尝试使用xlsxwriter引擎
  19.         df.to_excel('测试_xlsxwriter.xlsx', index=False, engine='xlsxwriter')
  20.         print("使用xlsxwriter引擎导出成功")
  21.     except Exception as e2:
  22.         print(f"xlsxwriter引擎导出失败: {e2}")
  23. # 方法2:分块写入大数据
  24. def safe_export_large_data(df, file_path, chunk_size=10000):
  25.     """
  26.     安全地导出大型DataFrame到Excel
  27.    
  28.     参数:
  29.         df: 要导出的DataFrame
  30.         file_path: 输出文件路径
  31.         chunk_size: 每块的行数
  32.     """
  33.     try:
  34.         if len(df) <= chunk_size:
  35.             # 如果数据量小,直接导出
  36.             df.to_excel(file_path, index=False)
  37.         else:
  38.             # 如果数据量大,分块导出
  39.             writer = pd.ExcelWriter(file_path, engine='openpyxl')
  40.             
  41.             # 写入第一块(包含表头)
  42.             df.iloc[:chunk_size].to_excel(writer, sheet_name='数据', index=False)
  43.             
  44.             # 追加剩余块
  45.             for i in range(chunk_size, len(df), chunk_size):
  46.                 df.iloc[i:i+chunk_size].to_excel(
  47.                     writer,
  48.                     sheet_name='数据',
  49.                     index=False,
  50.                     startrow=i+1,  # +1 因为表头占了一行
  51.                     header=False   # 不包含表头
  52.                 )
  53.             
  54.             writer.close()
  55.         
  56.         print(f"数据成功导出到 {file_path}")
  57.     except Exception as e:
  58.         print(f"导出失败: {e}")
  59.         
  60.         # 尝试使用CSV格式作为备选方案
  61.         csv_path = file_path.replace('.xlsx', '.csv')
  62.         try:
  63.             df.to_csv(csv_path, index=False, encoding='utf-8-sig')
  64.             print(f"已使用CSV格式导出到 {csv_path}")
  65.         except Exception as e2:
  66.             print(f"CSV导出也失败: {e2}")
  67. # 模拟大型DataFrame
  68. import numpy as np
  69. large_df = pd.DataFrame({
  70.     'ID': range(1, 100001),
  71.     '值': np.random.rand(100000)
  72. })
  73. # 使用安全导出方法
  74. safe_export_large_data(large_df, '大型数据_安全导出.xlsx')
复制代码

问题2:日期时间格式不正确

原因:Excel和Python对日期时间的处理方式不同,可能导致格式显示不正确。

解决方案:
  1. import pandas as pd
  2. from datetime import datetime
  3. # 创建包含日期的DataFrame
  4. data = {
  5.     '事件': ['项目启动', '第一阶段完成', '中期评审', '项目完成'],
  6.     '日期': [
  7.         datetime(2023, 1, 1),
  8.         datetime(2023, 2, 15),
  9.         datetime(2023, 4, 1),
  10.         datetime(2023, 6, 30)
  11.     ],
  12.     '时间': [
  13.         datetime(2023, 1, 1, 9, 30),
  14.         datetime(2023, 2, 15, 14, 45),
  15.         datetime(2023, 4, 1, 10, 15),
  16.         datetime(2023, 6, 30, 16, 0)
  17.     ]
  18. }
  19. df = pd.DataFrame(data)
  20. # 方法1:使用datetime_format参数
  21. with pd.ExcelWriter('日期时间_格式化1.xlsx', engine='xlsxwriter',
  22.                    datetime_format='yyyy-mm-dd') as writer:
  23.     df.to_excel(writer, sheet_name='项目时间表', index=False)
  24. # 方法2:分别设置日期和时间格式
  25. with pd.ExcelWriter('日期时间_格式化2.xlsx', engine='xlsxwriter') as writer:
  26.     df.to_excel(writer, sheet_name='项目时间表', index=False)
  27.    
  28.     # 获取xlsxwriter对象
  29.     workbook = writer.book
  30.     worksheet = writer.sheets['项目时间表']
  31.    
  32.     # 设置日期格式
  33.     date_format = workbook.add_format({'num_format': 'yyyy-mm-dd'})
  34.     time_format = workbook.add_format({'num_format': 'hh:mm:ss'})
  35.    
  36.     # 应用日期格式
  37.     for row in range(1, len(df) + 1):
  38.         worksheet.write_datetime(row, 2, df['日期'][row-1], date_format)
  39.         worksheet.write_datetime(row, 3, df['时间'][row-1], time_format)
  40. # 方法3:使用openpyxl设置格式
  41. df.to_excel('日期时间_格式化3.xlsx', index=False)
  42. from openpyxl import load_workbook
  43. from openpyxl.styles import numbers
  44. book = load_workbook('日期时间_格式化3.xlsx')
  45. sheet = book.active
  46. # 设置日期格式
  47. for row in range(2, len(df) + 2):  # +2 因为第一行是表头,索引从1开始
  48.     sheet.cell(row=row, column=3).number_format = 'YYYY-MM-DD'  # 日期列
  49.     sheet.cell(row=row, column=4).number_format = 'HH:MM:SS'  # 时间列
  50. book.save('日期时间_格式化3.xlsx')
复制代码

问题3:中文显示乱码

原因:编码问题可能导致中文字符在Excel中显示为乱码。

解决方案:
  1. import pandas as pd
  2. # 创建包含中文的DataFrame
  3. data = {
  4.     '姓名': ['张三', '李四', '王五', '赵六'],
  5.     '部门': ['技术部', '市场部', '财务部', '人力资源部'],
  6.     '备注': ['优秀员工', '表现良好', '需要改进', '新员工']
  7. }
  8. df = pd.DataFrame(data)
  9. # 方法1:使用utf-8-sig编码(适用于CSV)
  10. df.to_csv('中文数据.csv', index=False, encoding='utf-8-sig')
  11. # 方法2:使用openpyxl引擎(适用于xlsx)
  12. df.to_excel('中文数据_openpyxl.xlsx', index=False, engine='openpyxl')
  13. # 方法3:使用xlsxwriter引擎并设置字体
  14. with pd.ExcelWriter('中文数据_xlsxwriter.xlsx', engine='xlsxwriter') as writer:
  15.     df.to_excel(writer, sheet_name='员工信息', index=False)
  16.    
  17.     # 获取xlsxwriter对象
  18.     workbook = writer.book
  19.     worksheet = writer.sheets['员工信息']
  20.    
  21.     # 添加支持中文的字体格式
  22.     chinese_font = workbook.add_format({'font_name': 'Microsoft YaHei', 'font_size': 11})
  23.    
  24.     # 应用格式到所有单元格
  25.     for row in range(len(df) + 1):  # +1 包含表头
  26.         for col in range(len(df.columns)):
  27.             worksheet.write(row, col, df.iloc[row-1, col] if row > 0 else df.columns[col], chinese_font)
  28. # 方法4:使用openpyxl设置字体
  29. df.to_excel('中文数据_openpyxl_font.xlsx', index=False, engine='openpyxl')
  30. from openpyxl import load_workbook
  31. from openpyxl.styles import Font
  32. book = load_workbook('中文数据_openpyxl_font.xlsx')
  33. sheet = book.active
  34. # 设置支持中文的字体
  35. chinese_font = Font(name='Microsoft YaHei', size=11)
  36. # 应用字体到所有单元格
  37. for row in sheet.iter_rows():
  38.     for cell in row:
  39.         cell.font = chinese_font
  40. book.save('中文数据_openpyxl_font.xlsx')
复制代码

问题4:大数据量导出内存不足

原因:当处理大量数据时,可能会遇到内存不足的问题。

解决方案:
  1. import pandas as pd
  2. import numpy as np
  3. # 创建一个大型DataFrame(50万行)
  4. np.random.seed(42)
  5. large_df = pd.DataFrame({
  6.     'ID': range(1, 500001),
  7.     '值1': np.random.rand(500000),
  8.     '值2': np.random.randn(500000),
  9.     '类别': np.random.choice(['A', 'B', 'C', 'D'], 500000)
  10. })
  11. # 方法1:分块处理
  12. def export_large_data_in_chunks(df, file_path, chunk_size=50000):
  13.     """
  14.     分块导出大型DataFrame到Excel
  15.    
  16.     参数:
  17.         df: 要导出的DataFrame
  18.         file_path: 输出文件路径
  19.         chunk_size: 每块的行数
  20.     """
  21.     writer = pd.ExcelWriter(file_path, engine='openpyxl')
  22.    
  23.     # 写入第一块(包含表头)
  24.     df.iloc[:chunk_size].to_excel(writer, sheet_name='大数据', index=False)
  25.    
  26.     # 追加剩余块
  27.     for i in range(chunk_size, len(df), chunk_size):
  28.         df.iloc[i:i+chunk_size].to_excel(
  29.             writer,
  30.             sheet_name='大数据',
  31.             index=False,
  32.             startrow=i+1,  # +1 因为表头占了一行
  33.             header=False   # 不包含表头
  34.         )
  35.    
  36.     writer.close()
  37.     print(f"数据已分块导出到 {file_path}")
  38. # 使用分块方法导出
  39. export_large_data_in_chunks(large_df, '大型数据_分块导出.xlsx')
  40. # 方法2:使用CSV格式(对于非常大的数据集)
  41. def export_to_csv_with_compression(df, file_path, compression='gzip'):
  42.     """
  43.     导出DataFrame到压缩的CSV文件
  44.    
  45.     参数:
  46.         df: 要导出的DataFrame
  47.         file_path: 输出文件路径(不包括扩展名)
  48.         compression: 压缩类型,可以是'gzip', 'bz2', 'zip', 'xz'
  49.     """
  50.     compressed_path = f"{file_path}.{compression}"
  51.     df.to_csv(compressed_path, index=False, compression=compression)
  52.     print(f"数据已压缩导出到 {compressed_path}")
  53. # 使用压缩CSV方法导出
  54. export_to_csv_with_compression(large_df, '大型数据_压缩')
  55. # 方法3:优化内存使用后导出
  56. def optimize_and_export(df, file_path):
  57.     """
  58.     优化DataFrame内存使用后导出
  59.    
  60.     参数:
  61.         df: 要导出的DataFrame
  62.         file_path: 输出文件路径
  63.     """
  64.     # 优化数据类型
  65.     optimized_df = df.copy()
  66.    
  67.     for col in optimized_df.columns:
  68.         col_type = optimized_df[col].dtype
  69.         
  70.         if col_type == 'object':
  71.             # 对象类型转换为类别类型(如果唯一值较少)
  72.             num_unique_values = len(optimized_df[col].unique())
  73.             num_total_values = len(optimized_df[col])
  74.             if num_unique_values / num_total_values < 0.5:
  75.                 optimized_df[col] = optimized_df[col].astype('category')
  76.         
  77.         elif col_type == 'float64':
  78.             # 64位浮点数转换为32位浮点数
  79.             optimized_df[col] = pd.to_numeric(optimized_df[col], downcast='float')
  80.         
  81.         elif col_type == 'int64':
  82.             # 64位整数转换为更小的整数类型
  83.             optimized_df[col] = pd.to_numeric(optimized_df[col], downcast='integer')
  84.    
  85.     # 比较内存使用
  86.     original_memory = df.memory_usage(deep=True).sum() / 1024**2
  87.     optimized_memory = optimized_df.memory_usage(deep=True).sum() / 1024**2
  88.     print(f"原始DataFrame内存使用: {original_memory:.2f} MB")
  89.     print(f"优化后DataFrame内存使用: {optimized_memory:.2f} MB")
  90.     print(f"内存节省: {(1 - optimized_memory/original_memory)*100:.2f}%")
  91.    
  92.     # 导出优化后的DataFrame
  93.     optimized_df.to_excel(file_path, index=False)
  94.     print(f"优化后的数据已导出到 {file_path}")
  95. # 使用优化方法导出
  96. optimize_and_export(large_df, '大型数据_内存优化.xlsx')
  97. # 方法4:使用数据库作为中间存储
  98. def export_via_database(df, file_path, table_name='temp_data'):
  99.     """
  100.     通过SQLite数据库导出大型DataFrame到Excel
  101.    
  102.     参数:
  103.         df: 要导出的DataFrame
  104.         file_path: 输出文件路径
  105.         table_name: 临时数据库表名
  106.     """
  107.     import sqlite3
  108.     from sqlalchemy import create_engine
  109.    
  110.     # 创建SQLite数据库连接
  111.     engine = create_engine('sqlite:///temp_db.sqlite')
  112.    
  113.     # 将DataFrame写入数据库
  114.     df.to_sql(table_name, engine, index=False, if_exists='replace')
  115.    
  116.     # 分块从数据库读取并写入Excel
  117.     writer = pd.ExcelWriter(file_path, engine='openpyxl')
  118.    
  119.     # 第一次读取(包含表头)
  120.     chunk = pd.read_sql_table(table_name, engine, chunksize=50000)
  121.     first_chunk = next(chunk)
  122.     first_chunk.to_excel(writer, sheet_name='大数据', index=False)
  123.    
  124.     # 继续读取剩余数据
  125.     for i, chunk in enumerate(chunk):
  126.         chunk.to_excel(
  127.             writer,
  128.             sheet_name='大数据',
  129.             index=False,
  130.             startrow=len(first_chunk) + i*50000 + 1,  # 计算正确的起始行
  131.             header=False   # 不包含表头
  132.         )
  133.    
  134.     writer.close()
  135.    
  136.     # 关闭数据库连接
  137.     engine.dispose()
  138.    
  139.     # 删除临时数据库文件
  140.     import os
  141.     if os.path.exists('temp_db.sqlite'):
  142.         os.remove('temp_db.sqlite')
  143.    
  144.     print(f"数据已通过数据库导出到 {file_path}")
  145. # 使用数据库方法导出
  146. export_via_database(large_df, '大型数据_通过数据库.xlsx')
复制代码

总结

本指南全面介绍了如何使用pandas将数据输出到Excel文件,从基础操作到高级技巧,帮助您解决实际工作中的数据保存与分享问题。我们学习了:

1. 基础操作:如何安装必要的库,创建DataFrame并导出到Excel,以及如何控制导出格式。
2. 中级技巧:如何将多个DataFrame导出到同一个Excel文件的不同工作表中,如何设置单元格样式,以及如何处理日期时间格式。
3. 高级应用:如何添加条件格式,创建图表,添加数据验证,以及添加公式等高级Excel功能。
4. 性能优化:如何处理大数据量,优化内存使用,以及使用分块写入等技术。
5. 实际案例:通过销售报告自动化和财务数据导出与分析两个实际案例,展示了如何将所学知识应用到实际工作中。
6. 常见问题与解决方案:解决了导出的Excel文件打不开或损坏、日期时间格式不正确、中文显示乱码、大数据量导出内存不足等常见问题。

基础操作:如何安装必要的库,创建DataFrame并导出到Excel,以及如何控制导出格式。

中级技巧:如何将多个DataFrame导出到同一个Excel文件的不同工作表中,如何设置单元格样式,以及如何处理日期时间格式。

高级应用:如何添加条件格式,创建图表,添加数据验证,以及添加公式等高级Excel功能。

性能优化:如何处理大数据量,优化内存使用,以及使用分块写入等技术。

实际案例:通过销售报告自动化和财务数据导出与分析两个实际案例,展示了如何将所学知识应用到实际工作中。

常见问题与解决方案:解决了导出的Excel文件打不开或损坏、日期时间格式不正确、中文显示乱码、大数据量导出内存不足等常见问题。

通过掌握这些技巧,您可以更加高效地处理数据,并将结果以专业、美观的方式分享给他人。无论是简单的数据导出,还是复杂的报告生成,pandas与Excel的结合都能满足您的需求。

在实际应用中,请根据您的具体需求选择合适的方法和技巧,并注意性能优化,特别是在处理大数据量时。希望本指南能帮助您更好地利用pandas和Excel,提高工作效率。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则