1.编写xlsx文件,必须是xlsx后缀的即07版之后的excel
2.xlsx文件,需要三个Sheet页
3.第一个Sheet页为公共变量, 这些变量名称 最终用在第三个Sheet页中,已{{变量名}}的方式取值
4.第二个Sheet页为生成图片多少的列表信息,第一行为头信息,从第二行开始为具体数据信息,最终也用在第三Sheet页中,已{{表头列名}}的方式取值
5.第三个Sheet页需要设置页面背景,页面背景在页面布局选项中,然后在背景上放置需要输出的变量,已{{变量}}的方式去第一和第二Sheet页中的变量
6.编辑好xlsx文件,跟主程序《贴地飞行图片批量生成.exe》放在同一目录下,然后执行exe文件,即下当前目录生成相应的图片
7生成的图片命名规则为第二sheet页中的前两列字段拼接名
8.在第三Sheet页中变量名可以设置字体大小和颜色,但字体是宋体还是雅黑这个xlsx取不到,需要在config.ini中设置字体路径,Windows字体文件在C:\Windows\Fonts中,文件名具体看文件属性,例如宋体simsun.ttc,Linux下需要写全路径/usr/share/fonts/msyh.ttf
附:config.ini配置项说明
font = msyh.ttf 配置字体文件路径
#6.88*(4/3.0)
x = 9.173333 这个变量放在图片上位置x的比例像素,默认即可,正常不需要动
#(4/3.0)
y = 1.3333333 这个变量放在图片上位置y的比例像素,默认即可,正常不需要动
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
from openpyxl import load_workbook
import re
from PIL import Image, ImageDraw, ImageFont
import os
import zipfile
try:
import configparser as configparser
except Exception:
import ConfigParser as configparser
from collections import OrderedDict
logging.basicConfig(level=logging.DEBUG,#控制台打印的日志级别
filename='newlog.log',
filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志
#a是追加模式,默认如果不写的话,就是追加模式
format=
'%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
#日志格式
)
# 判断是否是文件和判断文件是否存在
def isfile_exist(file_path):
if not os.path.isfile(file_path):
print("It's not a file or no such file exist ! %s" % file_path)
return False
else:
return True
# 修改指定目录下的文件类型名,将excel后缀名修改为.zip
def change_file_name(file_path, new_type='1.zip'):
if not isfile_exist(file_path):
return ''
extend = os.path.splitext(file_path)[1] # 获取文件拓展名
if extend != '.xlsx' and extend != '.xls':
print("It's not a excel file! %s" % file_path)
return False
file_name = os.path.basename(file_path) # 获取文件名
new_name = str(file_name.split('.')[0]) + new_type # 新的文件名,命名为:xxx.zip
dir_path = os.path.dirname(file_path) # 获取文件所在目录
new_path = os.path.join(dir_path, new_name) # 新的文件路径
if os.path.exists(new_path):
os.remove(new_path)
os.rename(file_path, new_path) # 保存新文件,旧文件会替换掉
return new_path # 返回新的文件路径,压缩包
# 解压文件
def unzip_file(zipfile_path):
if not isfile_exist(zipfile_path):
return False
if os.path.splitext(zipfile_path)[1] != '.xlsx':
print("It's not a zip file! %s" % zipfile_path)
return False
file_zip = zipfile.ZipFile(zipfile_path, 'r')
file_name = os.path.basename(zipfile_path) # 获取文件名
zipdir = os.path.join(os.path.dirname(zipfile_path), str(file_name.split('.')[0])) # 获取文件所在目录
# if not os.path.exists(zipdir):
# os.makedirs(zipdir)
pic_dir = 'xl' + os.sep + 'media'
for files in file_zip.namelist():
if files.find(pic_dir)>=0:
file_zip.extract(files, os.path.join(zipdir)) # 解压到指定文件目录
file_zip.close()
return True
# 读取解压后的文件夹,打印图片路径
def read_img(zipfile_path):
if not isfile_exist(zipfile_path):
return False
dir_path = os.path.dirname(zipfile_path) # 获取文件所在目录
file_name = os.path.basename(zipfile_path) # 获取文件名
pic_dir = 'xl' + os.sep + 'media' # excel变成压缩包后,再解压,图片在media目录
pic_path = os.path.join(dir_path, str(file_name.split('.')[0]), pic_dir)
file_list = os.listdir(pic_path)
for file in file_list:
filepath = os.path.join(pic_path, file)
fsize = os.path.getsize(filepath)
fsize = fsize / float(1024 * 1024)
if fsize>0.05:
print(filepath)
return filepath
return ''
# 组合各个函数
def compenent(excel_file_path):
zip_file_path = excel_file_path#change_file_name(excel_file_path)
if zip_file_path != '':
if unzip_file(zip_file_path):
return read_img(zip_file_path)
return ''
def getsheet2(booksheet):
defaultRowHeight = booksheet.sheet_format.defaultRowHeight
defaultColWidth = booksheet.sheet_format.defaultColWidth
print (defaultRowHeight)
print (defaultColWidth)
rows = booksheet.rows
x=0
dict=OrderedDict()
for i,row in enumerate(rows):
y=0
for j,col in enumerate(row):
# print(col.value,i,j)
if col.value!=None and len(col.value)>0 and col.value.startswith("{{") and col.value.endswith("}}"):
text = re.findall(r'\{{(.*?)\}}', col.value)[0]
dict[text]=[i,j,x,y,col.font,col.fill]
if booksheet.column_dimensions[col.coordinate].width == None:
y=y+defaultColWidth
else:
y = y + booksheet.column_dimensions[col.coordinate].width
if booksheet.row_dimensions[i].height==None:
x=x+defaultRowHeight
else:
x=x+booksheet.row_dimensions[i].height
# print (dict)
return dict
def getsheet0(booksheet):
dict=OrderedDict()
rows = booksheet.rows
try:
for row in rows:
dict[row[0].value]=row[1].value
except Exception as e:
logging.debug(e)
# print(dict)
return dict
def getsheet1(booksheet,dictcomm):
list=[]
rows = booksheet.rows
lista=[]
try:
for i,row in enumerate(rows):
dict = OrderedDict()
for j,col in enumerate(row):
if i == 0:
lista.append(col.value)
continue
# print (col.value)
dict[lista[j]]=col.value
if i != 0:
dict.update(dictcomm)
list.append(dict)
except Exception as e:
logging.debug(e)
# print(list)
return list
# main
if __name__ == '__main__':
try:
file_list = os.listdir(os.getcwd())
conf = configparser.SafeConfigParser()
conf.read("config.ini")
fontpath= conf.get("config", "font")#msyh.ttf
xxx = float(conf.get("config", "x"))#9.173333
yyy = float(conf.get("config", "y"))#1.3333333
for file in file_list:
if not os.path.splitext(file)[0].startswith('.') and os.path.splitext(file)[1] == '.xlsx':
name=file
imgpath=compenent(name)
if imgpath=='':
logging.debug('未获取到xlsx中的图片')
else:
workbook = load_workbook(name)
sheets = workbook.sheetnames #从名称获取sheet
booksheet = workbook[sheets[2]]
lists=getsheet1(workbook[sheets[1]],getsheet0(workbook[sheets[0]]))
dicts=getsheet2(workbook[sheets[2]])
#往图片写入
for index,li in enumerate(lists):
base = Image.open(imgpath)
d = ImageDraw.Draw(base)
for key in dicts:
fill=(0, 0, 0)
fnt = ImageFont.truetype(fontpath, int(dicts[key][4].sz))
if dicts[key][4].color==None:
fill='#'+dicts[key][5].fgColor.value[2:]
else:
fill = '#' +dicts[key][4].color.value[2:]
d.text(( dicts[key][3]*xxx,dicts[key][2]*yyy), unicode(str(li[key]),'UTF-8'),font=fnt ,fill=fill)
filename =''
if len(li)>1:
filename=str(li.items()[0][1])+'_'+str(li.items()[1][1])
else:
filename =str(li.items()[0][1])
print(filename)
logging.debug(filename)
base.save(filename+str(index)+os.path.splitext(imgpath)[1])
# break
except Exception as e:
logging.debug(e)
最终批量生成图片效果图: