🔥
个人主页:
杨利杰YJlio
❄️
个人专栏:
《Sysinternals实战教程》
《Windows PowerShell 实战》
《WINDOWS教程》
《IOS教程》
《微信助手》
《锤子助手》
《Python》
《Kali Linux》
《那些年未解决的Windows疑难杂症》
🌟
让复杂的事情更简单,让重复的工作自动化

《超简单:用 Python 让 Excel 飞起来》读书笔记:3.5.2 文件的读取和写入:read_excel、read_csv、to_excel、to_csv
- 1. 3.5.2 文件的读取和写入:read_excel、read_csv、to_excel、to_csv
- 2. 读取 Excel:pd.read_excel()
- 3. 读取 CSV:pd.read_csv() 与乱码问题
- 4. 写入 Excel 和 CSV:to_excel() 与 to_csv()
- 5. 一个完整小闭环:读 → 处理 → 写
- 6. 常见问题:文件读写不是只看语法
- 7. 总结提升:把文件读写看成自动化闭环

1. 3.5.2 文件的读取和写入:read_excel、read_csv、to_excel、to_csv
V4修正版进度标记:本篇为 06月14日 第2篇,承接 06月07日第2篇“2.7.2 自定义函数”之后继续更新。
这一篇是我阅读《超简单:用 Python 让 Excel 飞起来》时整理的读书笔记,主题是 3.5.2 文件的读取和写入:read_excel、read_csv、to_excel、to_csv。这一节开始,Pandas 的价值会变得非常明显:它不是让我们一格一格操作 Excel,而是把文件读成 DataFrame,处理完成后再统一导出。
如果说前面学习 os、xlwings 更偏“文件与 Excel 对象操作”,那么这一节更偏“数据处理闭环”。实际办公自动化里,很多任务都是这样的:先读取 Excel 或 CSV,清洗、筛选、计算,再输出新的 Excel 或 CSV 文件。
我对这一节的理解是:Pandas 文件读写不是孤立函数,而是办公自动化的输入口和输出口。会读,才能把外部文件变成可处理的数据;会写,才能把处理结果变成别人能打开、能检查、能交付的文件。
这张图展示的是 Pandas 文件读取与写入的整体流程:Excel / CSV 文件先被读取成 DataFrame,处理完成后再输出为 Excel / CSV。

从图中可以看出,DataFrame 是中间核心。Excel 和 CSV 只是数据的文件形态,真正进入 Python 后,我们主要围绕 DataFrame 做筛选、计算、清洗和导出。掌握这条链路后,后面的批量报表处理、数据清洗、自动生成结果文件就有了基础。
#mermaid-svg-6fXK7Vtb4dSirQtZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6fXK7Vtb4dSirQtZ .error-icon{fill:#552222;}#mermaid-svg-6fXK7Vtb4dSirQtZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6fXK7Vtb4dSirQtZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .marker.cross{stroke:#333333;}#mermaid-svg-6fXK7Vtb4dSirQtZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6fXK7Vtb4dSirQtZ p{margin:0;}#mermaid-svg-6fXK7Vtb4dSirQtZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster-label text{fill:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster-label span{color:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster-label span p{background-color:transparent;}#mermaid-svg-6fXK7Vtb4dSirQtZ .label text,#mermaid-svg-6fXK7Vtb4dSirQtZ span{fill:#333;color:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .node rect,#mermaid-svg-6fXK7Vtb4dSirQtZ .node circle,#mermaid-svg-6fXK7Vtb4dSirQtZ .node ellipse,#mermaid-svg-6fXK7Vtb4dSirQtZ .node polygon,#mermaid-svg-6fXK7Vtb4dSirQtZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .rough-node .label text,#mermaid-svg-6fXK7Vtb4dSirQtZ .node .label text,#mermaid-svg-6fXK7Vtb4dSirQtZ .image-shape .label,#mermaid-svg-6fXK7Vtb4dSirQtZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-6fXK7Vtb4dSirQtZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .rough-node .label,#mermaid-svg-6fXK7Vtb4dSirQtZ .node .label,#mermaid-svg-6fXK7Vtb4dSirQtZ .image-shape .label,#mermaid-svg-6fXK7Vtb4dSirQtZ .icon-shape .label{text-align:center;}#mermaid-svg-6fXK7Vtb4dSirQtZ .node.clickable{cursor:pointer;}#mermaid-svg-6fXK7Vtb4dSirQtZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .arrowheadPath{fill:#333333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6fXK7Vtb4dSirQtZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6fXK7Vtb4dSirQtZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6fXK7Vtb4dSirQtZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster text{fill:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ .cluster span{color:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6fXK7Vtb4dSirQtZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6fXK7Vtb4dSirQtZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-6fXK7Vtb4dSirQtZ .icon-shape,#mermaid-svg-6fXK7Vtb4dSirQtZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6fXK7Vtb4dSirQtZ .icon-shape p,#mermaid-svg-6fXK7Vtb4dSirQtZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6fXK7Vtb4dSirQtZ .icon-shape .label rect,#mermaid-svg-6fXK7Vtb4dSirQtZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6fXK7Vtb4dSirQtZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6fXK7Vtb4dSirQtZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6fXK7Vtb4dSirQtZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Excel / CSV 原始文件
read_excel / read_csv 读取
DataFrame 数据处理
to_excel 输出 Excel
to_csv 输出 CSV
结果文件 / 报表交付
这张流程图就是本节的核心逻辑。不要把 read_excel()、read_csv()、to_excel()、to_csv() 当成四个零散函数来背,而要把它们放到“读入 → 处理 → 输出”的完整链路里理解。

