xlsxwriter
入门与核心概念xlsxwriter
概述xlsxwriter
是一个 Python 模块,用于将文本、数字、公式以及格式化信息写入 Microsoft Excel 2007+ .xlsx
格式的文件。
主要特点:
xlsxwriter
通常比其他库有更好的性能,部分原因在于其流式写入和内存优化选项。vbaProject.bin
文件)。constant_memory
),用于处理非常大的数据集。.xlsx
文件完全符合 Office Open XML (OOXML) 规范,不需要在服务器或运行环境中安装 Microsoft Excel。ExcelWriter
的引擎,方便地将 DataFrame 导出到 Excel。与 openpyxl
的关键区别:
特性 | xlsxwriter |
openpyxl |
---|---|---|
文件操作 | 仅创建新文件 (.xlsx ) |
创建、读取、修改现有文件 (.xlsx , .xlsm ) |
依赖性 | 无外部依赖 (除了Python标准库) | 无外部依赖 (除了Python标准库) |
性能 | 通常在写入新大文件时性能更优 | 读取和修改操作灵活,写入性能尚可 |
图表API | 较底层,但功能全面 | 提供了较好的图表对象模型 |
VBA宏 | 可以嵌入 vbaProject.bin |
可以读取和保存包含宏的文件 (.xlsm ) |
内存优化 | 提供 constant_memory 模式 |
也有只读/只写优化模式 |
选择哪个库取决于具体需求。如果你的任务是从头生成 Excel 文件,特别是需要高性能或特定高级格式化功能时,xlsxwriter
是一个绝佳的选择。如果需要读取或修改现有文件,则应选择 openpyxl
。
xlsxwriter
安装 xlsxwriter
非常简单,使用 pip 即可:
pip install XlsxWriter
这条命令会从 Python Package Index (PyPI) 下载并安装最新版本的 xlsxwriter
。
使用 xlsxwriter
创建 Excel 文件的基本步骤如下:
xlsxwriter
模块。Workbook
对象:这是 Excel 文件在内存中的表示。在创建 Workbook
对象时,需要指定要输出的文件名。Workbook
中添加一个或多个 Worksheet
对象:每个工作表对应 Excel 文件中的一个 sheet。Worksheet
的单元格中写入数据:可以使用 worksheet.write()
方法或其特定类型的变体(如 write_string()
, write_number()
, write_formula()
等)。Format
对象并将其应用于单元格或行/列。Workbook
对象:调用 workbook.close()
方法。这个步骤至关重要,它会将所有数据和格式写入到磁盘上的 .xlsx
文件中。如果不调用 close()
,文件可能不会被正确创建或内容不完整。 推荐使用 with
语句来自动管理 Workbook
的关闭。xlsxwriter
程序:Hello Excel让我们创建一个简单的 Excel 文件,包含一些基本数据。
import xlsxwriter # 导入 xlsxwriter 模块
# 1. 创建一个新的 Excel 文件并添加一个工作表。
# 构造函数 Workbook() 接受文件名作为参数。
workbook = xlsxwriter.Workbook('hello_excel.xlsx') # 创建一个名为 'hello_excel.xlsx' 的 Workbook 对象
# add_worksheet() 方法添加一个新的工作表。
# 如果不指定名称,工作表将按默认名称命名,如 Sheet1, Sheet2 等。
worksheet = workbook.add_worksheet('问候') # 向工作簿中添加一个名为 '问候' 的工作表
# 2. 向单元格写入数据。
# write() 方法用于向单元格写入数据。
# 参数可以是:(row, col, item, cell_format=None) 或 (cell_name, item, cell_format=None)
# row 和 col 是从0开始的索引。
# 使用 A1 单元格引用方式写入字符串
worksheet.write('A1', '你好,世界!') # 在 A1 单元格写入字符串 '你好,世界!'
# 使用行号和列号 (row, col) 方式写入数字
worksheet.write(1, 0, 123.45) # 在第2行第1列 (即 A2 单元格,索引为 1,0) 写入数字 123.45
# 写入公式
worksheet.write(2, 0, '=SUM(A2, 10)') # 在 A3 单元格写入公式 '=SUM(A2, 10)'
# 写入日期 (需要使用 workbook.add_format() 来格式化日期)
import datetime # 导入 datetime 模块
date_format = workbook.add_format({
'num_format': 'yyyy-mm-dd hh:mm:ss'}) # 创建一个日期格式对象
a_date = datetime.datetime(2023, 11, 15, 10, 30, 0) # 创建一个 datetime 对象
worksheet.write_datetime('A4', a_date, date_format) # 在 A4 单元格写入日期,并应用日期格式
# 3. 关闭 Workbook 对象。
# 这会将数据写入 Excel 文件并关闭它。
workbook.close() # 关闭工作簿,将内存中的数据写入到磁盘文件
print("文件 'hello_excel.xlsx' 已成功创建。") # 打印成功创建文件的消息
打开生成的 hello_excel.xlsx
文件,你会看到:
=SUM(A2,10)
,并且其显示值为 133.45。使用 with
语句管理 Workbook
(推荐)
为了确保 workbook.close()
总是被调用,即使在发生异常时也是如此,推荐使用 with
语句:
import xlsxwriter # 导入 xlsxwriter 模块
import datetime # 导入 datetime 模块
file_name_with_with = 'hello_with_statement.xlsx' # 定义文件名
with xlsxwriter.Workbook(file_name_with_with) as workbook: # 使用 with 语句创建 Workbook 对象,确保自动关闭
worksheet = workbook.add_worksheet("示例Sheet") # 添加一个名为 "示例Sheet" 的工作表
worksheet.write_string(0, 0, "使用with语句") # 在 A1 单元格写入字符串
worksheet.write_number(1, 0, 999) # 在 A2 单元格写入数字
worksheet.write_formula(2, 0, '=B2*2') # 在 A3 单元格写入公式
date_fmt = workbook.add_format({
'num_format': 'yyyy/mm/dd'}) # 创建日期格式
worksheet.write_datetime(3, 0, datetime.date(2024, 1, 1), date_fmt) # 在 A4 单元格写入日期
print(f"文件 '{
file_name_with_with}' 已通过 with 语句成功创建。") # 打印成功消息
当 with
语句块结束时,workbook
对象的 __exit__
方法会被调用,该方法内部会执行 self.close()
。
xlsxwriter
提供了多种 write_*()
方法来显式地处理不同类型的数据,这有助于确保数据在 Excel 中被正确解释和存储。虽然通用的 write()
方法通常能根据 Python 数据类型自动选择合适的 Excel 类型,但使用特定类型的方法可以提供更精细的控制。
write_string(row, col, string, cell_format=None)
用于写入字符串。
# ... (假设 workbook 和 worksheet 已创建) ...
# worksheet = workbook.add_worksheet()
worksheet.write_string(0, 0, "这是一个字符串") # 在 A1 写入字符串
worksheet.write_string('B1', "另一个字符串") # 在 B1 写入字符串
Excel 对单元格中的字符串长度有限制(通常是32767个字符)。如果字符串超过此限制,xlsxwriter
会截断它或引发异常,具体行为取决于版本和配置。
write_number(row, col, number, cell_format=None)
用于写入整数或浮点数。
# ... (worksheet 已创建) ...
worksheet.write_number(1, 0, 123) # 在 A2 写入整数 123
worksheet.write_number('B2', 3.14159) # 在 B2 写入浮点数 3.14159
worksheet.write_number(1, 2, -50.5) # 在 C2 写入负数 -50.5
write_blank(row, col, blank, cell_format=None)
用于写入一个空单元格。这与单元格中有一个空字符串 ""
不同。一个真正的空单元格通常用于格式化或作为公式的占位符。
参数 blank
通常是 None
。
# ... (worksheet 已创建) ...
# 创建一个带边框的格式,用于空单元格
blank_format = workbook.add_format({
'border': 1}) # 创建一个带单线边框的格式
worksheet.write_blank(2, 0, None, blank_format) # 在 A3 写入一个空单元格,并应用边框格式
worksheet.write_string(2, 1, "", blank_format) # 在 B3 写入一个空字符串,并应用边框格式 (注意区别)
在Excel中,A3单元格将是真正的空(但有边框),而B3单元格包含一个零长度的字符串。
write_formula(row, col, formula, cell_format=None, value=None)
用于写入 Excel 公式。
formula
: 字符串形式的 Excel 公式,必须以 =
开头。cell_format
: 可选的单元格格式。value
: 可选参数,用于设置公式计算的初始结果。如果 Excel 文件被不支持公式计算的应用程序(如某些查看器)打开,这个值会被显示。如果省略,xlsxwriter
通常会将值设置为0。# ... (worksheet 已创建) ...
worksheet.write_number('A5', 10) # 在 A5 写入数字 10
worksheet.write_number('B5', 20) # 在 B5 写入数字 20
# 写入简单公式
worksheet.write_formula('C5', '=A5+B5') # 在 C5 写入公式 '=A5+B5'
# 写入带结果的公式
worksheet.write_formula('D5', '=SUM(A5:B5)', None, 30) # 在 D5 写入公式 '=SUM(A5:B5)',并指定结果为30
# 写入引用其他工作表的公式
worksheet2 = workbook.add_worksheet('Sheet2') # 添加另一个工作表 Sheet2
worksheet2.write_number('A1', 100) # 在 Sheet2 的 A1 写入数字 100
# 假设当前 worksheet 是 'Sheet1'
worksheet.write_formula('E5', "=Sheet2!A1 * 2") # 在 Sheet1 的 E5 写入引用 Sheet2!A1 的公式
# 动态公式 (字符串函数等)
worksheet.write_formula('F5', '=LEFT(A1, 2)') # 在 F5 写入公式 '=LEFT(A1, 2)' (假设A1是 "这是一个字符串")
# 数组公式 (见后续高级部分)
# worksheet.write_array_formula('A6:A8', '{=TREND(C1:C3,B1:B3)}')
公式的语法和函数名必须是英文的,即使在非英文版的 Excel 中也是如此。Excel 会在打开文件时自动将它们本地化。
write_datetime(row, col, datetime_obj, cell_format=None)
用于写入 Python datetime.datetime
, datetime.date
, 或 datetime.time
对象。Excel 将日期和时间存储为序列号。xlsxwriter
会自动进行转换。为了正确显示日期/时间,通常需要提供一个包含数字格式的 cell_format
。
import datetime # 导入 datetime 模块
# ... (workbook 和 worksheet 已创建) ...
# 创建日期时间格式
date_fmt_full = workbook.add_format({
'num_format': 'yyyy-mm-dd hh:mm:ss', 'align': 'left'}) # 创建完整日期时间格式
date_fmt_ymd = workbook.add_format({
'num_format': 'yyyy"年"mm"月"dd"日"'}) # 创建年月日格式
time_fmt = workbook.add_format({
'num_format': 'hh:mm AM/PM'}) # 创建时间格式
# 写入 datetime.datetime 对象
dt_obj = datetime.datetime(2023, 12, 25, 14, 30, 55) # 创建一个 datetime 对象
worksheet.write_datetime('A7', dt_obj, date_fmt_full) # 在 A7 写入完整的日期时间
# 写入 datetime.date 对象
d_obj = datetime.date(2024, 7, 1) # 创建一个 date 对象
worksheet.write_datetime('B7', d_obj, date_fmt_ymd) # 在 B7 写入日期 (年月日)
# 写入 datetime.time 对象 (Excel 中时间是日期的一部分,通常是序列号的小数部分)
# 单独的时间对象会被视为从1899-12-30 (或1904-01-01,取决于日期系统) 开始的小数
t_obj = datetime.time(18, 45, 0) # 创建一个 time 对象
worksheet.write_datetime('C7', t_obj, time_fmt) # 在 C7 写入时间
# 注意:如果单元格没有日期部分,Excel可能会显示一个奇怪的日期(如1900-01-00)。
# 如果只想显示时间,通常会将日期时间对象(如 datetime.datetime.now())写入,并仅用时间格式化。
# 或者,如果只关注时间部分,可以写一个包含时间的完整日期,然后只显示时间。
full_dt_for_time = datetime.datetime(2000, 1, 1, 18, 45, 0) # 创建一个包含日期的 datetime 对象
worksheet.write_datetime('D7', full_dt_for_time, time_fmt) # 在 D7 写入,仅显示时间部分
# 写入当前日期和时间
worksheet.write_datetime('E7', datetime.datetime.now(), date_fmt_full) # 在 E7 写入当前日期时间
write_boolean(row, col, boolean, cell_format=None)
用于写入布尔值 True
或 False
。Excel 会将它们显示为 TRUE 和 FALSE。
# ... (worksheet 已创建) ...
worksheet.write_boolean(7, 0, True) # 在 A8 写入布尔值 TRUE
worksheet.write_boolean('B8', False) # 在 B8 写入布尔值 FALSE
write_url(row, col, url, cell_format=None, string=None, tip=None)
用于写入超链接。
url
: 链接的目标地址 (例如 'http://www.python.org/'
或 'internal:Sheet2!A1'
或 'file:///path/to/file.txt'
)。cell_format
: 可选,应用到链接文本的格式。xlsxwriter
默认会应用标准的蓝色下划线超链接样式。你可以通过 workbook.get_default_url_format()
获取并修改这个默认格式,或者提供一个全新的格式。string
: 可选,链接显示的文本。如果省略,将显示 url
本身。tip
: 可选,鼠标悬停在链接上时显示的工具提示文本 (屏幕提示)。# ... (worksheet 已创建) ...
# 获取并修改默认的URL格式 (例如,去掉下划线)
url_format = workbook.get_default_url_format() # 获取默认URL格式对象
url_format.set_underline(False) # 设置URL格式为无下划线
url_format.set_font_color('navy') # 设置URL字体颜色为海军蓝
# 写入外部URL,显示自定义文本和提示
worksheet.write_url('A9', 'https://www.djangoproject.com/', string='Django官网', tip='访问Django项目主页') # 在 A9 写入外部URL
# 写入内部工作表链接
worksheet.write_url('B9', "internal:Sheet2!B5", string="跳转到Sheet2的B5", cell_format=url_format) # 在 B9 写入内部链接,并应用自定义格式
# 写入文件链接
worksheet.write_url('C9', r'file:///C:\Users\Public\Documents\example.txt', string='打开示例文档') # 在 C9 写入文件链接 (注意路径格式)
# 对于本地文件,路径需要是绝对路径,并且格式正确
# 写入邮件链接
worksheet.write_url('D9', 'mailto:[email protected]?subject=Hello from XlsxWriter', string='发送邮件') # 在 D9 写入邮件链接
# 如果只想显示URL本身作为链接文本
worksheet.write_url('E9', 'https://xlsxwriter.readthedocs.io/') # 在 E9 写入URL,链接文本也是URL本身
write(row, col, data, cell_format=None)
方法write()
方法会尝试根据传入的 data
的 Python 类型来调用相应的 write_*()
方法。
str
-> write_string()
int
, float
-> write_number()
bool
-> write_boolean()
datetime.datetime
, datetime.date
, datetime.time
-> write_datetime()
data
是以 =
开头的字符串,则调用 write_formula()
。data
是 None
,则调用 write_blank()
(除非有格式,否则可能不写入任何内容)。# ... (worksheet 已创建) ...
worksheet.write(9, 0, "自动类型推断") # 在 A10 写入,自动识别为字符串
worksheet.write(9, 1, 789.01) # 在 B10 写入,自动识别为数字
worksheet.write(9, 2, True) # 在 C10 写入,自动识别为布尔值
worksheet.write(9, 3, datetime.date.today(), date_fmt_ymd) # 在 D10 写入,自动识别为日期,并应用格式
worksheet.write(9, 4, '=B10*2') # 在 E10 写入,自动识别为公式
worksheet.write(9, 5, None) # 在 F10 写入,识别为blank (如果没格式,单元格会是空的)
虽然 write()
很方便,但在某些情况下,显式使用 write_*()
方法可以提供更好的可读性和控制,特别是当数据类型可能不明确或需要特定处理时。
Excel 工作表有最大行数和列数限制:
xlsxwriter
会遵守这些限制。尝试写入超出范围的单元格会导致错误。
格式化是 xlsxwriter
的核心强项之一。它允许你对单元格应用丰富的格式,包括字体、数字格式、对齐方式、颜色、边框等。
Format
对象在 xlsxwriter
中,所有的单元格格式化都是通过 Format
对象来定义的。Format
对象由 Workbook
的 add_format()
方法创建。
# ... (workbook 已创建) ...
# 创建一个 Format 对象
bold_format = workbook.add_format() # 创建一个空的 Format 对象
bold_format.set_bold() # 调用 Format 对象的方法来设置属性,例如设置为粗体
# 或者在创建时通过字典传递属性
red_italic_format = workbook.add_format({
'bold': False, 'italic': True, 'font_color': 'red'}) # 创建Format对象并初始化属性
# 将 Format 对象应用于单元格
# worksheet = workbook.add_worksheet()
worksheet.write('A1', '粗体文本', bold_format) # 在 A1 单元格写入文本 "粗体文本",并应用 bold_format 格式
worksheet.write('B1', '红色斜体', red_italic_format) # 在 B1 单元格写入文本 "红色斜体",并应用 red_italic_format 格式
add_format()
方法返回一个 Format
对象。你可以多次调用 Format
对象的方法来设置不同的格式属性。Format
对象在工作簿中是共享的,如果多个单元格使用完全相同的格式,它们会引用同一个 Format
对象,这有助于减小文件大小。
Format
对象支持大量的属性设置方法。以下是一些最常用的:
set_font_name(font_name)
: 设置字体名称,如 ‘Arial’, ‘微软雅黑’, ‘Times New Roman’。font_name_format = workbook.add_format() # 创建格式对象
font_name_format.set_font_name('微软雅黑') # 设置字体为微软雅黑
worksheet.write('A2', '微软雅黑字体', font_name_format) # 应用格式
set_font_size(size)
: 设置字体大小 (磅)。font_size_format = workbook.add_format({
'font_size': 16}) # 创建格式对象并设置字体大小为16
worksheet.write('B2', '16号字', font_size_format) # 应用格式
set_font_color(color_string)
: 设置字体颜色。颜色可以是HTML样式的 '#RRGGBB'
字符串(如 '#FF0000'
代表红色),或者预定义的颜色名称(如 'red'
, 'green'
, 'blue'
, 'yellow'
, 'magenta'
, 'cyan'
, 'black'
, 'white'
, 'gray'
等)。font_color_format = workbook.add_format() # 创建格式对象
font_color_format.set_font_color('blue') # 设置字体颜色为蓝色
worksheet.write('C2', '蓝色字体', font_color_format) # 应用格式
font_color_hex_format = workbook.add_format({
'font_color': '#E066FF'}) # 紫色
worksheet.write('D2', '自定义紫色字体', font_color_hex_format) # 应用格式
set_bold()
: 设置为粗体。set_italic()
: 设置为斜体。set_underline(style)
: 设置下划线。style
可以是:
1
或 True
: 单下划线 (默认)2
: 双下划线33
: 单会计式下划线34
: 双会计式下划线bold_italic_format = workbook.add_format({
'bold': True, 'italic': True}) # 创建粗斜体格式
worksheet.write('A3', '粗斜体', bold_italic_format) # 应用格式
underline_format = workbook.add_format() # 创建格式对象
underline_format.set_underline(2) # 设置双下划线
worksheet.write('B3', '双下划线', underline_format) # 应用格式
set_font_strikeout()
: 设置删除线。set_font_script(style)
: 设置上标或下标。style
可以是:
1
: 上标2
: 下标strike_format = workbook.add_format({
'font_strikeout': True}) # 创建删除线格式
worksheet.write('C3', '删除线', strike_format) # 应用格式
superscript_format = workbook.add_format() # 创建格式对象
superscript_format.set_font_script(1) # 设置为上标
worksheet.write_rich_string('D3', 'E=mc', superscript_format, '2') # 写入 "E=mc²" (见富文本部分)
su