真正的勇士,敢于直面银行卡上的余额,敢于正视磅秤上的数字。

表格数据是最常见的数据类型,Excel是日常办公中最常接触的文件。

上一章提过Python可以通过openpyxl模块处理Excel文件。

其实Python处理Excel的三方模块主要有这几个:xlrd、xlwt和xlutils,支持读写Excel文件。

openpyxl,支持读写和修改OpenXML格式的Excel文件。

xlswriter,支持写文件,以及更多Excel功能特性。

pandas,底层依赖xlrd和xlwt读写Excel文件,处理数据神器。

pywin32,调用Win32 API操作文件,只适用于Windows。

xlwings,可理解为pywin32的多平台加强版,有商业版支持。

简单做个对比分析:第1类中3个模块,属于同一作者的开源项目,目前已停更,不建议直接使用。

pywin32和xlwings基于原生Excel软件提供服务,需提前安装软件,读写性能和功能最佳,xlwings还有商业版本支持。

pandas侧重数据分析,Excel文件读写只是其数据输入和输出部分。

openpyxl不需要依赖Excel功能,直接读写OpenXML内容,兼容性好。

xlswriter侧重写Excel文件,支持VBA等更多特性。

建议的使用场景:如果企业内大量使用Excel,并用了很多如VBA宏的特性,建议用xlwings。一方面功能全,另一方面可以采买商业付费版支持。

对于普通Excel文件自动处理,建议用openpyxl,大部分情况下够用。

GB级以下的数据分析,建议用pandas,后续会单独出一个数据分析系列来介绍它。

本文重点介绍openpyxl的使用,它足够应付大部分人日常的表格自动化处理场景。

日常处理Excel文件,最常见的应用场景有3类:读写Excel文件

合并、分割文档数据

报表自动化,批量生成图表

模块安装:pip install openpyxl

基本使用

Excel表格文件中主要元素有这几个:sheet(工作表):一个Excel文件可以有多个sheet。

row/col(行和列),iter_rows()和iter_cols()可以返回所有行和列。

cell(单元格):和Excel一样用sheet['A1']表示,注意行列都以1开始。

formulae(公式):可以为单元格设置计算公式,和Excel概念一致。

charts(图表):比如饼图、柱状图等。

style(样式):支持自定义样式,以及条件格式化等。

image(图片),支持pillow的图像处理。

打开Excel文件

import pathlib

import datetime

from openpyxl import load_workbook

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

in_path = path.joinpath('input.xlsx')

wb = load_workbook(in_path, read_only=True)

for name in wb.sheetnames:

ws = wb[name]

print(f'{name} 表有 {ws.max_row-ws.min_row+1} 行, {ws.max_column-ws.min_column+1} 列.')

读取Excel文件内的数据

import pathlib

import datetime

from openpyxl import load_workbook

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

in_path = path.joinpath('input.xlsx')

wb = load_workbook(in_path)

ws = wb[wb.sheetnames[0]] # 第一个工作表

# 操作单列

for cell in ws["A"]:

print(cell.value)

# 操作单行

for cell in ws["1"]:

print(cell.value, end='\t')

# 操作多列

for column in ws['A:C']:

for cell in column:

print(cell.value)

# 操作多行

for row in ws['1:3']:

for cell in row:

print(cell.value, end='\t')

print()

# 指定范围

for row in ws['A1:C3']:

for cell in row:

print(cell.value)

# 所有行

for row in ws.iter_rows():

for cell in row:

print(cell.value)

# 所有列

for column in ws.iter_cols():

for cell in column:

print(cell.value)

创建Excel文件

import pathlib

import datetime

from openpyxl import Workbook

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

out_path = path.joinpath('004excel_basic.xlsx')

sheet_path = path.joinpath('004excel_sheet.xlsx')

wb = Workbook()

ws = wb.active # 找当前Sheet

ws['A1'] = 42

ws.append([1, 2, 3]) # 添加行

ws['A2'] = datetime.datetime.now()

wb.save(out_path)

# 创建第二个sheet

wb.create_sheet('sheet2')

ws = wb['sheet2']

ws.title = '第二个工作表'

ws.sheet_properties.tabColor = "FF0000"

# 增加一整行数据

ws.append([1, 2, 3, datetime.datetime.now()])

ws.cell(row=1, column=3, value=10)

# 获取cell方式一

d1 = ws.cell(row=1, column=4)

# 获取cell方式二

d2 = ws['D1']

print(d1==d2)

