赞
踩
纵使xlwings
很好用,也掩盖不了无法在Linux上部署的缺点。
openpyxl
是一款读、写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库,它通过操作Office Open XML实现Excel的读写。
本文openpyxl版本为3.0.6
pip install openpyxl
from openpyxl import Workbook
wb = Workbook() # 创建新的工作簿
ws = wb['Sheet'] # 实例化工作表
# ws = wb.active # 默认实例化最后一个工作表
# ws = wb.create_sheet('Sheet1') # 在末尾创建工作表
ws.title = 'Sheet1' # 重命名工作表
ws['A1'] = 'Hello World' # 写入
print(ws['A1'].value) # 读取
wb.save('test.xlsx')
wb.close()
读取工作簿:openpyxl.load_workbook()
from openpyxl import load_workbook
wb = load_workbook(filename='test.xlsx')
ws = wb.active
for cells in ws.rows: # 按行遍历
for cell in cells:
value = cell.value
print(value, end=' ')
print()
插入一行数据:Worksheet.append()
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
first_row = ['a', 'b', 'c'] # 首行数据
row = 1
for i, data in enumerate(first_row): # 逐个写入
column = i + 1
ws.cell(row, column).value = data
for row in ws.iter_rows(min_row=1): # 逐个读取
for cell in row:
print(cell.value)
ws.append(['Foo 1', 'Foo 2', 'Foo 3']) # 批量写入一行(传列表)
ws.append({'A': 'Foo 1', 'C': 'Foo 3'}) # 批量写入一行(传字典)
ws.append({1: 'Foo 1', 3: 'Foo 3'}) # 批量写入一行(传字典)
wb.save('test.xlsx')
wb.close()
1.jpg
宽高为 200×153
安装
pip install pillow
代码
from openpyxl import Workbook
from openpyxl.drawing.image import Image
wb = Workbook()
ws = wb.active
img = Image('1.jpg') # 打开图片
_width, _height = img.width, img.height # 原图片宽高
width = 100 # 图片宽度设为100
height = width / _width * _height # 等比设置图片高度
img.width = width
img.height = height
ws.add_image(img, 'A1') # 插入图片
wb.save('test.xlsx')
wb.close()
效果
手动调整后
图片宽高与列宽行高的关系(不同电脑可能有区别)
列宽 = 图片宽度 × 0.13887
行高 = 图片高度 × 0.753
from openpyxl import Workbook
from openpyxl.drawing.image import Image
wb = Workbook()
ws = wb.active
img = Image('1.jpg') # 打开图片
_width, _height = img.width, img.height # 原图片宽高
width = 100 # 图片宽度设为100
height = width / _width * _height # 等比设置图片高度
print(width, height)
img.width = width
img.height = height
ws.add_image(img, 'A1') # 插入图片
ws.column_dimensions['A'].width = width * 0.13887 # 设置图片列宽
ws.row_dimensions[1].height = height * 0.753 # 设置图片行高
wb.save('test.xlsx')
wb.close()
效果
img.anchor(cell, anchortype="oneCell")
import datetime
from openpyxl import Workbook
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws.append(['Hello', '', 1, datetime.datetime.now()]) # 第1行
ws.append(['Hello World\nHow are you\nFine, thank you']) # 第2行
ws.merge_cells('A2:D2') # 合并单元格
ws['A2'].alignment = Alignment(wrap_text=True) # 第2行允许多行文本
ws.row_dimensions[2].height = 14.4 * 3 # 2行行高
ws.column_dimensions['D'].width = 20.0 # D列列宽
wb.save('test.xlsx')
wb.close()
效果
自动调整行高列宽
偷懒可以用这个,这块是很大一个坑,远没有Excel本身自动调整行高、列宽精细,且多行或字符较多时无法显示完整
import datetime
from openpyxl import Workbook
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws.append(['Hello', '', 1, datetime.datetime.now()]) # 第1行
ws.append(['Hello World\nHow are you\nFine, thank you']) # 第2行
ws.merge_cells('A2:D2') # 合并单元格
ws['A2'].alignment = Alignment(wrap_text=True) # 第2行允许多行文本
for i in ws.column_dimensions:
i.bestFit = True
i.auto_size = True
wb.save('test.xlsx')
wb.close()
效果
自动调整行高列宽(自己实现)
比例统计见下文 “统计字符数量与列宽关系”
import datetime
from openpyxl.cell import Cell
def auto_fit(ws, height_scale=1.0, width_scale=1.0):
"""自动调整openpyxl.Worksheet的行高列宽"""
BEGIN_ASCII = 2.5546875 # 首个ASCII字符所占宽度
BEGIN_UNICODE = 3.5546875 # 首个Unicode字符所占宽度
ONE_ASCII = 1.1 # 一个ASCII字符所占宽度
ONE_UNICODE = 2.2 # 一个Unicode字符所占宽度
DEFAULT_FONT_SIZE = 11 # 默认字体大小
DEFAULT_ROW_HEIGHT = 14.4 # 默认行高
row_heights = {} # 每一行的行高
col_widths = {} # 每一列的列宽
for row in ws.rows: # 从上往下遍历
for cell in row: # 从左往右遍历
scale = cell.font.size / DEFAULT_FONT_SIZE if cell.font.size else 1.0 # 当前字体与默认字体的比例
begin = True # 是否首个字符
length = 0 # 该单元格列宽
cell_type = type(cell.value) # 该单元格数据类型
value = str(cell.value)
row_heights[cell.row] = max((row_heights.get(cell.row, 0),
(value.count('\n') + 1) * DEFAULT_ROW_HEIGHT * scale * height_scale)) # 最大行高
if not isinstance(cell, Cell) or cell.coordinate in ws.merged_cells: # 跳过合并单元格
continue
value = max(value.splitlines(), key=str.__len__) if value else value # 多行取最长一行
for char in value: # 遍历每个字符
if cell_type == datetime.datetime and char == '.': # 日期类型后面不显示
break
if begin and ord(char) > 256: # 首个Unicode
length += BEGIN_UNICODE
begin = False
if begin and ord(char) <= 256:
length += BEGIN_ASCII # 首个ASCII
begin = False
if ord(char) > 256:
length += ONE_UNICODE
else:
length += ONE_ASCII
col_widths[cell.column_letter] = max(
(col_widths.get(cell.column_letter, 0), length * scale * width_scale)) # 最大列宽
for row, height in row_heights.items():
ws.row_dimensions[row].height = height # 设置行高
for column, width in col_widths.items():
ws.column_dimensions[column].width = width # 设置列宽
if __name__ == '__main__':
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font
wb = Workbook()
ws = wb.active
ws.append(['Hello', '', 1, datetime.datetime.now()]) # 第1行
ws.append(['Hello World\nHow are you\nFine, thank you']) # 第2行
ws.merge_cells('A2:D2') # 合并单元格
ws['A2'].alignment = Alignment(wrap_text=True) # 第2行允许多行文本
ws['A3'] = 'Hello!'
ws['A3'].font = Font(size=50)
auto_fit(ws)
wb.save('test.xlsx')
wb.close()
不用 auto_fit()
用了 auto_fit()
如果报错 AttributeError: ‘Cell’ object has no attribute ‘column_letter’
将column_letter
改成column
默认为底端对齐
from openpyxl import Workbook
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws.append(['a\n\nb', 'c']) # 写入一行
ws['A1'].alignment = Alignment(vertical='center', wrap_text=True) # 垂直居中,多行文本
ws['B1'].alignment = Alignment(horizontal='center') # 水平居中
ws.column_dimensions['A'].width = 10 # 列宽
ws.column_dimensions['B'].width = 10 # 列宽
ws.row_dimensions[1].height = 50 # 行高
wb.save('test.xlsx')
wb.close()
效果
推荐阅读:
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
for i in range(1, 11):
ws.append({i: i}) # 指定位置写入
for row in ws.rows: # 按行遍历
for cell in row:
value = cell.value
if value:
print(value)
wb.save('test.xlsx')
wb.close()
或
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
for i in range(1, 11):
ws.append({i: i}) # 指定位置写入
for (row, col), cell in ws._cells.items():
print((row, col), cell.value)
wb.save('test.xlsx')
wb.close()
效果
对应英文
import time
from datetime import datetime
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws['A1'] = '1'
ws['A2'] = 1234.567
ws['A2'].number_format = '####.#'
ws['A3'] = datetime.now() # 日期
ws['A4'] = time.strftime('%H:%M:%S', time.localtime())
ws['A5'] = 1234.567
ws['A5'].number_format = '0.00E+00'
print(ws['A1'].number_format) # General
print(ws['A2'].number_format) # ####.#
print(ws['A3'].number_format) # yyyy-mm-dd h:mm:ss
print(ws['A4'].number_format) # General
print(ws['A5'].number_format) # 0.00E+00
ws.column_dimensions['A'].width = 20 # 调整A列列宽
wb.save('test.xlsx')
wb.close()
效果
详细阅读:
函数使用英文名,参数用逗号分隔
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws['A1'] = '=SUM(1, 1)'
wb.save('test.xlsx')
wb.close()
效果
查看所有函数
from openpyxl.utils import FORMULAE
print(FORMULAE)
merge_cells()
unmerge_cells()
from openpyxl.workbook import Workbook
wb = Workbook()
ws = wb.active
# 合并单元格
ws.merge_cells('A1:C2')
# ws.merge_cells(start_row=1, start_column=1, end_row=2, end_column=3)
ws['A1'] = 1
# 拆分单元格
# ws.unmerge_cells('A1:C2')
# ws.unmerge_cells(start_row=1, start_column=1, end_row=2, end_column=3)
wb.save('test.xlsx')
wb.close()
效果
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active
ws.column_dimensions.group('A', 'D', hidden=True)
ws.row_dimensions.group(1, 10, hidden=True)
wb.save('test.xlsx')
wb.close()
效果
insert_rows()
insert_cols()
delete_rows()
delete_cols()
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
for i in range(1, 11):
ws.append({i: i}) # 指定位置写入
ws.insert_rows(2, 1) # 第2行开始插入1行
ws.insert_cols(3, 1) # 第3列开始插入1列
ws.delete_rows(5, 2) # 第5行开始删除2行
ws.delete_cols(6, 1) # 第5行开始删除2行
wb.save('test.xlsx')
wb.close()
move_range()
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws['A1'] = 1
ws['A2'] = 2
ws['B2'] = '=SUM(3)'
ws.move_range('A2:B2', rows=-1, cols=1, translate=True)
# rows=-1,向上移动一行
# cols=1,向右移动一列
# translate=True,移动数学公式
wb.save('test.xlsx')
wb.close()
ws.auto_filter.ref = ws.dimensions # 开启筛选功能
按功能分类:
Font
:字体,大小、颜色、下划线PatternFill
:填充,图案、颜色、渐变Border
:边框Alignment
:单元格对齐方式Protection
:保护按作用对象分类:
from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font
font = Font(name='Calibri',
size=11,
bold=False,
italic=False,
vertAlign=None,
underline='none',
strike=False,
color='FF000000')
fill = PatternFill(fill_type=None,
start_color='FFFFFFFF',
end_color='FF000000')
border = Border(left=Side(border_style=None,
color='FF000000'),
right=Side(border_style=None,
color='FF000000'),
top=Side(border_style=None,
color='FF000000'),
bottom=Side(border_style=None,
color='FF000000'),
diagonal=Side(border_style=None,
color='FF000000'),
diagonal_direction=0,
outline=Side(border_style=None,
color='FF000000'),
vertical=Side(border_style=None,
color='FF000000'),
horizontal=Side(border_style=None,
color='FF000000')
)
alignment = Alignment(horizontal='general',
vertical='bottom',
text_rotation=0,
wrap_text=False,
shrink_to_fit=False,
indent=0)
number_format = 'General'
protection = Protection(locked=True,
hidden=False)
参数 | 含义 | 取值 |
---|---|---|
name | 字体类型 | str |
b | 加粗 | bool |
bold | 加粗 | bool |
sz | 大小 | float |
size | 大小 | float |
i | 斜体 | bool |
italic | 斜体 | bool |
strike | 删除线 | bool |
strikethrough | 删除线 | bool |
color | 颜色 | openpyxl.styles.colors.Color |
vertAlign | 上下标 | 下标subscript 上标superscript |
u | 下划线 | 单下划线single 双下划线double 会计用单下划线singleAccounting 会计用双下划线doubleAccounting |
underline | 下划线 | 单下划线single 双下划线double 会计用单下划线singleAccounting 会计用双下划线doubleAccounting |
outline | bool | |
shadow | bool | |
condense | bool | |
extend | bool | |
family | float | |
scheme | {‘major’, ‘minor’} | |
charset | int |
from openpyxl import Workbook
from openpyxl.styles import Font, Color
wb = Workbook()
ws = wb.active
ws['A1'] = 123
ws['B2'] = 456
ws['C3'] = 789
ws['D4'] = 'Hello!'
ws['E5'] = '新年好!'
ws['A1'].font = Font(color='FF0000', italic=True)
ws['B2'].font = Font(name='Tahoma', strike=True)
ws['C3'].font = Font(color=Color(indexed=4)) # 按索引取预定义颜色
ws['D4'].font = Font(size=100)
ws['E5'].font = Font(name='微软雅黑')
wb.save('test.xlsx')
wb.close()
效果
预定义颜色
from openpyxl import Workbook
from openpyxl.styles import Font, Color
wb = Workbook()
ws = wb.active
ws['A1'] = 'AAAAA'
ws['B2'] = 'BBBBB'
ws['C3'] = 'CCCCC'
ws['A1'].font = Font(color='FF0000') # HEX定义红色
ws['B2'].font = Font(color=Color(indexed=32)) # 按索引取预定义颜色
ws['C3'].font = Font(color=Color(theme=6, tint=0.5)) # 按主题取
wb.save('test.xlsx')
wb.close()
效果
边框参数
参数 | 含义 | 取值 |
---|---|---|
bottom | 下框线 | Side |
diagonal | 对角框线样式 | Side |
diagonalDown | 是否出现对角框线_斜下框线 | bool |
diagonalUp | 是否出现对角框线_斜上框线 | bool |
end | Side | |
horizontal | Side | |
left | 左框线 | Side |
outline | bool | |
right | 右框线 | Side |
start | Side | |
top | 上框线 | Side |
vertical | Side |
代码
from openpyxl import Workbook
from openpyxl.styles import Side, Border
wb = Workbook()
ws = wb.active
side = Side(border_style='thin', color='FF0000')
cell = ws['A1']
cell.border = Border(diagonal=side, diagonalDown=True, diagonalUp=True) # 对角框线
cell = ws['B2']
cell.border = Border(top=side, bottom=side, left=side, right=side) # 上下左右框线
wb.save('test.xlsx')
wb.close()
效果
线条参数
参数 | 含义 | 取值 |
---|---|---|
border_style | 样式的别名 | 虚线hair 线点点dashDotDot 线点dashDot 细实线thin 中虚线mediumDashed 斜线点DashDot 点dotted 虚线dashed 中实线medium 粗实线thick 中线点mediumDashDot 双划线double 中线点点mediumDashDotDot |
color | 颜色 | Color |
style | 样式 | 同上border_style |
代码
from openpyxl import Workbook
from openpyxl.styles import Side, Border
from openpyxl.utils import get_column_letter
wb = Workbook()
ws = wb.active
border_styles = ['hair', 'dashDotDot', 'dashDot', 'thin', 'mediumDashed', 'slantDashDot', 'dotted', 'dashed', 'medium',
'thick', 'mediumDashDot', 'double', 'mediumDashDotDot']
for i, border_style in enumerate(border_styles):
row = 2 * (i + 1)
column = 2 + i
cell = ws.cell(row=row, column=column, value=border_style)
side = Side(border_style=border_style, color='FF0000')
cell.border = Border(top=side, left=side, right=side, bottom=side)
ws.row_dimensions[row].height = 14.4 * 1.5 # 行高
ws.column_dimensions[get_column_letter(column)].width = 1.5 * len(border_style) # 列宽
wb.save('test.xlsx')
wb.close()
效果
设置有值的单元格框线,其余留白
容易失效,慎用
from openpyxl import Workbook
from openpyxl.styles import Side, Border
def set_border(ws, side=None, blank=True):
"""设置有值的单元格框线,其余留白
:param ws: 工作表
:param side: 框线样式,默认为黑色实线
:param blank: 是否留白
:return:
"""
wb = ws._parent
side = side if side else Side(border_style='thin', color='000000')
for cell in ws._cells.values():
cell.border = Border(top=side, bottom=side, left=side, right=side)
if blank:
white = Side(border_style='thin', color='FFFFFF')
wb._borders.append(Border(top=white, bottom=white, left=white, right=white))
wb._cell_styles[0].borderId = len(wb._borders) - 1
if __name__ == '__main__':
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws.merge_cells('A1:J2')
ws['A1'] = 'Merge'
ws['A1'].alignment = Alignment(horizontal='center', vertical='center')
ws._current_row = 2
for i in range(1, 26):
ws.append([i] * 10)
side = Side(border_style='thin', color='FF0000')
set_border(ws, side)
wb.save('test.xlsx')
wb.close()
效果
参数 | 含义 | 取值 |
---|---|---|
fill_type | 填充类型 | 不指定则无效, 取值看下方 |
fgColor | 前景色 | openpyxl.styles.colors.Color |
bgColor | 背景色 | openpyxl.styles.colors.Color |
start_color | 开始颜色 | openpyxl.styles.colors.Color |
end_color | 结束颜色 | openpyxl.styles.colors.Color |
patternType | 填充类型 | {‘darkUp’, ‘lightTrellis’, ‘darkHorizontal’, ‘darkGray’, ‘lightHorizontal’, ‘darkGrid’, ‘lightUp’, ‘darkDown’, ‘darkTrellis’, ‘lightGrid’, ‘lightGray’, ‘lightVertical’, ‘gray125’, ‘gray0625’, ‘mediumGray’, ‘lightDown’, ‘darkVertical’, ‘solid’} |
from openpyxl import Workbook
from openpyxl.styles import PatternFill
wb = Workbook()
ws = wb.active
cell = ws['A1']
cell.value = 'Hello'
cell.fill = PatternFill(fill_type='solid', start_color='DDDDDD', end_color='DDDDDD')
wb.save('test.xlsx')
wb.close()
效果
参数 | 含义 | 取值 |
---|---|---|
horizontal | 水平对齐 | 两端对齐justify 跨列居中centerContinuous 靠右(缩进)right 居中center 常规general 填充fill 分散对齐(缩进)distributed 靠左(缩进)left |
indent | 缩进 | float |
justifyLastLine | bool | |
readingOrder | 文字方向 | float 0根据内容 1总是从左到右 2总是从右到左 |
relativeIndent | float | |
shrinkToFit | 缩小字体填充 | bool |
shrink_to_fit | 缩小字体填充 | bool |
textRotation | 文本方向 | [0, 180] |
vertical | 垂直对齐 | 两端对齐justify 居中center 靠上top 靠下bottom 分散对齐distributed |
wrapText | 自动换行 | bool |
wrap_text | 自动换行 | bool |
from openpyxl import Workbook
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws['A1'] = '标题'
ws['A1'].alignment = Alignment(textRotation=45) # 文字旋转45度
ws['A2'] = 1
ws['A2'].alignment = Alignment(horizontal='center') # 水平居中
ws['A3'] = '\n1\n'
ws['A3'].alignment = Alignment(vertical='center', wrap_text=True) # 垂直居中,自动换行
ws['A4'] = 'Hello World'
ws['A4'].alignment = Alignment(shrink_to_fit=True) # 缩小字体填充
wb.save('test.xlsx')
wb.close()
效果
from openpyxl import Workbook
from openpyxl.styles import Border, Side, PatternFill, Font, Alignment
def apply_style(cell, font=None, fill=None, border=None, alignment=None, **kwargs):
"""应用样式
:param cell: 单元格
:param font: 字体
:param fill: 填充
:param border: 边框
:param alignment: 对齐
"""
if font:
cell.font = font
if fill:
cell.fill = fill
if border:
cell.border = border
if alignment:
cell.alignment = alignment
for k, v in kwargs.items():
setattr(cell, k, v)
wb = Workbook()
ws = wb.active
cell = ws['A1']
cell.value = '标题'
thin = Side(border_style='thin', color='000000')
double = Side(border_style='double', color='ff0000')
apply_style(
ws['A1'],
font=Font(bold=True),
fill=PatternFill('solid', fgColor='DDDDDD'),
border=Border(top=double, left=thin, right=thin, bottom=double),
alignment=Alignment(horizontal='center', vertical='center'),
)
wb.save('test.xlsx')
wb.close()
效果
官方文档:批量应用样式只能用在文件关闭后,否则需要逐单元格应用
本人没成功过,有成功的朋友评论区留言~
from openpyxl import Workbook
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
for i in range(1, 6):
ws.append([i] * 5)
col = ws.column_dimensions['A']
col.font = Font(bold=True)
row = ws.row_dimensions[5]
row.font = Font(underline='single')
wb.save('test.xlsx')
wb.close()
自己实现,缺点是要有值才会生效,建议结合 ws._current_row
将需要单独设置样式的存起来,填完所有值后再统一设置样式
from openpyxl import Workbook
from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill, Alignment
def apply_style(cell, font=None, fill=None, border=None, alignment=None, **kwargs):
"""应用样式
:param cell: 单元格
:param font: 字体
:param fill: 填充
:param border: 边框
:param alignment: 对齐
"""
if font:
cell.font = font
if fill:
cell.fill = fill
if border:
cell.border = border
if alignment:
cell.alignment = alignment
for k, v in kwargs.items():
setattr(cell, k, v)
def apply_batch_style(ws, min_row=None, max_row=None, min_col=None, max_col=None,
font=None, fill=None, border=None, alignment=None, **kwargs):
"""批量应用样式
:param ws: 工作表
:param min_row: 起始行,从1开始
:param max_row: 终止行
:param min_col: 起始列,从1开始
:param max_col: 终止列
:param font: 字体
:param fill: 填充
:param border: 边框
:param alignment: 对齐
"""
for row in ws.iter_rows(min_row, max_row, min_col, max_col):
for cell in row:
apply_style(cell, font=font, fill=fill, border=border, alignment=alignment, **kwargs)
wb = Workbook()
ws = wb.active
for i in range(1, 6):
ws.append([i] * 5)
# thin = Side(border_style='thin', color='000000')
# double = Side(border_style='double', color='ff0000')
# apply_batch_style(
# ws,
# font=Font(bold=True),
# fill=PatternFill('solid', fgColor='DDDDDD'),
# border=Border(top=double, left=thin, right=thin, bottom=double),
# alignment=Alignment(horizontal='center', vertical='center')
# ) # 全局应用样式
apply_batch_style(ws, max_row=1, font=Font(bold=True)) # 首行加粗
apply_batch_style(ws, max_col=1, font=Font(color='FF0000')) # 首列红色
wb.save('test.xlsx')
wb.close()
效果
容易失效,慎用
from openpyxl import Workbook
def set_default_style(wb, font=None, fill=None, border=None, alignment=None):
"""设置默认样式
:param wb: 工作簿
:param font: 字体
:param fill: 填充
:param border: 边框
:param alignment: 对齐
"""
if font:
wb._fonts.append(font)
for _cell_style in wb._cell_styles:
_cell_style.fontId = len(wb._fonts) - 1
if fill:
wb._fills.append(fill)
for _cell_style in wb._cell_styles:
_cell_style.fillId = len(wb._fills) - 1
if border:
wb._borders.append(border)
for _cell_style in wb._cell_styles:
_cell_style.borderId = len(wb._borders) - 1
if alignment:
wb._alignments.append(alignment)
for _cell_style in wb._cell_styles:
_cell_style.alignmentId = len(wb._alignments) - 1
if __name__ == '__main__':
from openpyxl.styles import Font, PatternFill, Side, Border, Alignment
wb = Workbook()
ws = wb.active
# 设置默认样式
font = Font(name='等线')
fill = PatternFill('solid', fgColor='DDDDDD')
side = Side(border_style='thin', color='000000')
border = Border(top=side, bottom=side, left=side, right=side)
alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)
set_default_style(wb, font, fill, border, alignment)
# 设置完样式后再填值
ws.merge_cells('A1:J2')
ws['A1'] = 'Merge'
ws._current_row = 2
for i in range(1, 26):
ws.append([i] * 10)
wb.save('test.xlsx')
wb.close()
效果
from openpyxl import Workbook
from openpyxl.styles import Border, Side, PatternFill, Font, GradientFill, Alignment
wb = Workbook()
ws = wb.active
ws.merge_cells('B2:F4')
top_left_cell = ws['B2']
top_left_cell.value = 'My Cell'
thin = Side(border_style='thin', color='000000')
double = Side(border_style='double', color='ff0000')
top_left_cell.border = Border(top=double, left=thin, right=thin, bottom=double) # 边框
top_left_cell.fill = PatternFill('solid', fgColor='DDDDDD') # 图案填充
top_left_cell.fill = GradientFill(stop=('000000', 'FFFFFF')) # 渐变填充
top_left_cell.font = Font(b=True, color='FF0000') # 字体
top_left_cell.alignment = Alignment(horizontal='center', vertical='center') # 垂直水平居中
wb.save('test.xlsx')
wb.close()
效果
冻结首行:Worksheet.freeze_panes = topLeftCell
,如 ws.freeze_panes = 'A2' # 冻结首行
from openpyxl import Workbook
from openpyxl.styles import Alignment
wb = Workbook()
ws = wb.active
ws.merge_cells('A1:J2')
ws['A1'] = '合并单元格'
ws['A1'].alignment = Alignment(horizontal='center', vertical='center')
ws._current_row = 2 # 修改当前行
for i in range(1, 100):
ws.append([i] * 10)
ws.freeze_panes = 'A3'
wb.save('test.xlsx')
wb.close()
效果
import copy
from openpyxl import Workbook
from openpyxl.styles import Font
def copy_style(style, **kwargs):
"""复制样式"""
new_style = copy.deepcopy(style)
for k, v in kwargs.items():
setattr(new_style, k, v)
return new_style
wb = Workbook()
ws = wb.active
font = Font(name='等线')
bold_font = copy_style(font, bold=True)
ws['A1'] = '标题'
ws['A1'].font = font
ws['A2'] = '标题'
ws['A2'].font = bold_font
wb.save('test.xlsx')
wb.close()
含义 | 参数 | 取值 |
---|---|---|
最大行数 | ws.max_row | int |
最大列数 | ws.max_column | int |
最小行数 | ws.min_row | int |
最小列数 | ws.min_column | int |
选中单元格 | selected_cell | str |
当前行 | ws._current_row | int |
删除工作表:Workbook.remove()
from openpyxl import Workbook
wb = Workbook() # 创建新的工作簿
wb.create_sheet('Sheet1') # 在末尾创建工作表
wb.create_sheet('Sheet2') # 在末尾创建工作表
for i, name in enumerate(wb.sheetnames):
print(name)
if i == 0: # 至少有一张工作表
continue
ws = wb[name]
wb.remove(ws)
# wb.remove_sheet(ws) # 效果同上
# del ws # 效果同上
wb.save('test.xlsx')
wb.close()
默认行高14.4,列宽8.11
默认字体宋体,字号11
遍历输入数字、字母、汉字
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = '数字'
data = ['1' * i for i in range(1, 101)]
ws.append(data)
ws = wb.create_sheet('字母')
data = ['a' * i for i in range(1, 101)]
ws.append(data)
ws = wb.create_sheet('英文标点')
data = ['!' * i for i in range(1, 101)]
ws.append(data)
ws = wb.create_sheet('汉字')
data = ['我' * i for i in range(1, 101)]
ws.append(data)
ws = wb.create_sheet('中文标点')
data = ['!' * i for i in range(1, 101)]
ws.append(data)
wb.save('test.xlsx')
wb.close()
手动全选,自动调整列宽,保存
计算出对应比例
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
wb = load_workbook('test.xlsx')
scale = {}
for name in wb.sheetnames:
ws = wb[name]
_scale = {}
for i in range(1, 101):
length = len(str(ws.cell(1, i).value))
width = ws.column_dimensions[get_column_letter(i)].width
_scale[length] = width
scale[name] = _scale
for k, v in scale.items():
print(k, v)
# 数字 {1: 2.5546875, 2: 3.5546875, 3: 4.5546875, 4: 5.5546875, 5: 6.5546875, 6: 7.5546875, 7: 8.5546875, 8: 9.5546875, 9: 10.5546875}
# 字母 {1: 2.5546875, 2: 3.5546875, 3: 4.5546875, 4: 5.5546875, 5: 6.5546875, 6: 7.5546875, 7: 8.5546875, 8: 9.5546875, 9: 10.5546875}
# 英文标点 {1: 2.5546875, 2: 3.5546875, 3: 4.5546875, 4: 5.5546875, 5: 6.5546875, 6: 7.5546875, 7: 8.5546875, 8: 9.5546875, 9: 10.5546875}
# 汉字 {1: 3.5546875, 2: 5.5546875, 3: 7.5546875, 4: 9.5546875, 5: 11.6640625, 6: 13.88671875, 7: 16.109375, 8: 18.33203125, 9: 20.44140625}
# 中文标点 {1: 3.5546875, 2: 5.5546875, 3: 7.5546875, 4: 9.5546875, 5: 11.6640625, 6: 13.88671875, 7: 16.109375, 8: 18.33203125, 9: 20.44140625}
# 对应关系
s_ascii = scale['数字']
s_utf8 = scale['汉字']
for i in range(2, len(s_ascii) - 1):
pre = i - 1
print(s_ascii[i] - s_ascii[pre], s_utf8[i] - s_utf8[pre])
观察得到,数字、字母、英文标点为一个类型(ASCII),汉字、中文标点为一个类型(UTF-8、Unicode)。
自动调整列宽后,第一个ASCII字符为2.5546875,随后每个增加 1 - 1.1133,约 1.1
自动调整列宽后,第一个Unicode字符为3.5546875,随后每个增加 2 - 2.2223,约 2.2
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。