2. 读取 Excel:pd.read_excel()
读取 Excel 文件,最常用的函数是 pd.read_excel()。它的作用很直接:把一个 .xlsx 文件中的工作表读取成 DataFrame。对于日常办公来说,这一步相当于把 Excel 表格搬进 Python,后续才能做自动化处理。
最基础的写法如下:
import pandas as pd
df = pd.read_excel(r"C:\\Temp\\data\\报表.xlsx")
print(df.head())
这里的 df 就是读取后的 DataFrame。df.head() 用来查看前几行数据,适合在读取完成后先确认文件是否正常读进来。
我建议读取文件后第一件事就是看 df.head()。因为脚本没有报错,不代表数据结构就一定正确。比如表头行不对、空行过多、读取错了工作表,都会导致后续处理出问题。
如果 Excel 文件里有多张工作表,就需要通过 sheet_name 指定读取哪一张表。可以按表名读取:
df = pd.read_excel(r"C:\\Temp\\data\\报表.xlsx", sheet_name="Sheet1")
也可以按索引读取,0 表示第一张表:
df = pd.read_excel(r"C:\\Temp\\data\\报表.xlsx", sheet_name=0)
如果一次读取多个工作表,返回结果是一个字典,字典的 key 是工作表名称,value 是对应的 DataFrame:
dfs = pd.read_excel(
r"C:\\Temp\\data\\报表.xlsx",
sheet_name=["Sheet1", "汇总"]
)
print(type(dfs))
print(dfs["汇总"].head())
这张图展示的是读取 Excel 和 CSV 文件的共同目标:不管源文件是 .xlsx 还是 .csv,最终都要读成 DataFrame。

从图中可以看出,read_excel() 和 read_csv() 的入口文件不同,但输出结果都是 DataFrame。这就是 Pandas 最统一的地方:不同格式的文件,读进来以后都尽量变成同一种数据结构。
如果 Excel 第一列是工号、编号、资产编号这类主键,可以使用 index_col 指定索引列:
df = pd.read_excel(
r"C:\\Temp\\data\\报表.xlsx",
sheet_name=0,
index_col=0
)
print(df.index)
index_col=0 表示把第 1 列作为索引。也可以按列名指定,例如 index_col="工号"。不过前提是表头中确实存在这个列名。
需要注意:Excel 的中文乱码问题,通常不是靠 encoding 解决。.xlsx 不是普通文本文件,实际遇到问题时,优先检查文件格式、工作表名称、表头位置和读取引擎,而不是第一反应就加 encoding。