print(type(d2.value))

wb.save(sheet_path)

设置单元格样式

单元格样式可以用NumberFormat(数据格式)、Alignment(对齐)、Font(字体)、Border(边框)、PatternFill(填充)、Protection(保护)等来设置。

也可以通过NamedStyle自定义样式,重复应用到单元格。

此外,通过row_dimensions和column_dimensions可以设置整行/整列的样式。

import pathlib

import datetime

from openpyxl import Workbook

from openpyxl.styles import numbers, Font, GradientFill, PatternFill, Border, Side, Alignment, Protection

from openpyxl.styles import NamedStyle

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

out_path = path.joinpath('004excel_style.xlsx')

wb = Workbook()

ws = wb.active

ws.cell(row=1, column=1, value='微软雅黑').font = Font(name='微软雅黑', size=18, bold=True, color='123456')

ws.cell(row=2, column=1, value='居中对齐').alignment = Alignment(horizontal='center', vertical='center')

ws.cell(row=3, column=1, value='填充渐变色').fill = GradientFill(stop=['FF0000', '0000FF'])

ws.cell(row=4, column=1, value='设置边线').border = Border(left=Side(border_style='thin', color='123456'), right= Side(border_style='thick', color='FF0000'))

ws.cell(row=5, column=1, value='受保护的').protection = Protection(locked=True, hidden=True)

ws.cell(row=6, column=1, value=0.88).number_format =numbers.FORMAT_PERCENTAGE

ws.column_dimensions['A'].width = 80 # 修改列宽

# 设置整行

row = ws.row_dimensions[4]

row.font = Font(name='宋体', size=30, italic=True, color='FF0000')

# 设置整列

column = ws.column_dimensions["B"]

column.fill = PatternFill("solid", fgColor="1874CD")

# 自定义样式

my_style = NamedStyle(name='my_style',

font=Font(name='宋体',size=12, color='FF000000'),

fill=PatternFill(fill_type='solid', fgColor="FFDAB9"),

border=Border(top=Side(border_style='thin', color='FF000000')),

alignment=Alignment(horizontal='left',vertical='center'))

ws['B4'] = '自定义样式'

ws['B4'].style=my_style

wb.save(out_path)

合并单元格合并单元格:merge_cells()

解除合并:unmerge_cells()

注意:对于没有合并过单元格的位置调用unmerge_cells()会出错;此外合并的单元格顺序是从左上角到右下角。

import pathlib

import datetime

from openpyxl import Workbook

from openpyxl.styles import numbers, Font, GradientFill, Border, Side, Alignment, Protection

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

out_path = path.joinpath('004excel_cell_merge.xlsx')

wb = Workbook()

ws = wb.active

# 合并,必须是从左上角,到右下角的顺序

ws.merge_cells('A3:D5')

ws.merge_cells('A7:D10')

# 合并后以起点为代表读写值,其他的cell都被设置为只读

ws['A3']='test'

# 解除合并

ws.unmerge_cells('A7:D10')

# 也可以用起止行列数字来选取合并区域

ws.merge_cells(start_row=12,start_column=11,end_row=15,end_column=14)

ws['K12']='合并过'

ws.unmerge_cells(start_row=12,start_column=11,end_row=15,end_column=14)

wb.save(out_path)

图表和公式应用

openpyxl支持的图表都在openpyxl.chart包中,比如直方图、饼图、折线图等。

可以直接把单元格的值设置为公式,在Excel软件中可以获得结果,但openpyxl并不支持公式的计算。

如果生成的xlsx文件被Excel软件打开过,这时公式的计算结果会缓存在文件中,这时用openpyxl打开文件时候,增加一个data_only=True参数,也可以读取到计算结果。

import pathlib

import datetime

from openpyxl import Workbook

from openpyxl.chart import BarChart, PieChart, LineChart, Reference

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

out_path = path.joinpath('004excel_graph.xlsx')

wb = Workbook()

ws = wb.active

# 装载数据

data = [

('月份', '产品A销量', '产品B销量'),

(1, 100, 200),

(2, 106, 100),

(3, 120, 200),

(4, 180, 100),

(5, 200, 300),

(6, 280, 400),

(7, 400, 200),

(8, 500, 800),

(9, 600, 1000),

(10, 800, 300),

]

for d in data:

ws.append(d)

# 用Python做些统计

ws['A12'] = '汇总累加'

ws['B12'] = sum([d[1] for i, d in enumerate(data) if i > 0])

