python操作Excel、openpyxl 之图表,折线图、饼图、柱状图等
- 需要模块:
from openpyxl.workbook import Workbook
from openpyxl.chart import Series,LineChart, Reference
openpyxl支持利用工作表中单元格的数据,创建条形图、折线图、散点图等
步骤:
wb = Workbook()
ws = wb.create_sheet("{0}蒸汽压力记录表".format("样品名称"), 0)
从将表格中涉及的要画图的数据使用:Reference 创建一个对象
比如:我选取 data = Reference(ws, min_col=5, min_row=4, max_col=10, max_row=4)
参数含义:ws 一个活跃的sheet,数据来源。可以使用ws = wb.active 获取
其他的就是指定这个表中的行列数据了:起始行、起始列、终止行、终止列通过传入Reference对象,创建一个Series对象
创建一个Chart对象
可选择的设置Chart对象的长(drawing.height)、宽(drawing.width)、坐标位置(drawing.top、drawing.left)。
将Chart对象添加到Worksheet对象。
chart = LineChart() #图表对象
data = Reference(ws, min_col=5, min_row=4, max_col=10, max_row=4) #涉及数据
seriesObj = Series(data, title='压力') #创建series对象
chart.append(seriesObj) #添加到chart中
ws.add_chart(chart, "A6") #将图表添加到 sheet中
- 一个饼图
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference, Series
wb = load_workbook('e:\\sample.xlsx')
ws1=wb.active
wb = Workbook()
ws = wb.active
for i in range(10):
ws.append([i])
values = Reference(ws, min_col=1, min_row=1, max_col=1, max_row=10)
chart = BarChart()
chart.add_data(values)
ws.add_chart(chart, "E15")
# Save the file
wb.save("e:\\sample.xlsx")

