Python Excel第三方库——openpyxl
文章目录
- 简介
- 安装
- 初试
- 读写数据
- 插入图片
- TODO:批量插入图片
- 行高列宽
- 水平垂直居中
- 遍历所有单元格
- 单元格数字格式
- 数学公式
- 合并单元格
- 折叠
- 插入和删除行、列
- 移动范围单元格
- 样式
- 默认样式
- 字体
- 颜色
- 边框
- 填充
- 对齐
- 应用样式
- 批量应用样式
- 设置默认样式
- 应用在合并单元格
- 冻结首行
- 复制样式
- 常用属性
- 删除工作表
- 图表
- 统计字符数量与列宽关系
- 参考文献
简介
纵使xlwings
很好用,也掩盖不了无法在Linux上部署的缺点。
openpyxl
是一款读、写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库,它通过操作Office Open XML实现Excel的读写。
本文openpyxl版本为3.0.6
安装
pip install openpyxl
初试
from openpyxl import Workbookwb = 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_workbookwb = load_workbook(filename='test.xlsx')
ws = wb.active
for cells in ws.rows: # 按行遍历for cell in cells:value = cell.valueprint(value, end=' ')print()
插入一行数据:Worksheet.append()
from openpyxl import Workbookwb = Workbook()
ws = wb.activefirst_row = ['a', 'b', 'c'] # 首行数据
row = 1
for i, data in enumerate(first_row): # 逐个写入column = i + 1ws.cell(row, column).value = datafor 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 Imagewb = Workbook()
ws = wb.activeimg = 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 Imagewb = Workbook()
ws = wb.activeimg = 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()
效果
TODO:批量插入图片
Python xlwings插入图片
Drawing.anchor
img.anchor(cell, anchortype="oneCell")
行高列宽
import datetime
from openpyxl import Workbook
from openpyxl.styles import Alignmentwb = 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 Alignmentwb = 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 = Truei.auto_size = Truewb.save('test.xlsx')
wb.close()
效果
自动调整行高列宽(自己实现)
比例统计见下文 “统计字符数量与列宽关系”
import datetimefrom openpyxl.cell import Celldef 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: # 跳过合并单元格continuevalue = max(value.splitlines(), key=str.__len__) if value else value # 多行取最长一行for char in value: # 遍历每个字符if cell_type == datetime.datetime and char == '.': # 日期类型后面不显示breakif begin and ord(char) > 256: # 首个Unicodelength += BEGIN_UNICODEbegin = Falseif begin and ord(char) <= 256:length += BEGIN_ASCII # 首个ASCIIbegin = Falseif ord(char) > 256:length += ONE_UNICODEelse:length += ONE_ASCIIcol_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 Workbookfrom openpyxl.styles import Alignment, Fontwb = Workbook()ws = wb.activews.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 Alignmentwb = Workbook()
ws = wb.activews.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()
效果
推荐阅读:
- openpyxl.styles.alignment
遍历所有单元格
from openpyxl import Workbookwb = Workbook()
ws = wb.activefor i in range(1, 11):ws.append({i: i}) # 指定位置写入for row in ws.rows: # 按行遍历for cell in row:value = cell.valueif value:print(value)wb.save('test.xlsx')
wb.close()
或
from openpyxl import Workbookwb = Workbook()
ws = wb.activefor 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 Workbookwb = Workbook()
ws = wb.activews['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+00ws.column_dimensions['A'].width = 20 # 调整A列列宽
wb.save('test.xlsx')
wb.close()
效果
详细阅读:
- Number format codes
- Standard numeric format strings
数学公式
函数使用英文名,参数用逗号分隔
from openpyxl import Workbookwb = Workbook()
ws = wb.active
ws['A1'] = '=SUM(1, 1)'
wb.save('test.xlsx')
wb.close()
效果
查看所有函数
from openpyxl.utils import FORMULAEprint(FORMULAE)
合并单元格
- 合并单元格:
merge_cells()
- 拆分单元格:
unmerge_cells()
from openpyxl.workbook import Workbookwb = 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 openpyxlwb = 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 Workbookwb = 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 Workbookwb = 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()
样式
按功能分类:
Font
:字体,大小、颜色、下划线PatternFill
:填充,图案、颜色、渐变Border
:边框Alignment
:单元格对齐方式Protection
:保护
按作用对象分类:
- 单元格样式
- 命名样式(样式模板)
默认样式
from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Fontfont = 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, Colorwb = Workbook()
ws = wb.activews['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, Colorwb = Workbook()
ws = wb.activews['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, Borderwb = 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_letterwb = Workbook()
ws = wb.activeborder_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 + icell = 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, Borderdef set_border(ws, side=None, blank=True):"""设置有值的单元格框线,其余留白:param ws: 工作表:param side: 框线样式,默认为黑色实线:param blank: 是否留白:return:"""wb = ws._parentside = 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) - 1if __name__ == '__main__':from openpyxl.styles import Alignmentwb = Workbook()ws = wb.activews.merge_cells('A1:J2')ws['A1'] = 'Merge'ws['A1'].alignment = Alignment(horizontal='center', vertical='center')ws._current_row = 2for 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 PatternFillwb = 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 Alignmentwb = Workbook()
ws = wb.activews['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, Alignmentdef 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 = fontif fill:cell.fill = fillif border:cell.border = borderif alignment:cell.alignment = alignmentfor k, v in kwargs.items():setattr(cell, k, v)wb = Workbook()
ws = wb.activecell = 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 Fontwb = 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, Alignmentdef 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 = fontif fill:cell.fill = fillif border:cell.border = borderif alignment:cell.alignment = alignmentfor 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 Workbookdef 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) - 1if fill:wb._fills.append(fill)for _cell_style in wb._cell_styles:_cell_style.fillId = len(wb._fills) - 1if border:wb._borders.append(border)for _cell_style in wb._cell_styles:_cell_style.borderId = len(wb._borders) - 1if alignment:wb._alignments.append(alignment)for _cell_style in wb._cell_styles:_cell_style.alignmentId = len(wb._alignments) - 1if __name__ == '__main__':from openpyxl.styles import Font, PatternFill, Side, Border, Alignmentwb = 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 = 2for 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, Alignmentwb = 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 Alignmentwb = 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 copyfrom openpyxl import Workbook
from openpyxl.styles import Fontdef copy_style(style, **kwargs):"""复制样式"""new_style = copy.deepcopy(style)for k, v in kwargs.items():setattr(new_style, k, v)return new_stylewb = Workbook()
ws = wb.activefont = Font(name='等线')
bold_font = copy_style(font, bold=True)
ws['A1'] = '标题'
ws['A1'].font = font
ws['A2'] = '标题'
ws['A2'].font = bold_fontwb.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 Workbookwb = Workbook() # 创建新的工作簿
wb.create_sheet('Sheet1') # 在末尾创建工作表
wb.create_sheet('Sheet2') # 在末尾创建工作表
for i, name in enumerate(wb.sheetnames):print(name)if i == 0: # 至少有一张工作表continuews = wb[name]wb.remove(ws)# wb.remove_sheet(ws) # 效果同上# del ws # 效果同上
wb.save('test.xlsx')
wb.close()
图表
Charts
统计字符数量与列宽关系
默认行高14.4,列宽8.11
默认字体宋体,字号11
遍历输入数字、字母、汉字
from openpyxl import Workbookwb = 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_letterwb = 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] = widthscale[name] = _scalefor 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 - 1print(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
参考文献
- openpyxl Documentation
- openpyxl issue
- Python Openpyxl Tutorial
- Openpyxl column widths and row heights
- openpyxl - adjust column width size
- Python最好的Excel第三方库——xlwings快速上手
Python Excel第三方库——openpyxl相关推荐
- Python的第三方库openpyxl
Python的第三方库openpyxl在Pypi上的地址:https://pypi.org/project/openpyxl/ openpyxl是一个用于读写Excel 2010 xlsx文件的Pyt ...
- python可以处理多大的数据_科多大数据之Python基础教程之Excel处理库openpyxl详解...
原标题:科多大数据之Python基础教程之Excel处理库openpyxl详解 科多大数据小课堂来啦~Python基础教程之Excel处理库openpyxl详解 openpyxl是一个第三方库,可以处 ...
- python的excell库_扣丁学堂Python基础教程之Excel处理库openpyxl详解
扣丁学堂Python基础教程之Excel处理库openpyxl详解 2018-05-04 09:49:49 3197浏览 openpyxl是一个第三方库,可以处理xlsx格式的Excel文件.pipi ...
- Python常用第三方库
Python常用第三方库 一. 文件读写 二.网络抓取和解析 三.数据库连接 四.数据清洗转换 五.数据计算和统计分析 六.自然语言处理和文本挖掘 七.图像和视频处理 八.音频处理 九.数据挖掘/机器 ...
- Python常用第三方库——简介及下载地址
Python常用第三方库 可以在 The Python Package Index (PyPI) 软件库(官网主页:https://pypi.org/ )查询.下载 和 发布 Python包或库 ...
- python升级第三方库_python一键升级所有第三方库
import pip from subprocess import call for dist in pip.get_installed_distributions(): call("pip ...
- 【详解】Python数据分析第三方库分析
Python数据分析第三方库分析 目录 Python数据分析第三方库分析 @常用库下载地址 1 Numpy 2 Matplotlib 3 Pandas 4 SciPy 5 Scikit-Learn 6 ...
- Python的第三方库xlrd
Python的第三方库xlrd在Pypi上的地址:https://pypi.org/project/xlrd/ xlrd是一个用于读取xls格式的Excel文件的Python库,当前版本为2.0.1, ...
- Python的第三方库xlwt
Python的第三方库xlwt在Pypi上的地址:https://pypi.org/project/xlwt/ xlwt是一个用于创建xls格式的Excel文件的Python库,当前版本为1.3.0, ...
最新文章
- Apache无法启动解决 the requested operation has failed
- linux中的线程函数
- 小程序服务器七牛云,基于七牛云 API 开发的微信小程序 SDK
- jquery源码--merge grep type trim
- javascript原型_在JavaScript中冻结原型时会发生什么
- 基于matlab的pcb焊盘,EDA复习题
- 使用Linux好还是unix好
- Android手机怎么找回微信好友,安卓手机微信怎么找回删除的好友?专业靠谱!...
- UI自动化报错Can not connect to the Service解决方案
- css改变权重,1. CSS 权重
- 计算机视觉论文-2021-11-03
- JetChat-简仿微信聊天应用
- 养老保险个人帐户说明[南京]
- motion_primitive_library导航源码阅读笔记
- jquery easyui datagrid 列自适应窗口宽度
- 【JS数组 习题练习】
- 不同范数下的余弦定理_什么是绝对矩阵范数?
- 2.跟我走吧,现在就出发
- mysql基础架构(一条update语句如何执行)
- ABCD四个人说真话的概率都是1/3。假如A声称B否认C说D是说谎了,那么D说过的那句话真话的概率是多少...