3. 读取 CSV:pd.read_csv() 与乱码问题
CSV 文件在办公自动化中非常常见,很多系统导出的数据不是 Excel,而是 .csv。它看起来像表格,但本质上是文本文件。因此,CSV 比 Excel 更容易遇到编码、分隔符和列错位问题。
最基础的读取方式如下:
import pandas as pd
df = pd.read_csv(r"C:\\Temp\\data\\data.csv")
print(df.head())
如果 CSV 是标准逗号分隔,这段代码通常可以直接读取。但真实办公环境里,经常会遇到分号、制表符、竖线等其他分隔符。这时就需要指定 delimiter 或 sep。
df = pd.read_csv(r"C:\\Temp\\data\\data.csv", delimiter=";")
如果是制表符分隔的 .tsv 文件,可以这样写:
df = pd.read_csv(r"C:\\Temp\\data\\data.tsv", delimiter="\\t")
sep 和 delimiter 在这里可以理解为同类参数,很多人更习惯写 sep=";" 或 sep="\\t"。
这张图展示的是 CSV 读取时最容易出问题的几个参数:encoding、delimiter/sep 和 index_col。

从图中可以看出,CSV 的问题通常不是函数不会用,而是文件本身存在差异。编码不对会乱码,分隔符不对会列错位,索引列设置不对会影响后续数据处理。
CSV 的中文乱码是高频坑。常见编码主要有 utf-8、utf-8-sig 和 gbk。如果 CSV 是给 Excel 打开的,我更推荐写入时使用 utf-8-sig;如果文件来自老系统或 Windows 旧软件导出,读取时可以尝试 gbk。
df = pd.read_csv(
r"C:\\Temp\\data\\data.csv",
encoding="utf-8-sig"
)
如果上面读取失败,可以尝试:
df = pd.read_csv(
r"C:\\Temp\\data\\data.csv",
encoding="gbk"
)
CSV 同样可以指定索引列:
df = pd.read_csv(
r"C:\\Temp\\data\\data.csv",
index_col=0
)
也可以按列名指定:
df = pd.read_csv(
r"C:\\Temp\\data\\data.csv",
index_col="工号"
)
我的建议是:读取 CSV 时先确认三件事:编码、分隔符、表头是否正确。这三个点不确认,后面的数据处理很容易建立在错误数据上。

4. 写入 Excel 和 CSV:to_excel() 与 to_csv()
读取文件只是第一步,办公自动化最终还是要输出结果。Pandas 中常用的输出函数有两个:DataFrame.to_excel() 和 DataFrame.to_csv()。前者适合生成 Excel 报表,后者适合生成通用文本数据文件。
最基础的 Excel 写入方式如下:
df.to_excel(r"C:\\Temp\\output\\结果.xlsx")
如果要指定写入的工作表名称,可以使用 sheet_name:
df.to_excel(
r"C:\\Temp\\output\\结果.xlsx",
sheet_name="汇总"
)
默认情况下,to_excel() 会把索引也写入 Excel。如果不想多出一列索引,建议加上 index=False。
df.to_excel(
r"C:\\Temp\\output\\结果.xlsx",
sheet_name="汇总",
index=False
)
如果只想输出部分列,可以使用 columns 参数:
df.to_excel(
r"C:\\Temp\\output\\结果.xlsx",
sheet_name="汇总",
index=False,
columns=["姓名", "工资"]
)
这张图展示的是 DataFrame 输出到 Excel 和 CSV 的常见路径,也包括输出时经常需要关注的参数。

从图中可以看出,to_excel() 更适合输出报表文件,常用参数是 sheet_name、index 和 columns;to_csv() 更适合输出通用数据文件,重点参数是 encoding、sep 和 index。
写入 CSV 的基础方式如下:
df.to_csv(r"C:\\Temp\\output\\结果.csv")
但在中文办公环境里,我更推荐这样写:
df.to_csv(
r"C:\\Temp\\output\\结果.csv",
encoding="utf-8-sig",
index=False
)
encoding="utf-8-sig" 对 Excel 打开 CSV 更友好。很多时候你用 Python 打开不乱码,但用户用 Excel 双击打开 CSV 出现乱码,就是因为编码没有考虑 Excel 的识别习惯。
如果需要生成分号分隔的 CSV,可以指定 sep:
df.to_csv(
r"C:\\Temp\\output\\结果.csv",
sep=";",
encoding="utf-8-sig",
index=False
)
注意:不要只看文件是否生成,还要打开结果文件检查列是否对齐、中文是否正常、索引列是否多出一列。这一步比单纯看到“运行成功”更重要。

