其他分享
首页 > 其他分享> > openpyxl 追加 Excel 数据与 Excel 画像素画

openpyxl 追加 Excel 数据与 Excel 画像素画

作者:互联网

你好,我是悦创。

本篇文章所涉及代码文件关注公众号:AI悦创,后台回复:20210222

xlsxwriter 只能创建新的文件,不能对文件进行数据的追加和读取操作。

需要追加和读取 xlsx 文件,就需要用到 openpyxl 这个库了。安装命令:pip install openpyxl。使用 openpyxl 完成这面这个需求:

需求有四个,有难有易。

拷贝文件

第一个是拷贝文件和 sheet1

其实拷贝了文件,自然就包含sheet1,最简单了,如下代码:

import openpyxl
filename = 'xlsxwriter插入数据和折线图.xlsx'
wb = openpyxl.load_workbook(filename)
wb.save('poenpyxl插入数据和折线图[copy xlsxwriter].xlsx')

这样就得到了源文件和 sheet1 的复制品。

拷贝 sheet 内容

第二个需求,拷贝sheet1,做成sheet2

也简单,如下代码:

import openpyxl
filename = 'xlsxwriter插入数据和折线图.xlsx'
wb = openpyxl.load_workbook(filename)

sheet1 = wb['sheet1']
sheet2 = wb.copy_worksheet(sheet1)
sheet2.title = "sheet2"

wb.save('poenpyxl插入数据和折线图[copy xlsxwriter].xlsx')

获取 sheet1,复制一个给 sheet2  参数,然后改下  sheet2 的标题 title,这个  title 就是文件的 sheet2 的名字。

追加数据内容

第三个需求,sheet2 中,数据1 和数据2 追加一年的数据,数据可以随意生成

貌似简单,但是年份时间不好计算,并且现在只有 2019 年的。如果之前数据是 2018 年,则追加一年,应该是 2019 年,所以要读取时间和月份追加。

这里的难点就是时间字符串的读取,以及字符串转时间,以及时间的相加。如下实现代码:

import openpyxl, random, datetime
from dateutil.relativedelta import relativedelta
filename = 'xlsxwriter插入数据和折线图.xlsx'
wb = openpyxl.load_workbook(filename)

sheet1 = wb['sheet1']
sheet2 = wb.copy_worksheet(sheet1)
sheet2.title = "sheet2"

rows = sheet2.max_row # 读取最后一行
prev_date_str = sheet2.cell(row=rows,column=1).value # 取出时间的字符串
prev_date = datetime.datetime.strptime(prev_date_str, "%Y-%m") # 时间字符串转时间对象
for i in range(1,13):
tmp_date = prev_date + relativedelta(months=i) # 月份的计算,每次增加一个月,就得到了第二年的12个月
tmp_num1 = random.randint(1,100)
tmp_num2 = random.randint(1,100)
sheet2.append([tmp_date.strftime("%Y-%m"), tmp_num1, tmp_num2])

wb.save('poenpyxl插入数据和折线图[copy xlsxwriter].xlsx')

实现思路:

第三个需求搞定,下一个需求,sheet2 画折线图

使用 openpyxl 画图表

第四个需求,在 sheet2 中对全部数据画折线图

这个难度不大,只要知道 openpyxl 的画图工具即可,如下代码:

import openpyxl, random, datetime
from dateutil.relativedelta import relativedelta
filename = 'xlsxwriter插入数据和折线图.xlsx'
wb = openpyxl.load_workbook(filename)

sheet1 = wb['sheet1']
sheet2 = wb.copy_worksheet(sheet1)
sheet2.title = "sheet2"

rows = sheet2.max_row
prev_date_str = sheet2.cell(row=rows,column=1).value
prev_date = datetime.datetime.strptime(prev_date_str, "%Y-%m")
for i in range(1,13):
tmp_date = prev_date + relativedelta(months=i)
tmp_num1 = random.randint(1,100)
tmp_num2 = random.randint(1,100)
sheet2.append([tmp_date.strftime("%Y-%m"), tmp_num1, tmp_num2])