- 说明:
enity 参数是我从数据库,通过sqlalchemy查询出来的一个实体对象,
recordList 是我每次试验产生的数据列,每个数据列30万数据左右
import sys
import uuid
import string
import json
import time
import random
import os
import base64
from openpyxl.workbook import Workbook
from openpyxl.styles import Font, Alignment, Side, Border
from openpyxl.drawing import image
from openpyxl.chart import Series,LineChart, Reference
from openpyxl.chart.axis import DateAxis
# path = os.path.dirname(os.path.dirname(__file__))
# sys.path.insert(0,path)
from Lib.Utils import Utils
class ExportReport:
def __init__(self,entity, recordList,**kwargs):
"""
:param entity: 记录对象
:param recordList: 记录["压力","电流"]列表
:param kwargs:
"""
self.entity = entity
self.record_list = recordList
self.status_all = ["未完成", "成功", "<2070kpa"]
self.data_head = ["start_time","experiment_user_name","material_name", "experiment_type","is_success", "time_cost","test_count"]
self.base_info_list = ["试验日期","试验人", "样品名称", "试验类型", "试验状态", "耗费时间","试验次数"]
self.wb = Workbook()
self.ws = self.wb.create_sheet("{0}试验记录表".format(self.entity.material_name), 0)
#生成头部所含列总数的大写字母
self.header_upper_string_list = string.ascii_uppercase[:len(self.base_info_list)]
# 水平对齐,居中对齐
self.alignment_style = Alignment(horizontal='center', vertical='center')
#定义border 边框样式
left, right, top, bottom = [Side(style='thin', color='000000')]*4
self.border_style = Border(left=left, right=right, top=top, bottom=bottom)
#定义字体
self.font_size = Font(size=9)
for col in self.header_upper_string_list :
self.ws.column_dimensions[col].width = 25
#单元格样式字体调整
def cell_set(self, cellObj, fontSzie=12, alignmentStyle=None):
alignmentStyle = alignmentStyle if alignmentStyle else self.alignment_style
cellObj.alignment = alignmentStyle #对齐方式
cellObj.font = Font(size=fontSzie, bold=True) #字体
#单元格样式字体居中
def cell_textalign_center(self,cellObj):
cellObj.alignment = self.alignment_style
#创建表头第一行
def create_row1(self):
#把1、2行所有列合并
self.ws.merge_cells(start_row=1, end_row=2, start_column=1, end_column=self.base_info_list.__len__())
#写入值
self.ws.cell(row=1, column=1).value = "{0}试验记录表".format(self.entity.material_name)
self.cell_set(self.ws['A1'], 16)
self.create_row3_4()
self.create_row7_8()
def create_row3_4(self):
for col in range(1, len(self.base_info_list)+1):
self.ws.merge_cells(start_row=3, end_row=4, start_column=col, end_column=col)
col_str = self.header_upper_string_list[col-1]+"3"
self.ws[col_str] = self.base_info_list[col-1]
self.cell_set(self.ws[col_str])
#合并 5 6 两行单元格
for col in range(1, len(self.base_info_list)+1):
self.ws.merge_cells(start_row=5, end_row=6, start_column=col, end_column=col)
def create_row7_8(self):
dataNum = ["序号", "压力", "电流"]
for col in range(1, 4):
self.ws.merge_cells(start_row=7, end_row=8, start_column=col, end_column=col)
col_str = "ABCD"[col-1]+"7"
self.ws[col_str] = dataNum[col-1]
self.cell_set(self.ws[col_str])
def timeStampToUTC8(self,timeStamp):
return time.strftime("%Y/%m/%d %H:%M:%S",time.localtime(timeStamp/1000))
def add_data(self):
#第五行开始写入数据,所有数据居中对齐,水平居中
# 字符为A/B,第五行
for i,v in enumerate(self.data_head):
cur_v = getattr(self.entity,v)
if v == "experiment_type":
cur_v = ["样品试验","参考品试验","时间/压力试验"][cur_v]
if v == "is_success":
cur_v = ["异常","计时","<2070kPa"][cur_v]
self.ws[self.header_upper_string_list[i]+"5"] = cur_v
for i in self.header_upper_string_list:
col_str = i +"5"
self.cell_textalign_center(self.ws[col_str])
for idx, data in enumerate(self.record_list[0]):
col_str = "A{}".format(9+idx)
self.ws[col_str] = idx
self.cell_textalign_center(self.ws[col_str])
col_str = "B{}".format(9 + idx)
self.ws[col_str] = data
self.cell_textalign_center(self.ws[col_str])
col_str = "C{}".format(9 + idx)
self.ws[col_str] = self.record_list[1][idx]
self.cell_textalign_center(self.ws[col_str])
self.draw_line_chart()
#画折线图
def draw_line_chart(self):
self.chart = LineChart()
self.chart.title = "压力变化记录折线图"
self.chart.style = 2
self.chart.width = 36
self.chart.height = 20
self.chart.y_axis.title = "压力kpa"
# self.chart.y_axis.crossAx = 500
# self.chart.x_axis = DateAxis(crossAx=100)
# self.chart.x_axis.number_format = '%H:%M:%S'
# self.chart.x_axis.majorTimeUnit = "days"
self.chart.x_axis.title = "序号"
#选中要画图的数据列(Y轴)
data1 = Reference(
self.ws,
min_col=2,
min_row=8,
max_col=2,
max_row=len(self.record_list[0])+8
)
seriesObj1 = Series(data1, title='压力值')
self.chart.append(seriesObj1)
# self.chart.add_data(data, titles_from_data=True)
#指定X轴选取的数据列(还可以有时间-日期格式,这儿作者就不演示了)
dates = Reference(self.ws, min_col=1, min_row=8, max_row=len(self.record_list[0])+8)
self.chart.set_categories(dates)
self.ws.add_chart(self.chart, "D7")
def draw_electric_cur(self):
self.chart = LineChart()
self.chart.title = "电流记录折线图"
self.chart.style = 2
self.chart.width = 36
self.chart.height = 20
self.chart.y_axis.title = "电流A"
# self.chart.y_axis.crossAx = 500
# self.chart.x_axis.crossAx = -5
# self.chart.x_axis = DateAxis(crossAx=100)
# self.chart.x_axis.number_format = '%H:%M:%S'
# self.chart.x_axis.majorTimeUnit = "days"
self.chart.x_axis.title = "序号"
#设定坐标系内,Y轴最大、最小值
# self.chart.y_axis.scaling.min = self.min_diff-0.1
# self.chart.y_axis.scaling.max = self.max_diff+0.1
data3 = Reference(
self.ws,
min_col=3,
min_row=8,
max_col=3,
max_row=len(self.record_list[1])+8
)
seriesObj3 = Series(data3, title='电流')
self.chart.append(seriesObj3)
dates = Reference(self.ws, min_col=1, min_row=8, max_row=len(self.record_list[1]) + 8)
self.chart.set_categories(dates)
self.ws.add_chart(self.chart, "D49")
def create(self,value=None):
if value:
self.ws.cell(row=1, column=1).value = value
self.create_row1()
self.add_data()
self.draw_line_chart()
if self.entity.experiment_type!=2:
self.draw_electric_cur()
def save(self, filename):
try:
self.wb.save(filename)
except Exception as e:
print(e)
self.wb.save(filename[:-5] + str('_' + Utils.getFileName()) + filename[-5:])
# 关闭excel
self.close()
def close(self):
self.wb.close()
class TestObj:
def __init__(self):
self.test_list = ["start_time","experiment_user_name","material_name", "experiment_type","is_success", "time_cost","test_count"]
if __name__ == '__main__':
t = TestObj()
for idx,para in enumerate(t.test_list):
t.__setattr__(para,idx)
record_list = [
[random.randrange(i,i+10) for i in range(100)],
[random.random() for j in range(150)]
]
export = ExportReport(t,record_list)
export.create()
export.save("127.xlsx")