5. 一个完整小闭环:读 → 处理 → 写
真正的办公自动化不是只读取文件,也不是只导出文件,而是形成一个完整闭环:读取原始数据,完成处理逻辑,再输出结果文件。下面这个例子演示的是一个最小可用模板。
import pandas as pd
# 1. 读取 Excel,指定第一张表,并把第一列作为索引
df = pd.read_excel(
r"C:\\Temp\\data\\报表.xlsx",
sheet_name=0,
index_col=0
)
# 2. 简单处理:新增一列
df["工资_涨10%"] = df["工资"] * 1.1
# 3. 写回 Excel
df.reset_index().to_excel(
r"C:\\Temp\\output\\结果.xlsx",
sheet_name="处理结果",
index=False
)
# 4. 同时导出 CSV,使用 Excel 友好编码
df.reset_index().to_csv(
r"C:\\Temp\\output\\结果.csv",
encoding="utf-8-sig",
index=False
)
print("处理完成:已输出 Excel + CSV")
这张图展示的是完整的数据流转过程:Excel / CSV 输入,经过 DataFrame 处理,再输出 Excel / CSV 结果文件。

从图中可以看出,Pandas 文件读写的关键不是某一个函数,而是把输入、处理、输出串成稳定流程。只要这个闭环跑通,后面就可以继续加入筛选、排序、去重、分组统计、字段清洗等更多处理动作。
这里有一个细节:示例中使用了 df.reset_index()。这是因为前面读取时设置了 index_col=0,如果直接导出,有时索引会以单独列的形式影响结果结构。通过 reset_index() 可以把索引恢复成普通列,再输出成更接近 Excel 表格的样子。
我的建议是:每次写读写闭环脚本,都至少验证三个点:读取是否正确、处理结果是否正确、输出文件是否能正常打开。不要只看控制台有没有报错。

6. 常见问题:文件读写不是只看语法
Pandas 文件读写的函数不难,真正容易出问题的是文件本身。尤其是在办公环境里,文件来源复杂,可能来自系统导出、同事手工整理、网页下载、旧软件生成,格式经常没有想象中标准。
第一个常见问题是路径错误。Windows 路径里有反斜杠,建议使用原始字符串,例如 r"C:\\Temp\\data\\报表.xlsx"。如果路径写错,脚本会直接找不到文件。
第二个常见问题是工作表名称不一致。代码里写 sheet_name="Sheet1",但真实文件里可能叫 数据 或 明细。这类问题不是 Pandas 不会读,而是目标表根本不存在。
第三个常见问题是CSV 编码错误。中文乱码、读取失败、Excel 打开乱码,大多和编码有关。CSV 是文本文件,encoding 是高频关键参数;Excel 文件不是普通文本,encoding 不是万能解法。
第四个常见问题是多出索引列。如果导出时没有写 index=False,Excel 或 CSV 结果里可能多出一列索引。这不是错误,但经常不符合交付习惯。
我比较推荐的输出方式是:
df.to_excel(
r"C:\\Temp\\output\\结果.xlsx",
index=False
)
df.to_csv(
r"C:\\Temp\\output\\结果.csv",
encoding="utf-8-sig",
index=False
)
这两个参数组合非常实用:Excel 输出关闭索引,CSV 输出使用 utf-8-sig 并关闭索引。对大多数中文办公场景来说,这样生成的文件更接近用户期望。

7. 总结提升:把文件读写看成自动化闭环
这一节我最后记成一句话:Pandas 的文件读写,本质是把外部 Excel / CSV 文件转换成 DataFrame,处理完成后再输出成可交付文件。
pd.read_excel() 适合读取 Excel 工作表,重点关注 sheet_name 和 index_col;pd.read_csv() 适合读取文本型数据文件,重点关注 encoding、delimiter/sep 和 index_col。
df.to_excel() 适合输出报表结果,重点关注 sheet_name、index 和 columns;df.to_csv() 适合输出通用数据文件,中文环境下建议重点关注 encoding="utf-8-sig" 和 index=False。
如果只会复制函数,但不知道文件格式、编码、分隔符、索引列这些参数的意义,真实办公数据一来还是会卡住。因为办公自动化不是跑通一段示例代码,而是处理不那么标准的真实文件。
我的建议是:以后写 Pandas 文件处理脚本时,先搭一个最小闭环。也就是先完成“读入一个文件 → 简单处理一列 → 导出一个结果文件 → 打开验证结果”。这个闭环跑稳了,再继续加复杂逻辑。
真正能提升效率的,不是记住多少函数名,而是形成稳定的处理套路:输入是什么,处理对象是什么,输出给谁看,如何验证结果正确。这才是 Pandas 在办公自动化里真正有用的地方。
🔝 返回顶部
点击回到顶部