ws['C12'] = sum([d[2] for i, d in enumerate(data) if i > 0])

# 用公式统计

ws['A13'] = '公式累加'

ws['B13'] = '=SUM(B2:B11)'

ws['C13'] = '=SUM(C2:C11)'

# 增加一列总销量

ws['D1'] = '当月总销量'

for i in range(2, 13):

ws[f'D{i}'] = ws[f'C{i}'].value + ws[f'B{i}'].value

# 列状图

ct_bar= BarChart()

ct_bar.type = "col" # 列状图

ct_bar.style = 10

ct_bar.title = "销量柱状图"

ct_bar.y_axis.title = '销量'

ct_bar.x_axis.title = '月份'

d_ref = Reference(ws, min_col=2, min_row=1, max_row=11, max_col=3)

series = Reference(ws, min_col=1, min_row=2, max_row=11)

ct_bar.add_data(d_ref, titles_from_data=True)

ct_bar.set_categories(series)

ws.add_chart(ct_bar, 'A15')

# 饼图

ct_pie = PieChart()

ct_pie.title = "产品销量占比"

d_ref = Reference(ws, min_col=2, min_row=12, max_col=3)

series = Reference(ws, min_col=2, min_row=1, max_col=3)

ct_pie.add_data(d_ref, titles_from_data=True)

ct_pie.set_categories(series)

ct_pie.splitType='val'

ws.add_chart(ct_pie, 'I15')

# 一个图两个轴

ct_bar = BarChart()

d_ref = Reference(ws, min_col=2, min_row=1, max_row=11, max_col=3)

ct_bar.add_data(d_ref, titles_from_data=True)

ct_bar.x_axis.title = '月份'

ct_bar.y_axis.title = '产品AB销量'

ct_bar.y_axis.majorGridlines = None

ct_bar.title = '销量分析'

ct_line = LineChart()

d_ref = Reference(ws, min_col=4, min_row=1, max_row=11)

ct_line.add_data(d_ref, titles_from_data=True)

ct_line.y_axis.axId = 200 # 不为空即可

ct_line.y_axis.title = '总销量'

# 让线条和第一图的最大值相交

ct_line.y_axis.crosses = 'max'

ct_bar += ct_line # 只支持+=赋值,不能直接+

ws.add_chart(ct_bar, 'A31')

wb.save(out_path)

插入图像

openpyxl的图像处理基于PIL.Image。

PIL.Image的宽和高单位默认使用Pixel(像素),如果需要映射到Excel中的位置,可以用pixels_to_EMU()转换。

import pathlib

from openpyxl import Workbook, load_workbook

from openpyxl.drawing.image import Image

from openpyxl.drawing.spreadsheet_drawing import AbsoluteAnchor

from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D

from openpyxl.utils.units import pixels_to_EMU as p2e

path = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/004excel')

out_path = path.joinpath('004excel_image.xlsx')

img_path = path.joinpath('image.jpg')

wb = Workbook()

ws = wb.active

img = Image(img_path)

img.width /= 2

img.height /= 2

h, w = img.height, img.width

# 绝对定位图片

position = XDRPoint2D(p2e(800), p2e(800))

size = XDRPositiveSize2D(p2e(h), p2e(w))

img.anchor = AbsoluteAnchor(pos=position, ext=size)

ws.add_image(img)

# 单元格定位

img = Image(img_path)

size = (90, 90)

img.width, img.height = size

ws.row_dimensions[3].height=90

ws.column_dimensions['B'].width=90

ws.add_image(img, 'B3')

wb.save(out_path)

总结

本文主要介绍了使用openpyxl模块处理Excel文件,包括基本的Excel文件读写、单元格样式处理、图表生成和图像结合等。

用Excel应对日常工作中的小规模数据足以。

比如实践应用中有一个“多门店加盟品牌数据统计”的案例,其中正好用到了上面的各项知识点。

案例说明:以Python和openpyxl应用实践为主。

提供解决问题思路,实战中可直接应用。

后续“数据分析专题”会介绍Pandas等数据分析工具,一个实战应用更灵活的模块。

想了解的可以入群获取,前100名免费。

