文章目录

  • 简介
  • 安装
  • 初试
  • 读写数据
  • 插入图片
  • 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()

效果

推荐阅读:

  1. 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()

效果

详细阅读:

  1. Number format codes
  2. 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()

效果

  1. 免费可商用字体

颜色

预定义颜色

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

参考文献

  1. openpyxl Documentation
  2. openpyxl issue
  3. Python Openpyxl Tutorial
  4. Openpyxl column widths and row heights
  5. openpyxl - adjust column width size
  6. Python最好的Excel第三方库——xlwings快速上手

Python Excel第三方库——openpyxl相关推荐

  1. Python的第三方库openpyxl

    Python的第三方库openpyxl在Pypi上的地址:https://pypi.org/project/openpyxl/ openpyxl是一个用于读写Excel 2010 xlsx文件的Pyt ...

  2. python可以处理多大的数据_科多大数据之Python基础教程之Excel处理库openpyxl详解...

    原标题:科多大数据之Python基础教程之Excel处理库openpyxl详解 科多大数据小课堂来啦~Python基础教程之Excel处理库openpyxl详解 openpyxl是一个第三方库,可以处 ...

  3. python的excell库_扣丁学堂Python基础教程之Excel处理库openpyxl详解

    扣丁学堂Python基础教程之Excel处理库openpyxl详解 2018-05-04 09:49:49 3197浏览 openpyxl是一个第三方库,可以处理xlsx格式的Excel文件.pipi ...

  4. Python常用第三方库

    Python常用第三方库 一. 文件读写 二.网络抓取和解析 三.数据库连接 四.数据清洗转换 五.数据计算和统计分析 六.自然语言处理和文本挖掘 七.图像和视频处理 八.音频处理 九.数据挖掘/机器 ...

  5. Python常用第三方库——简介及下载地址

    Python常用第三方库 可以在  The Python Package Index (PyPI)  软件库(官网主页:https://pypi.org/  )查询.下载 和 发布 Python包或库 ...

  6. python升级第三方库_python一键升级所有第三方库

    import pip from subprocess import call for dist in pip.get_installed_distributions(): call("pip ...

  7. 【详解】Python数据分析第三方库分析

    Python数据分析第三方库分析 目录 Python数据分析第三方库分析 @常用库下载地址 1 Numpy 2 Matplotlib 3 Pandas 4 SciPy 5 Scikit-Learn 6 ...

  8. Python的第三方库xlrd

    Python的第三方库xlrd在Pypi上的地址:https://pypi.org/project/xlrd/ xlrd是一个用于读取xls格式的Excel文件的Python库,当前版本为2.0.1, ...

  9. Python的第三方库xlwt

    Python的第三方库xlwt在Pypi上的地址:https://pypi.org/project/xlwt/ xlwt是一个用于创建xls格式的Excel文件的Python库,当前版本为1.3.0, ...

最新文章

  1. Apache无法启动解决 the requested operation has failed
  2. linux中的线程函数
  3. 小程序服务器七牛云,基于七牛云 API 开发的微信小程序 SDK
  4. jquery源码--merge grep type trim
  5. javascript原型_在JavaScript中冻结原型时会发生什么
  6. 基于matlab的pcb焊盘,EDA复习题
  7. 使用Linux好还是unix好
  8. Android手机怎么找回微信好友,安卓手机微信怎么找回删除的好友?专业靠谱!...
  9. UI自动化报错Can not connect to the Service解决方案
  10. css改变权重,1. CSS 权重
  11. 计算机视觉论文-2021-11-03
  12. JetChat-简仿微信聊天应用
  13. 养老保险个人帐户说明[南京]
  14. motion_primitive_library导航源码阅读笔记
  15. jquery easyui datagrid 列自适应窗口宽度
  16. 【JS数组 习题练习】
  17. 不同范数下的余弦定理_什么是绝对矩阵范数?
  18. 2.跟我走吧,现在就出发
  19. mysql基础架构(一条update语句如何执行)
  20. ABCD四个人说真话的概率都是1/3。假如A声称B否认C说D是说谎了,那么D说过的那句话真话的概率是多少...

热门文章

  1. apple watch se2 和 apple watch s7选哪个 苹果手表 se2 和 苹果手表 s7 对比
  2. 区块链或是“疫苗护照”国际互认的答案
  3. X计算器和PA私密相册常见问题汇总
  4. 微信小程序学习笔记-自定义组件
  5. 您知道吗?在网络运维行业 nVisual=Excel+Visio+CAD+GIS
  6. 微信小程序之底部栏tabBar
  7. 阿里达摩盘:如何进行渠道投放分析、投放漏斗分析、投放人群诊断?
  8. 微信小程序 列表渲染多层嵌套循环
  9. Linux虚拟机关闭防火墙
  10. 基于Ace的在线编辑器