#-*-coding=utf-8-*-
################################
#Func:读取零售集市数据字典,并重新写入excel,实现快速调整
#Author:winnie
#Date:2017年12月12日
################################
import xlrd
import xlwt
import numpy as np
def completeSheet(l1,l2):
'''比较2个列表,返回相同的元素和 l2比l1多出的元素'''
res2=[];res3=[]
for j in l2:
if j not in l1:res3.append(j)
else:res2.append(j)
return res2,res3
class Style(object):
'''单元格格式类,可以定义字体格式、边框格式、背景格式、对齐格式'''
def __init__(self):
self.style = xlwt.XFStyle()
self.font = xlwt.Font()
self.border = xlwt.Borders()
self.pattern = xlwt.Pattern()
self.alignment =xlwt.Alignment()
def set_font(self,color=0,bold=False,underline=False,italic=False,height=200 ):
self.font.colour_index = color # 0黑色 ,1 白色,4 蓝色
self.font.bold = bold # 加粗
self.font.underline = underline # 下划线
self.font.italic = italic # 倾斜
self.font.height = height
def set_border(self,left=0,right=0,top=0,bottom=0):
self.border.left = left # xlwt.Borders.THIN 实线
self.border.right = right
self.border.top = top
self.border.bottom = bottom
def set_pattern(self,pattern=0,color=0):
self.pattern.pattern = pattern # 0 xlwt.Pattern.NO_PATTERN 1 xlwt.Pattern.SOLID_PATTERN
self.pattern.pattern_fore_colour = color # 0 black 3 green 22 gray 2 red
def set_alignment(self,horz=0,vert=1):
self.alignment.horz = horz # 2 xlwt.Alignment.HORZ_CENTER 水平 1 HORZ_LEFT 0 HORZ_GENERAL
self.alignment.vert = vert # 1 xlwt.Alignment.VERT_CENTER 垂直
def get_style(self):
self.style.font=self.font
self.style.borders=self.border
self.style.pattern=self.pattern
self.style.alignment=self.alignment
return self.style
#常规字体
style = Style()
style.set_font(height=180);style.set_border(right=1,bottom=1)
style1=style.get_style()
#无边框字体
style = Style()
style2=style.get_style()
#首行格式字体
style = Style()
style.set_font(bold=True);style.set_border(right=1,bottom=1);style.set_pattern(pattern=1,color=3);style.set_alignment(horz=2) #值为2 居中
style3=style.get_style()
#超链接格式主页
style = Style()
style.set_font(color=4,underline=True,height=180);style.set_border(right=1,bottom=1)
style4=style.get_style()
#第二行标题格式
style = Style()
style.set_font(bold=True);style.set_border(right=1,bottom=1);style.set_pattern(pattern=1,color=22);style.set_alignment(horz=2) #值为2 居中
style5=style.get_style()
#第一列序号列格式
style = Style()
style.set_font(height=180);style.set_border(right=1,bottom=1);style.set_alignment(horz=2) #值为2 居中
style6=style.get_style()
#表sheet页 返回 的超链接格式
style = Style()
style.set_font(color=4,height=180)
style7=style.get_style()
#DSP上无此表
style = Style()
style.set_font(height=180,color=2);style.set_border(right=1,bottom=1)
style8=style.get_style()
#打开源文件
workBook = xlrd.open_workbook(u"DSP零售公共服务模型数据字典.xlsx")
#打开源文件目录页sheet
sheet = workBook.sheet_by_name(u"目录")
#读取源文件目录页sheet所有内容
content = np.array([ sheet.row_values(i) for i in range(sheet.nrows) ])
#取源文件表中文名
table_ch_name =[ i for i in content[2:,4] ]
#取源文件所有Sheet名 大多已表中文名一致,也有不一致
sheet_names = [ i.name for i in workBook.sheets() ]
#新建目标文件
excel = xlwt.Workbook(encoding='utf-8',style_compression=0)
#新建目标文件目录页
sheet1 = excel.add_sheet(u'目录',cell_overwrite_ok=True)
#设置列宽
sheet1.col(0).width = 2000;sheet1.col(1).width = 3000;sheet1.col(2).width = 10000;sheet1.col(3).width = 10000;sheet1.col(4).width = 10000;sheet1.col(11).width = 3500
#写入目标文件目录页内容
for i in range(sheet.nrows):
for j in range(sheet.ncols):
if i == 0 and j == 0: #第一格合并单元格
sheet1.write_merge(0, 0, 0, 11, content[i, j],style3) # 合并首行1-7列的单元格
continue
if i == 1: #第二行 背景灰色
sheet1.write(i, j, content[i, j], style5)
continue
if j==0 and i>=2: # 序号列 居中 注意:这里有转换序号为int类型,不然会是float
sheet1.write(i, j, int(float(content[i, j])), style6)
continue
if j == 2 and i>=2 and content[i, j] == content[i, j+1] : #DSP上无此表
sheet1.write(i, j, content[i, j].upper(), style8)
continue
if j == 3 and i>=2 and content[i, j] == content[i, j-1] : #DSP上无此表
sheet1.write(i, j, content[i, j].upper(), style8)
continue
sheet1.write(i,j,content[i,j].upper(),style1)
def write_sheet(table_name):
'''根据源文件表中文名,找到源文件sheet页,写入目标文件对应sheet页'''
global excel
#读取源文件sheet页内容
sht = workBook.sheet_by_name(table_name)
cot = np.array([sht.row_values(i) for i in range(sht.nrows)])
#将括号替换成'_',excel上这些字符会使超链接无效
tn=table_name.replace('(','_').replace(u'(','_')
tn=tn.replace(')','_').replace(u')','_').replace('-', '_')
#新建sheet
new_sht = excel.add_sheet(tn, cell_overwrite_ok=True)
#列宽设置
new_sht.col(0).width = 2000;new_sht.col(1).width = 7000;new_sht.col(2).width = 7000;new_sht.col(3).width = 7000;new_sht.col(4).width = 5000
for i in range(sht.nrows):
for j in range(sht.ncols):
if i == 0 and j == 0: #合并首行1-6列的单元格
new_sht.write_merge(0,0,0,5,cot[i,j],style3)
continue
if cot[i, j] == u'返回': #创建超链接
#建立超链接
if table_name in table_ch_name:
link = 'HYPERLINK("#%s","%s")'%(u"目录!E"+str(table_ch_name.index(table_name)+3),cot[i,j])
else:
link = 'HYPERLINK("#%s","%s")' % (u"目录!A1" , cot[i, j])
new_sht.write(i,j,xlwt.Formula(link),style7)
continue
if j>5 : #第6列以后的列,不加边框
new_sht.write(i, j, cot[i, j].strip().upper(), style2)
continue
elif j<=5 and i==1: # 第二行灰色背景
new_sht.write(i, j, cot[i, j].strip().upper(), style5)
continue
if j==0 and i>=2 and cot[i, j].strip() !='': # 序号列 居中
new_sht.write(i, j, int(float(cot[i, j])), style6)
continue
new_sht.write(i, j, cot[i, j].strip().upper(), style1)
#new_sht.write(i,j,cot[i,j],link_font())
#找到匹配上的表中文名
r2,r3 = completeSheet(table_ch_name,sheet_names)
#删除不是表的sheet页
r3.remove(u'变更记录');r3.remove(u'指标说明');r3.remove(u'目录')
#copy 所有表的sheet 页
for each in r2:
write_sheet(each)
#copy 找不到表的sheet页
for each in r3:
write_sheet(each)
#目录页建立超链接
for i,each in enumerate(table_ch_name):
if each in r2:
tn = each.replace('(', '_').replace(u'(', '_') #用其他 () <> 等字符 会使超链接失效
tn = tn.replace(')', '_').replace(u')', '_').replace('-', '_')
link = 'HYPERLINK("#%s!A1","%s")' % (tn, each)
sheet1.write(i+2,4, xlwt.Formula(link),style4)
#保存
excel.save(u'新数据字典.xls')