读取xlsx,根据模板图片批量添加文字生成相关图片,如证书,奖状,名片等
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 Falseelse: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 Falsefile_name = os.path.basename(file_path) # 獲取文件名new_name = str(file_name.split('.')[0]) + new_type # 新的文件名,命名為:xxx.zipdir_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 Falseif os.path.splitext(zipfile_path)[1] != '.xlsx':print("It's not a zip file! %s" % zipfile_path)return Falsefile_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 Falsedir_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 filepathreturn ''# 組合各個函數 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.defaultRowHeightdefaultColWidth = booksheet.sheet_format.defaultColWidthprint (defaultRowHeight)print (defaultColWidth)rows = booksheet.rowsx=0dict=OrderedDict()for i,row in enumerate(rows):y=0for 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+defaultColWidthelse:y = y + booksheet.column_dimensions[col.coordinate].widthif booksheet.row_dimensions[i].height==None:x=x+defaultRowHeightelse:x=x+booksheet.row_dimensions[i].height# print (dict)return dictdef getsheet0(booksheet):dict=OrderedDict()rows = booksheet.rowstry:for row in rows:dict[row[0].value]=row[1].valueexcept Exception as e:logging.debug(e)# print(dict)return dict def getsheet1(booksheet,dictcomm):list=[]rows = booksheet.rowslista=[]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.valueif 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.ttfxxx = float(conf.get("config", "x"))#9.173333yyy = float(conf.get("config", "y"))#1.3333333for file in file_list:if not os.path.splitext(file)[0].startswith('.') and os.path.splitext(file)[1] == '.xlsx':name=fileimgpath=compenent(name)if imgpath=='':logging.debug('未獲取到xlsx中的圖片')else:workbook = load_workbook(name)sheets = workbook.sheetnames #從名稱獲取sheetbooksheet = 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])# breakexcept Exception as e:logging.debug(e)最終批量生成圖片效果圖:
轉載于:https://my.oschina.net/djsoft/blog/2885388
總結
以上是生活随笔為你收集整理的读取xlsx,根据模板图片批量添加文字生成相关图片,如证书,奖状,名片等的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 汽车VIN码超详细解析规则
- 下一篇: ADS仿真学习:s2p文件导入ADS