import uuid
import string
import json
import time
import os
import base64
from openpyxl.workbook import Workbook
from openpyxl.styles import Font, Alignment, Side, Border
from openpyxl.drawing import image
from openpyxl.chart import Series,LineChart, Reference
from Lib.Utils import Utils
class ExportReport:
def __init__(self, start_time, water_temp, test_people,
sample_name, pressure_value, pressure_list,*args, **kwargs):
"""
:param start_time: 实验开始时间
:param water_temp: 水浴温度
:param test_people: 试验人
:param sample_name: 样品名称
:param pressure_value: 最终压力
:param args: 实验过程压力记录列表
:param kwargs:
"""
self.start_time = start_time
self.water_temp = str(water_temp)+' ℃'
self.test_people = test_people
self.sample_name = sample_name
self.pressure_value = pressure_value
self.all_col = 5+len(pressure_list) #一共多少列
self.pressure_record = pressure_list #第六列到最后一列的数据列表
self.image_path = kwargs.get('imgPath', None) #图片路径
#所有的数据列
self.data_list = [
self.start_time, self.water_temp,
self.test_people,self.sample_name,
self.pressure_value
]
self.data_list.extend(self.pressure_record)
self.col_list = ["开始时间", "水浴温度", "测试人", "样品名称", "最终压力值"]
# base64转化为图片
# self.bs64 = bs64
# self.img_path = Utils.change_base64_as_img(self.bs64)
self.wb = Workbook()
#self.wb.remove(self.wb["sheet"])
self.ws = self.wb.create_sheet("{0}蒸汽压力记录表".format(self.sample_name), 0)
#生成所含列总数的大写字母
self.upper_string_list = string.ascii_uppercase[:self.all_col]
# 水平对齐,居中对齐
self.alignment_style = Alignment(horizontal='center', vertical='center')
#定义border 边框样式
left, right, top, bottom = [Side(style='thin', color='000000')]*4
self.border_style = Border(left=left, right=right, top=top, bottom=bottom)
#定义字体
self.font_size = Font(size=9)
for col in self.upper_string_list:
self.ws.column_dimensions[col].width = 20
#单元格样式字体调整
def cell_set(self, cellObj, fontSzie=12, alignmentStyle=None):
alignmentStyle = alignmentStyle if alignmentStyle else self.alignment_style
cellObj.alignment = alignmentStyle
cellObj.font = Font(size=fontSzie, bold=True)
#创建表头第一行
def create_row1(self):
#把所有列合并
self.ws.merge_cells(start_row=1, end_row=1, start_column=1, end_column=self.all_col)
#写入值
# self.ws.cell(row=1, column=1).value = value
self.ws.cell(row=1, column=1).value = "{0}蒸汽压力记录表".format(self.sample_name)
# self.ws['A1'].alignment = self.alignment_style
# self.ws['A1'].font = Font(size=16, bold=True)
self.cell_set(self.ws['A1'], 16)
self.create_row2_3()
def create_row2_3(self):
#把前五列,二三行单元格合并,并写入值
for col in range(1, len(self.col_list)+1):
self.ws.merge_cells(start_row=2, end_row=3, start_column=col, end_column=col)
col_str = self.upper_string_list[col-1]+"2"
self.ws[col_str] = self.col_list[col-1]
# self.ws[col_str].alignment = self.alignment_style
# self.ws[col_str].font = Font(size=12, bold=True)
self.cell_set(self.ws[col_str])
#把第二行第六列开始到最后列合并
self.ws.merge_cells(start_row=2, end_row=2, start_column=len(self.col_list)+1, end_column=self.all_col)
col_str = self.upper_string_list[len(self.col_list)]+"2"
self.ws[col_str] = "实验过程压力记录"
# self.ws[col_str].alignment = self.alignment_style
# self.ws[col_str].font = Font(size=12, bold=True)
self.cell_set(self.ws[col_str])
#第三行第六列开始到最后列写入值
for index, col_ltr in enumerate(self.upper_string_list[len(self.col_list):]):
col_str = col_ltr+'3'
self.ws[col_str] = "第{0}次压力记录".format(index+1)
# self.ws[col_str].alignment = self.alignment_style
# self.ws[col_str].font = Font(size=12, bold=True)
self.cell_set(self.ws[col_str])
def add_data(self):
#第四行开始写入数据,所有数据居中对齐,水平居中
for index, col in enumerate(self.upper_string_list):
col_str = col+"4"
self.ws[col_str] = self.data_list[index]
# self.ws[col_str].alignment = self.alignment_style
# self.ws[col_str].font = Font(size=12, bold=True)
self.cell_set(self.ws[col_str])
#画折线图
def draw_line_chart(self):
data_col = self.ws["{0}:{1}".format(self.upper_string_list[len(self.col_list)]+"3",self.upper_string_list[-1]+"3" )]
self.chart = LineChart()
self.chart.width = 21.2
self.chart.height = 8
self.chart.style = 2 ##线条的style,Max value is 48 2 10
self.chart.title = "压力记录图"
self.chart.y_axis.title = "压力值"
self.chart.x_axis.title = "压力测量次数"
#从活动表中关联压力记录次数数据, 第六行到第10行
data = Reference(
self.ws,
min_col=len(self.col_list)+1,
min_row=4,
max_col=self.all_col,
max_row=4
)
#将数据添加到系列中
seriesObj = Series(data, title='压力')
format_str = "第{0}次记录:/n压力:{1}".format(seriesObj.xVal,seriesObj.yVal)
# seriesObj.labels
self.chart.append(seriesObj)
# self.chart.add_data(data, from_rows=False)
# style = self.chart.series[0]
# style.smooth = True
self.ws.add_chart(self.chart, "A6")
def create(self,value=None):
if value:
self.ws.cell(row=1, column=1).value = value
self.create_row1()
self.add_data()
self.draw_line_chart()
def save(self, filename):
try:
self.wb.save(filename)
except:
self.wb.save(filename[:-5] + str('_' + Utils.getFileName()) + filename[-5:])
# 关闭excel
self.close()
def close(self):
self.wb.close()
if __name__ == '__main__':
er = ExportReport(1, 2, 3, 4, 5, [17, 15, 19, 13,24])
er.create()
er.wb.save('17表.xlsx')
python操作Excel、openpyxl 之图表,折线图、饼图、柱状图等的更多相关文章
- python操作excel——openpyxl
一.概述 python操作excel各个库对比:https://www.cnblogs.com/paul-liang/p/9187503.html 官方文档:https://openpyxl.read ...
- python操作excel (openpyxl)
最近看到好几次群里有人问xlwt.wlrd的问题,怎么说呢,如果是office2007刚出来,大家用xlsx文件用不习惯,还可以理解,这都10年过去了喂,就算没有进化到office2016,还在用of ...
- RDLC报表系列(六) 多图表-折线图和柱状图
美好的一天开始了,这篇是RDLC系列的最后一篇文章,我的小项目也已经release,正在测试中. 1.新建demo3.aspx和demo3.rdlc文件 2.往rdlc文件中拖一个图标控件,在弹出的窗 ...
- python 操作excel openpyxl
1 安装 pip install openpyxl 如果装不上,请指定安装源来安装 pip install -i https://pypi.douban.com/simple openpyxl 如果e ...
- Python操作excel,及图表展示
学习:http://www.cnblogs.com/Lands-ljk/p/5444619.html
- excel在一个图表内,显示折线图和柱状图
折线图和柱状图,在同一个图表中拆分显示 一个图,设置主坐标轴 另外一个图,设置次坐标轴 拆分,通过调整纵坐标的最小值和最大值来实现 关于图表的标题,选中图表,选择布局,然后图表 ...
- Python 利用Python操作excel表格之openyxl介绍Part2
利用Python操作excel表格之openyxl介绍 by:授客 QQ:1033553122 欢迎加入全国软件测试交流qq群(群号:7156436) ## 绘图 c = LineChart() ...
- 自动化办公:python操作Excel
1.安装 -- upgrade pippython -m pip install --- install pypipip install pypi 执行python setup.py install进 ...
- Python操作excel(xlrd和xlwt)
Python操作excel表格有很多支持的库,例如:xlrd.xlwt.openpyxl.win32com,下面介绍使用xlrd.xlwt和xlutils模块这三个库不需要其他的支持,在任何操作系统上 ...
- Python 利用Python操作excel表格之openyxl介绍Part1
利用Python操作excel表格之openyxl介绍 by:授客 QQ:1033553122 欢迎加入全国软件测试交流qq群(群号:7156436),免费获取以下性能监控工具(类似Nmon精简版) ...
随机推荐
- U盘重装Win10系统视频教程
编程行业中,如你遇到非常奇怪.无法解释的问题时,通常会使用这三步骤:重启电脑.重装软件.重装系统: 作为终极大法重装系统在我们日常使用电脑中也可以说是不可避免的,比如你电脑无故运行非常卡.下软件可能中 ...
- 【Android Studio安装部署系列】十一、Android studio获取数字签名信息
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 概述 下面介绍下调试版本和发布版本获取数字签名的方法,通过以下方法可以获取到SHA1和MD5. 一般在使用分享功能,在第三方平台中创建应用 ...
- 数据结构之表(C语言实现)
抽象数据类型 (abstract data type,ADT) 抽象数据类型是一些操作的集合.抽象数据类型是数学中的定义,在ADT中,我们不关心操作是如何被实现的.因此,这可以看做是模块化的扩充.例如 ...
- .NET Core 使用NLog日志记录
前言 每个项目都会需要使用到日志功能,这对于项目上线后 出现的bug异常,能及时定位和便于后期错误分析.那我们今天来看看在.NET Core中如何使用NLog日志. NLog 什么是NLog呢? NL ...
- Dalvik 虚拟机操作码
Dalvik 虚拟机操作码 表中的vx.vy.vz表示某个Dalvik寄存器.根据不同指令可以访问16.256或64K寄存器. 表中lit4.lit8.lit16.lit32.lit64表示字面值(直 ...
- 每周分享五个 PyCharm 使用技巧(二)
这是 「PyCharm 技巧分享」系列的第二篇分享.由于上一篇文章得到了大家的一些赞同,所以今天又来给大家推荐一些我平时自己有用的小技巧,大家择需所取即可. 先声明下,并不保证对所有的人都是有帮助的, ...
- c# aes,des,md5加密等解密算法
一:可逆加密,即是能加密也能解密 对称可逆加密:加密后能解密回原文,加密key和解密key是一个 加密算法都是公开的,密钥是保密的, 即使拿到密文 你是推算不了密钥 也推算不了原文 加密解密的速度快, ...
- mac webstorm无法打开 如何使webstorm不卡
场景:在应用程序里删除了原先的webstorm,然后从官网下载了新的安装包,进行安装.安装后,webstorm就再也打不开了. 解决方案:执行以下命令,清楚webstorm所有缓存,然后重新安装 $ ...
- Odoo:全球第一免费开源ERP库龄表的简单实现方法(无需二开)
问题背景 希望查看库龄超过30天的货物,该如何实现?此种简单数据查询需要二开吗? 解决方案 方法一:Stock Quant列表视图增加过滤器 <filter string="库龄超30 ...
- Android Studio教程07-Fragment的使用
目录 1. Fragment是什么 1.1. 设计原理和实例 2. 创建fragment 2.1. fragment的生命周期 2.2 添加用户界面:融入到Activity中 3. 管理fragmen ...