# 下面是画折线图的实现代码
from openpyxl.chart import Series,LineChart, Reference
chart = LineChart() #图表对象
rows = sheet2.max_row

data1 = Reference(sheet2, min_col=2, min_row=1, max_col=2, max_row=rows) #涉及数据
title1 = sheet2.cell(row=1,column=2).value
seriesObj1 = Series(data1, title=title1) #创建series对象

data2 = Reference(sheet2, min_col=3, min_row=1, max_col=3, max_row=rows) #涉及数据
title2 = sheet2.cell(row=1,column=3).value
seriesObj2 = Series(data2, title=title2) #创建series对象

chart.append(seriesObj1) #添加到chart中
chart.append(seriesObj2) #添加到chart中

sheet2.add_chart(chart, "E3") #将图表添加到 sheet中


wb.save('poenpyxl插入数据和折线图[copy xlsxwriter].xlsx')

导入所需的画图工具,图表初始化,然后生成数据对象:

最后文件保存,大功告成。

查看最后的效果图

然后就是用 Office 打开 poenpyxl 插入数据和折线图 [copy xlsxwriter].xlsx,看下  sheet2 的样子,如下图:watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

25 行数据,除了标题 24 行,刚好是 2019+2020 的 24 个月。折线图也一切正常。

Excel 画像素画

Excel 和图片类似

Excel 文件,单元格支持编辑内容和设置背景色。

一张图片,都是由密密麻麻的像素组成,且每个像素都是一个 rgb 的颜色值。

那是否可以读取图片每个像素的颜色,填充到 Excel 中,就可以做到 Excel 中画图。

这么想,是可以的。理论上也是可行的,那接下来就开始写代码。

打开文件和图片

第一步,导入所需库,分别是 xlsxwriter 和图片的  Image 库。使用 xlsxwriter 的理由,是 xls 内容有限,图片的像素可是很多的,所以最好是使用 xlsx 格式。

import xlsxwriter
from PIL import Image

导入之后,准备图片,并读取图片的宽高,以及像素对象:

path = '1.png'
img = Image.open(path)
imgL = img.convert("P").convert("RGB")
pix = imgL.load()
w, h = imgL.size
watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=image.png

使用 Image 读取图片对象,获取宽和高,以及 pix 这像素对象,通过 pix[1,1 ]拿到具体的颜色 RGB 值,然后转换成 16 进制的颜色值,进行背景色的写入。

准备一个特殊函数

现在打开一个 xlsx 文件,文件名任意,如下代码:

wb = xlsxwriter.Workbook('demo2.xlsx')
ws = wb.add_worksheet('sheet1')

然后找一个 RGB 转 16 进制的函数,因为 RGB 是 10 进制的,方式就是通过 hex 函数转换成 16  进制,然后加上 x  和 0,并全部大写,就可以了。如下函数:

def RGB_to_Hex(tmp):
rgb = list(tmp)
strs = '#'
for i in rgb:
num = int(i)
strs += str(hex(num))[-2:].replace('x','0').upper()
return strs

「为什么一定要   16  进制?」 因为  sheet 中,写入背景色时,颜色必须是 16 进制才可以。

读取和写入

下面就是循环的逐个单元格设置背景色,且不需要写入内容。如下代码:

for i in range(w):
for j in range(h):
rgb = pix[i,j]
color = RGB_to_Hex(rgb)
style = wb.add_format({'bg_color': '{}'.format(color)})
ws.write(j,i,'',style)
ws.set_row(j,1)
ws.set_column(0,w-1,0.5)

wb.close()

代码思路:

这是单元格的主要代码,写完后,关闭 workbook 即可。

查看像素画

读取图片的全部宽高,然后描绘到  Excel 中完成了。最后用图片的形式展示下文件的样子,如下图【使用  WPS 软件查看】:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=image.png

 

长按识别下方二维码,和众多位岛民一起

把别人的顿悟,变成你的基本功

 

 花半秒钟就看透事物本质的人,
  和花一辈子都看不清的人,
  注定是截然不同的命运。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

标签:wb,xlsxwriter,Excel,sheet1,sheet2,折线图,素画,数据,openpyxl
来源: https://blog.51cto.com/aiyc/2921548