ExcelInfo.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. # -*- coding: utf-8 -*-
  2. # 这段代码主要的功能是把excel表格转换成python可用的列表和字典数据
  3. import sys
  4. import xlrd #http://pypi.python.org/pypi/xlrd
  5. import json
  6. import time
  7. from datetime import datetime
  8. from xlrd import xldate_as_tuple
  9. class NameFlag:
  10. master='~'
  11. main='*'
  12. Type='#'
  13. error='!'
  14. class SplitFlag:
  15. flag1='|'
  16. flag2=':'
  17. class SheetType:
  18. # 普通表
  19. # 输出JSON ARRAY
  20. NORMAL = 0
  21. # 有主外键关系的主表
  22. # 输出JSON MAP
  23. MASTER = 1
  24. # 有主外键关系的附表
  25. # 输出JSON MAP
  26. SLAVE = 2
  27. # 支持的数据类型
  28. class DataType:
  29. Int= 'int'
  30. Float='float'
  31. STRING= 'str'
  32. BOOL= 'bool'
  33. DATE= 'date'
  34. Obj='obj'
  35. ARRAY= '[]'
  36. DIC= '{}'
  37. UNKNOWN= 'unknown'
  38. class HeadSetting:
  39. name=''
  40. Type=DataType.UNKNOWN
  41. index=0
  42. param=None
  43. def __init__(self,name,Type,index):
  44. self.name=name
  45. self.Type=Type
  46. self.index=index
  47. class SheetInfo:
  48. name=''
  49. sheetName=''
  50. Type = SheetType.NORMAL
  51. dataType=DataType.ARRAY
  52. idHead=HeadSetting('',DataType.UNKNOWN,0)
  53. masterHead=HeadSetting('',DataType.UNKNOWN,0)
  54. slaves= []
  55. head= []
  56. sheet={}
  57. table=[]
  58. masterCols=[]
  59. def __init__(self,name):
  60. self.name=name
  61. self.sheetName=name
  62. self.Type=SheetType.NORMAL
  63. self.dataType=DataType.ARRAY
  64. self.idHead=None
  65. self.masterHead=None
  66. self.slaves=[]
  67. self.head=[]
  68. self.sheet={}
  69. self.table=[]
  70. self.masterCols=[]
  71. class ExcelInfo:
  72. sheetInfos={'':SheetInfo('')}
  73. headRow=0
  74. Round=True
  75. ignoreEmpty=True
  76. def __init__(self,excelName,hr,r,i):
  77. self.sheetInfos={}
  78. self.headRow=hr
  79. self.Round=r
  80. self.ignoreEmpty=i
  81. self.setupSheetInfos(xlrd.open_workbook(excelName))
  82. self.parseSheetInfos()
  83. pass
  84. #获取最终所有可用表单
  85. def FinalTable(self):
  86. table={}
  87. for key in self.sheetInfos:
  88. sheetInfo=self.sheetInfos[key]
  89. if sheetInfo.Type==SheetType.SLAVE:
  90. continue
  91. if sheetInfo.idHead.Type==DataType.DIC:
  92. table[sheetInfo.name]=sheetInfo.sheet
  93. else:
  94. table[sheetInfo.name]=sheetInfo.table
  95. return table
  96. #处理表单父子关系
  97. def parseSheetInfos(self):
  98. if self.sheetInfos==None:
  99. pass
  100. for sheetInfo in self.sheetInfos.values():
  101. if sheetInfo.masterHead==None or sheetInfo.masterHead.name not in self.sheetInfos:
  102. if sheetInfo.slaves!=None and len(sheetInfo.slaves)>0:
  103. sheetInfo.Type=SheetType.MASTER
  104. continue
  105. if sheetInfo.dataType==DataType.DIC:
  106. for r in range(0,len(sheetInfo.table)):
  107. masterRow=self.sheetInfos[sheetInfo.masterHead.name].sheet[sheetInfo.masterCols[r]]
  108. if sheetInfo.name not in masterRow:
  109. masterRow[sheetInfo.name]={}
  110. idHead=sheetInfo.table[r][sheetInfo.idHead.name]
  111. masterRow[sheetInfo.name][idHead]=sheetInfo.table[r]
  112. elif sheetInfo.dataType==DataType.Obj:
  113. for r in range(0,len(sheetInfo.table)):
  114. idHead=sheetInfo.table[r][sheetInfo.idHead.name]
  115. self.sheetInfos[sheetInfo.masterHead.name].sheet[sheetInfo.masterCols[r]][idHead]=sheetInfo.table[r]
  116. else:
  117. for r in range(0,len(sheetInfo.table)):
  118. masterRow=self.sheetInfos[sheetInfo.masterHead.name].sheet[sheetInfo.masterCols[r]]
  119. if sheetInfo.name not in masterRow:
  120. masterRow[sheetInfo.name]=[]
  121. masterRow[sheetInfo.name].append(sheetInfo.table[r])
  122. # 预处理表单数据
  123. def setupSheetInfos(self, workbook):
  124. self.sheetInfos = {}
  125. sheetNames=workbook.sheet_names()
  126. for index in range(len(sheetNames)):
  127. sheet_name=sheetNames[index]
  128. if sheet_name[0]==NameFlag.error:
  129. continue
  130. sheetInfo=SheetInfo(sheet_name)
  131. sheetInfo.sheetName=sheet_name
  132. if sheet_name.count(NameFlag.master) > 0:
  133. pair=sheet_name.split(NameFlag.master)
  134. sheetInfo.name=pair[0].strip()
  135. sheetInfo.Type=SheetType.SLAVE
  136. sheetInfo.masterHead=HeadSetting(pair[1].strip(),DataType.UNKNOWN,0)
  137. if sheetInfo.name.count('#') > 0:
  138. pair=sheetInfo.name.split('#')
  139. sheetInfo.dataType=pair[1]
  140. sheetInfo.name=pair[0]
  141. self.sheetInfos[sheetInfo.name]=sheetInfo
  142. row=self.headRow - 1
  143. #初始化表单数据
  144. for sheetInfo in self.sheetInfos.values():
  145. if sheetInfo.Type==SheetType.SLAVE:
  146. self.sheetInfos[sheetInfo.masterHead.name].slaves.append(sheetInfo.name)
  147. sheet=workbook.sheet_by_name(sheetInfo.sheetName)
  148. cols = sheet.ncols
  149. for col in range(0,cols):
  150. cell=sheet.cell_value(row,col)
  151. ctype=sheet.cell(row,col).ctype
  152. if ctype==0 or cell[0]==NameFlag.error:
  153. continue
  154. head_setting=HeadSetting(cell,DataType.UNKNOWN,col)
  155. if cell[0]==NameFlag.master:
  156. if sheetInfo.masterHead!=None:
  157. sheetInfo.masterHead.Type=cell[1:len(cell)]
  158. sheetInfo.masterHead.index=col
  159. continue
  160. elif cell[0]==NameFlag.main:
  161. sheetInfo.idHead=head_setting
  162. cell=cell[1:len(cell)]
  163. head_setting.name=cell
  164. if cell.count(NameFlag.Type) != 0:
  165. pair=cell.split(NameFlag.Type)
  166. head_setting.name=pair[0].strip()
  167. head_setting.Type=pair[1].strip()
  168. if len(pair)>2:
  169. head_setting.param=pair[2].strip()
  170. sheetInfo.head.append(head_setting)
  171. if sheetInfo.idHead==None and sheetInfo.head!=None and len(sheetInfo.head)>0:
  172. sheetInfo.idHead=sheetInfo.head[0]
  173. sheetInfo.table = []
  174. sheetInfo.sheet = {}
  175. for i_row in range(self.headRow,sheet.nrows):
  176. self.parseRow(sheet, i_row, sheetInfo)
  177. for sheetInfo in self.sheetInfos.values():
  178. if sheetInfo.Type!=SheetType.SLAVE and len(sheetInfo.slaves)>0:
  179. sheetInfo.Type=SheetType.MASTER
  180. def Int(self,num):
  181. if self.Round:
  182. num=float(num)
  183. if num>0:
  184. return int(num+0.5)
  185. else:
  186. return int(num-0.5)
  187. return int(float(num))
  188. def unknownValue(self,num,ctype):
  189. if ctype == 2 and num % 1 == 0: # 如果是整形
  190. return self.Int(num)
  191. elif ctype == 3:
  192. # 转成datetime对象
  193. date = datetime(*xldate_as_tuple(num, 0))
  194. return date.strftime('%Y/%d/%m %H:%M:%S')
  195. elif ctype == 4:
  196. return False if num == 0 else True
  197. else:
  198. return num
  199. # 解析一行
  200. def parseRow(self,sheet,rowIndex, sheetInfo) :
  201. if sheetInfo.head==None or len(sheetInfo.head)==0:
  202. return
  203. result = {}
  204. if sheetInfo.masterHead!=None:
  205. cell =sheet.cell_value(rowIndex,sheetInfo.masterHead.index)
  206. #cell = row[sheetInfo.masterHead.index]
  207. sheetInfo.masterCols.append(cell)
  208. headIndex=0
  209. if sheetInfo.idHead!=None:
  210. headIndex=sheetInfo.idHead.index
  211. for i in range(0,len(sheetInfo.head)):
  212. name = sheetInfo.head[i].name
  213. if name[0]=='!':
  214. continue
  215. Type = sheetInfo.head[i].Type
  216. param=sheetInfo.head[i].param
  217. index= sheetInfo.head[i].index
  218. cell =sheet.cell_value(rowIndex,index)
  219. #cell = row[index]
  220. if cell == None:
  221. if self.ignoreEmpty==False:
  222. result[name] = None
  223. continue
  224. #ctype: 0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error
  225. ctype=sheet.cell(rowIndex,index).ctype
  226. if Type==DataType.UNKNOWN: # number string boolean
  227. cell=self.unknownValue(cell,ctype)
  228. if cell=='' and self.ignoreEmpty:
  229. continue
  230. elif Type==DataType.DATE:
  231. # 转成datetime对象
  232. date = datetime(*xldate_as_tuple(cell, 0))
  233. cell = date.strftime('%Y/%d/%m %H:%M:%S')
  234. elif Type==DataType.Int:
  235. if ctype == 2 :
  236. cell = self.Int(cell)
  237. else:
  238. Warning("type error at [%s,%s] ,%s is not a Int"%(rowIndex,index,cell))
  239. elif Type==DataType.Float:
  240. if ctype == 2: # 如果是数值
  241. if param!=None:
  242. r=self.Int(param)
  243. r=pow(10,r)
  244. cell=cell*r
  245. cell=self.Int(cell)
  246. cell=cell/r
  247. else:
  248. Warning("type error at [%s,%s] ,%s is not a Float"%(rowIndex,index,cell))
  249. elif Type==DataType.STRING:
  250. cell=str(cell)
  251. if cell=='':
  252. continue
  253. elif Type==DataType.BOOL:
  254. cell = False if cell == 0 else True
  255. elif Type==DataType.Obj:
  256. if index==headIndex:
  257. result[name]=str(cell)
  258. continue
  259. if ctype==1:
  260. temp=cell.split(SplitFlag.flag1)
  261. if len(temp)>0:
  262. for value in temp:
  263. tp=value.split(SplitFlag.flag2)
  264. ##if len(tp)==0:
  265. ## result["数据格式不对"]=str(cell)
  266. if len(tp)==1:
  267. result[tp[0]]=""
  268. elif len(tp)>1:
  269. result[tp[0]]=cell[len(tp[0])+1:len(value)]
  270. continue
  271. elif Type==DataType.ARRAY:
  272. if ctype==1:
  273. if cell=='':
  274. continue
  275. temp=cell.split(SplitFlag.flag1)
  276. if len(temp)>0:
  277. cell=temp
  278. else:
  279. temp.append(cell)
  280. cell=temp
  281. else:
  282. temp=self.unknownValue(cell,ctype)
  283. if temp=='':
  284. continue
  285. cell=[temp]
  286. elif Type==DataType.DIC:
  287. if index==headIndex:
  288. result[name]=str(cell)
  289. continue
  290. cl={}
  291. if ctype==1:
  292. temp=cell.split(SplitFlag.flag1)
  293. if len(temp)>0:
  294. for value in temp:
  295. tp=value.split(SplitFlag.flag2)
  296. if len(tp)==1:
  297. cl[tp[0]]=""
  298. elif len(tp)>1:
  299. cl[tp[0]]=tp[1]
  300. if len(cl)>0:
  301. cell=cl
  302. ##else:
  303. ## cell={"数据格式不对":cell}
  304. else :
  305. print("无法识别的类型:[%s,%s],%s,%s"%(rowIndex,index,cell,type(cell)))
  306. result[name] = cell
  307. sheetInfo.table.append(result)
  308. if sheetInfo.idHead!=None:
  309. if sheetInfo.idHead.name in result:
  310. sheetInfo.sheet[result[sheetInfo.idHead.name]]=result
  311. elif len(result)>0:
  312. sheetInfo.sheet[result[list(result)[0]]]=result