excel数据导入python后不对齐_Python处理Excel文件的实用姿势相关推荐

  1. excel数据导入python后不对齐_如何将excel文件导入python并检查列是否重复?

    我从一个只包含7000多个不同选择的系统收集了一些数据,我希望将这些数据导入python,并将列a(所有数据)作为一个列表处理,然后检查重复项.在 期望的结果是将所有重复的选择写入一个txt文件.在 ...

  2. 用java把excel数据导入oracle日期转换,Java代码兑现excel数据导入到Oracle

    Java代码实现excel数据导入到Oracle 1.首先需要两个jar包jxl.jar,ojdbc.jar(注意版本,版本不合适会报版本错误) 2.代码: import java.io.File; ...

  3. oracle 将excel数据导入多个表,5种从Excel数据导入Oracle方法

    最近同事遇到了每天手工导入Excel数据到Oracle的问题,他目前的操作是使用PL/SQL Developer中的复制粘贴方法,这样每天都需要进行手工的操作,很明显长期下来的工作量是比较大的,于是找 ...

  4. oracle录入excel无sql,Excel数据导入到oracle(待上传的Excel表格;oracle的数据表;PLSQL)...

    一.打开pl/sql,如图所示界面,点击菜单栏中的T00LS ODBC Imtorper,打开ODBC Importer选项框​ T00LS ODBC Imtorper 二.在Data fromODB ...

  5. python打开音频文件_Python处理音频文件的实用姿势

    每天叫醒我的不是理想,是楼下广场舞的音乐. 音乐是人类的通用语言,不分国界不分种族. 抖音短视频爆火的关键因素之一,就是普通人也能便捷地使用BGM表达自我. 从感性角度看,音乐可以有很多种解释,如:音 ...

  6. c# excel导入mysql_c#将Excel数据导入到数据库的实现代码

    c#将Excel数据导入到数据库的实现代码 假如Excel中的数据如下: 数据库建表如下: 其中Id为自增字段: 代码:using System; using System.Collections.G ...

  7. python将EXCEL数据导入数据库时日期型数据变成数字并加.0的问题一行代码解决方案方案

    [问题描述]:python将EXCEL数据导入数据库时日期变成文本型数据并显示为数字格式 [解决方案] 数据源: codes: #!/usr/bin/python3 -- coding: utf-8 ...

  8. python接入excel_使用python将excel数据导入数据库过程详解

    因为需要对数据处理,将excel数据导入到数据库,记录一下过程. 使用到的库:xlrd 和 pymysql (如果需要写到excel可以使用xlwt) 直接丢代码,使用python3,注释比较清楚. ...

  9. Python实现Excel数据导入MySQL

    前言 近年来,数据分析正在改变我们的工作方式,数据分析的相关工作也越来越受到人们的青睐.很多编程语言都可以做数据分析,比如Python.B.Matlab等,Python凭借着自身无可比拟的优势,被广泛 ...

最新文章

  1. 有关任意多条曲线的拟合度算法
  2. 分布式架构的对比-IBM XIV
  3. 风控策略和模型的区别_风控模型之产品赢利分析与策略优化
  4. YII2集成GOAOP,实现面向方面编程!
  5. 《python网络数据采集》读后感 第六章:读取文档
  6. Foundation框架: 5.常用结构体知识补充
  7. windos手工扩展分区
  8. 输出素数和排序后的数组和杨辉三角
  9. 邮件代理发送功能更新和Exchange 6月份补丁更新提示
  10. const,readonly字段的取舍!
  11. 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_13使用骨架创建maven的web工程...
  12. 游戏开发--开源18---Volity|PhiloGL|impactJs|createjs|C...
  13. HW-LCD-070 7寸液晶屏 数据手册
  14. Mac怎么方便看节假日安排,添加中国法定节假日安排
  15. code review流程规范
  16. java deflate,java.util.zip.Deflater.deflate(byte[] b, int off, int len)方法示例
  17. 计算机电源供电方式,电脑主板开关电源供电方式图文介绍
  18. 微信测试号中被动消息回复的测试
  19. 开发一款系统软件的流程步骤是什么
  20. 怎么删除w7桌面计算机图标,桌面图标删除不了_Win7桌面有图标删不掉怎么办

热门文章

  1. Vue的全局事件总线实现任意组件间通信
  2. 如何将Android应用发布到Google Play(Android Market)官方市场
  3. 【笨木头Lua专栏】基础补充01:巧说table的几种构造方式
  4. Android 拍照或从相册取图片并裁剪
  5. qemu 信号线程化
  6. 第七届蓝桥杯本科B组省赛 最大比例
  7. 计算机网络跨考看,计算机网络试题第一章概述_跨考网
  8. BLUEMOON记录
  9. HP Proliant DL 360 G9部署VMware ESXI 6.7
  10. java记——玩转星星