Keine Beschreibung

hardnessexcel.py 40KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365
  1. from openpyxl import load_workbook
  2. import pyodbc
  3. import time
  4. import sys
  5. from pprint import pprint
  6. import datetime
  7. from openpyxl.styles import NamedStyle, Font, colors, Border, Side
  8. import openpyxl.drawing.text as drawingText
  9. from copy import deepcopy
  10. from openpyxl.chart import LineChart, Reference, Series
  11. from openpyxl.chart.text import RichText
  12. from openpyxl.drawing.text import RichTextProperties,Paragraph,ParagraphProperties, CharacterProperties
  13. import openpyxl.utils as utils
  14. from openpyxl.chart.text import RichText
  15. from .utils import create_db_connection
  16. dateStyle = NamedStyle(name='custom_datetime', number_format='DD/MM/YYYY HH:MM:MM')
  17. codeMap = {
  18. "001": "D",
  19. "002": "T",
  20. "003": "H",
  21. "02": "P",
  22. "03": "E",
  23. "39": "E",
  24. "04": "W",
  25. "05": "JK",
  26. "06": "F",
  27. "51": "F",
  28. "07": "G",
  29. "B2": "G",
  30. "08": "U",
  31. "09": "M",
  32. "10": "A",
  33. "11": "N",
  34. "12": "J",
  35. "13": "X",
  36. "14": "Flatness",
  37. "15": "K",
  38. "16": "Thickness",
  39. "17": "Q",
  40. "18": "S",
  41. "72": "X"
  42. }
  43. # Specifying the ODBC driver, server name, database, etc. directly
  44. #cnxn = None
  45. #cursor = None
  46. '''cursor.execute('select * from data_wb')
  47. rows = cursor.fetchall()
  48. for row in rows:
  49. print(row)'''
  50. #wb = load_workbook(filename = './measurement-temp.xlsx')
  51. wb = load_workbook(filename = './hardness-temp.xlsx')
  52. #print(wb["Cert"]._images)
  53. #wb.save(filename = './createfrompy.xlsx');
  54. def getConditionRef(sid):
  55. global cursor
  56. try:
  57. query = f"select * from [TABLE_TI-T4] t4 where t4.TIT4 = {sid}"
  58. return cursor.execute(query)
  59. except:
  60. return []
  61. def findCustomer(code, lotno):
  62. global cursor
  63. global env
  64. tempResult = []
  65. views = []
  66. if env == "prod":
  67. views = ["bel_master_view", "e_master_view", "mg_master_view", "v_master_view"]
  68. else:
  69. views = ["bel_master_view_dev", "e_master_view_dev", "mg_master_view_dev", "v_master_view_dev"]
  70. ts = []
  71. select = "distinct MI24 as unbStd, MI13 as sampling, MI15, MI14, MI16, MI17, MI18, MI19, MI20, MI21, MI22, MI23, PRO5, PRO27,PRO1C as customer, cast(PRO8 as varchar) + cast(PRO9 as varchar) + ' ' + cast(PRO10 as varchar) + 'x' + cast(PRO11 as varchar ) + 'x' + cast(PRO12 as varchar) as sizestring, isnull(PRO13,'') + ' ' + isnull(PRO14,'') + ' ' + isnull(PRO15,'') + ' ' + isnull(PRO16, '') + ' ' + isnull(PRO17,'') + ' ' + isnull(PRO18,'') as spec"
  72. where = "PRO1 = '{0}' and PRO2 = '{1}'".format(code, lotno)
  73. for v in views:
  74. sqlQuery = "select {0} from {1} where {2}".format(select, v, where)
  75. ts.append(sqlQuery)
  76. #print(";".join(ts))
  77. merged = []
  78. for t in ts:
  79. merged += cursor.execute(t)
  80. return merged
  81. def createWS(name, values, codeno, filters):
  82. global wb
  83. #wb.create_sheet(name)
  84. wo = wb['Data Measurement']
  85. ws = wb.copy_worksheet(wo)
  86. ws.title = name
  87. cust = findCustomer(codeno.replace("-", ""))
  88. ws["B2"] = cust[0].customer
  89. ws["B3"] = codeno.replace("-", "")
  90. ws["B4"] = cust[0].sizestring
  91. ws["B5"] = cust[0].spec
  92. bcode = ord('B')
  93. ccode = 2
  94. for idx, val in enumerate(values):
  95. #print(idx)
  96. c = chr(bcode + idx)
  97. #print(val.lot_no)
  98. if ( bcode + idx) > ord('Z'):
  99. r = bcode + idx - ord('Z')
  100. c = 'A' + chr(ord('A') + (r - 1))
  101. #print("c = "+c)
  102. ws.cell(column= ccode, row=45, value = val.lot_no)
  103. ms = findInMasterView('*', "PRO2 = '{0}'".format(val.lot_no))
  104. #pressInfo = findPressInfo(codeno.replace("-", ""),val.lot_no, filters)
  105. #print("master view")
  106. #print(ms)
  107. if ms:
  108. ws.cell(column = ccode, row=35, value = ms[0].MI24)
  109. #ws[c+'38'] = ms[0].STD_Balance
  110. ws.cell(column = ccode , row=37, value = ms[0].PRO6)
  111. #ws[c+'44'] = ms[0].PRO5
  112. ws.cell(column = ccode, row = 43, value = ms[0].PRO10)
  113. ws.cell(column = ccode, row = 42, value = ms[0].PRO12)
  114. #if pressInfo:
  115. ws.cell(column = ccode , row=39, value = val.Press_UserName)
  116. ws.cell(column = ccode, row = 40, value = val.Press_McName)
  117. #print(type(pressInfo[0].Insp_Date))
  118. #ws[c+'46'].number_format = "Short Date"
  119. ws.cell(column = ccode, row = 46 , value = val.Insp_Date.date())
  120. #print(type(ws[c+'46'].value))
  121. #ws[c+'46'].style = dateStyle
  122. #ws[c+'46'].value = datetime.datetime(2010, 7, 21)
  123. #print(ws[c+'46'].number_format)
  124. #ws[c+'46']. = datetime.datetime
  125. ws.cell(column = ccode , row = 44, value = val.FG_Qty)
  126. dws = updateLength(val.lot_no)
  127. for j,v in enumerate(dws):
  128. ws.cell(column = ccode , row = 48+v.row_no , value = v.weight)
  129. dws = updateUb(val.lot_no)
  130. for j,v in enumerate(dws):
  131. ws.cell(column = ccode , row = 171+v.row_no , value = v.weight)
  132. ccode += 1
  133. c1 = LineChart()
  134. c1.legend.position = "t";
  135. c1.title = "Graph of Result Cp Unbalance"
  136. c1.title.font = Font(underline=Font.UNDERLINE_SINGLE)
  137. c1.y_axis.title = "Unb Weight"
  138. c1.y_axis.number_format = "#,##0.00"
  139. c1.x_axis.title = "Lot No"
  140. c1.width = 30
  141. c1.height = 10
  142. #print(len(values))
  143. lt = Reference(ws, min_col=2, max_col=len(values)+1, min_row=45, max_row=45)
  144. data = Reference(ws, min_col=1, max_col=len(values)+1, min_row=34, max_row=34)
  145. maxUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=29, max_row=29)
  146. minUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=30, max_row=30)
  147. avgUB = Reference(ws, min_col=1, max_col=len(values)+1, min_row=31, max_row=31)
  148. vsStd = Reference(ws, min_col=1, max_col=len(values)+1, min_row=36, max_row=36)
  149. c1.add_data(data, from_rows=True, titles_from_data=True)
  150. c1.add_data(minUB, from_rows=True, titles_from_data=True)
  151. c1.add_data(avgUB, from_rows=True, titles_from_data=True)
  152. c1.add_data(vsStd, from_rows=True, titles_from_data=True)
  153. c1.add_data(maxUB, from_rows=True, titles_from_data=True)
  154. s1 = c1.series[0]
  155. s1.marker.symbol = "triangle"
  156. s1.graphicalProperties.line.noFill = True
  157. s1 = c1.series[1]
  158. s1.marker.symbol = "circle"
  159. s1.graphicalProperties.line.noFill = True
  160. s1 = c1.series[2]
  161. s1.marker.symbol = "square"
  162. s1.graphicalProperties.line.noFill = True
  163. s1 = c1.series[4]
  164. s1.marker.symbol = "diamond"
  165. s1.graphicalProperties.line.noFill = True
  166. c1.set_categories(lt)
  167. c1.x_axis.txPr = RichText(bodyPr=RichTextProperties(anchor="ctr",anchorCtr="1",rot="-2700000",
  168. spcFirstLastPara="1",vertOverflow="ellipsis",wrap="square"),
  169. p=[Paragraph(pPr=ParagraphProperties(defRPr=CharacterProperties()), endParaRPr=CharacterProperties())])
  170. ws.add_chart(c1, "A7")
  171. #newws.title = name
  172. #copy data cp ws
  173. #insert values in the sheet
  174. def findInMasterView(select, where):
  175. global cursor
  176. global env
  177. tempResult = []
  178. views = []
  179. if env == "prod":
  180. views = ["bel_master_view", "e_master_view", "mg_master_view", "v_master_view"]
  181. else:
  182. views = ["bel_master_view_dev", "e_master_view_dev", "mg_master_view_dev", "v_master_view_dev"]
  183. ts = []
  184. for v in views:
  185. sqlQuery = "select {0} from {1} where {2}".format(select, v, where)
  186. ts.append(sqlQuery);
  187. qj = ';'.join(ts)
  188. #print(qj)
  189. merged = []
  190. for t in ts:
  191. merged += cursor.execute(t)
  192. if len(merged) > 0:
  193. return merged
  194. return merged
  195. def findPressInfo(code, lot, year):
  196. global cursor
  197. global env
  198. fyear = year.replace("created_at", "Insp_Date")
  199. q = "select * from tb_fg_pressinfo_lotlist where ProductCode = '{0}' and LotNo = '{1}' and {2}" \
  200. .format(code, lot, fyear)
  201. cursor.execute(q)
  202. return cursor.fetchall()
  203. def findProductDimension(codeno):
  204. stdSizes = """
  205. select * from AllProduct_Dimension_ForInsProcess where ProductCode='{0}'""".format(codeno.replace("-", ""))
  206. #print(stdSizes)
  207. return stdSizes
  208. def findProductPress(codeno):
  209. stdSizes = """
  210. select * from AllProduct_PressPosition_PressWeight where ProductCode='{0}'""".format(codeno.replace("-", ""))
  211. #print(stdSizes)
  212. return stdSizes
  213. def generateSQLDataMS(codeno, filters):
  214. if codeno.find('-') != -1:
  215. codeString = codeno
  216. else:
  217. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  218. if filters is not None:
  219. qMsData = """
  220. select * from data_ms where code='{0}' and (size1 > 0 or size2 > 0) and {1} order by lot_no asc, row_no asc
  221. """.format(codeString, filters)
  222. else:
  223. qMsData = """
  224. select * from data_ms where code='{0}' and (size1 > 0 or size2 > 0 ) order by lot_no asc, row_no asc
  225. """.format(codeString)
  226. return qMsData
  227. def updateLength(lotno):
  228. global cursor
  229. global wb
  230. q = "select * from data_wb where lot_no = '{0}' and judgement='OK' order by row_no asc".format(lotno)
  231. #print(q);
  232. return cursor.execute(q)
  233. def updateUb(lotno):
  234. global cursor
  235. global wb
  236. q = "select * from data_wb where lot_no = '{0}' and judgement='NG' order by row_no asc".format(lotno)
  237. #print(q);
  238. return cursor.execute(q)
  239. def actualChart(ws, title, data, position_data, body_data, cat_pos, position):
  240. '''
  241. for row in rows:
  242. ws.append(row)
  243. '''
  244. if isinstance(position_data, str):
  245. rs = ws[position_data]
  246. else:
  247. rs = tuple(ws.iter_rows(**position_data))
  248. for i in range(len(rs)):
  249. for j in range(len(rs[i])):
  250. print(rs[i][j])
  251. rs[i][j].value = data[i][j]
  252. #ws["A1"].value = rows
  253. #print(cells)
  254. print(rs)
  255. #return
  256. c1 = LineChart()
  257. c1.width = 10
  258. #c1.height = 10
  259. c1.title = title
  260. c1.style = 13
  261. c1.y_axis.title = 'Size'
  262. c1.x_axis.title = 'Lot'
  263. #print(ws.title+"?"+position_data)
  264. if isinstance(body_data, str):
  265. rdata = Reference(range_string=ws.title+"!"+body_data)
  266. else:
  267. rdata = Reference(ws, **body_data)
  268. c1.add_data(rdata, titles_from_data=True)
  269. if isinstance(cat_pos, str):
  270. lots = Reference(range_string=ws.title+"!"+cat_pos)
  271. else:
  272. lots = Reference(ws, **cat_pos)
  273. c1.set_categories(lots)
  274. # Style the lines
  275. s1 = c1.series[0]
  276. s1.marker.symbol = "triangle"
  277. s1.marker.graphicalProperties.solidFill = "FF0000" # Marker filling
  278. s1.marker.graphicalProperties.line.solidFill = "FF0000" # Marker outline
  279. s1.graphicalProperties.line.noFill = True
  280. s2 = c1.series[1]
  281. s2.graphicalProperties.line.solidFill = "00AAAA"
  282. s2.graphicalProperties.line.dashStyle = "sysDot"
  283. s2.graphicalProperties.line.width = 100050 # width in EMUs
  284. s2 = c1.series[2]
  285. s2.smooth = True # Make the line smooth
  286. if isinstance(position,str):
  287. ws.add_chart(c1, position)
  288. else:
  289. ptemp = get_column_letter(position[1])
  290. print("ptemp = ", ptemp)
  291. ws.add_chart(c1, ptemp + str(position[0]))
  292. def createXBarChart(codeno, filters):
  293. global cursor
  294. global wb
  295. global dateStyle
  296. global codeMap
  297. ws = wb.create_sheet("X Bar,R Chart")
  298. #find lot in a codeno
  299. sql = generateSQLDataMS(codeno, filters)
  300. sql2 = findProductPress(codeno)
  301. cursor.execute(sql)
  302. row = cursor.fetchall()
  303. cursor.execute(sql2)
  304. row2 = cursor.fetchall()
  305. #print(list(row2))
  306. temp = {}
  307. #map data into lotno list
  308. #find max, min
  309. sizes = {}
  310. stdSizes = {}
  311. pressType1 = pressType2 = pressType3 = ""
  312. for k in row2:
  313. if k.PressType_1 != "" and k.PressType_1 is not None:
  314. sizes["size1"] = []
  315. stdSizes["size1"] = k
  316. pressType1 = k.PressType_1
  317. if k.PressType_2 != "" and k.PressType_2 is not None:
  318. sizes["size2"] = []
  319. stdSizes["size2"] = k
  320. pressType2 = k.PressType_2
  321. if k.Press_T != "" and k.Press_T is not None:
  322. sizes["tpresssize"] = []
  323. stdSizes["tpresssize"] = k
  324. pressType3 = "Thickness Press"
  325. num = 0
  326. for r in row:
  327. #print(r)
  328. if r.lot_no not in temp:
  329. temp[r.lot_no] = []
  330. temp[r.lot_no].append(r)
  331. for k,v in sizes.items():
  332. sizes[k].append(getattr(r, k, None))
  333. #print("temp = ", temp)
  334. #print("temp keys = ", temp.keys());
  335. for k,v in temp.items():
  336. #print("k = ", k)
  337. num = len(v)
  338. #break
  339. #print("num = ", num)
  340. if num > 5:
  341. num = 5
  342. #filter only dimensions in master
  343. #print("TEMP == \n")
  344. #print(sizes)
  345. avgSize = {}
  346. minSize = {}
  347. maxSize = {}
  348. data2 = []
  349. data2.append(["Lot No"])
  350. for k,v in temp.items():
  351. data2[0].append(k)
  352. #print("data 2 = ", data2)
  353. #create maxtrix in form
  354. '''
  355. Lot, 1, 2, 3, 4, 5, max, min
  356. xxx, v, v, v, v, v, v, v
  357. '''
  358. bp = 1
  359. for keySize, keyValue in sizes.items():
  360. l = []
  361. n0 = 0
  362. beginRow = 2
  363. #print("key size = %s\n" %(keySize) )
  364. for k,v in temp.items():
  365. a0 = []
  366. a0.append(k)
  367. sv = len(v)
  368. if sv > 5:
  369. sv = 5
  370. n0 = sv
  371. for i in range(sv):
  372. a0.append(getattr(v[i], keySize, 0))
  373. avg = sum(a0[1:]) / len(a0[1:])
  374. a0.append(avg)
  375. r = max(a0[1:]) - min(a0[1:])
  376. a0.append(r)
  377. #print("std size ", stdSizes[keySize])
  378. max_min = 0
  379. if k == "size1":
  380. max_min = stdSizes[k].PressWeight_1
  381. if k == "size2":
  382. max_min = stdSizes[k].PressWeight_2
  383. if k == "tpresssize":
  384. maxMaster = stdSizes[k].PressT + stdSizes[k].Press_T_Tol
  385. minMaster = stdSizes[k].PressT - stdSizes[k].Press_T_Tol
  386. else:
  387. maxMaster = minMaster = float(max_min)
  388. a0.append(maxMaster)
  389. a0.append(minMaster)
  390. l.append(a0)
  391. #print("l = ", l)
  392. header = ["Lot No"] + [str(i+1) for i in range(n0)] + ["avg", "r", "max", "min"]
  393. #print("header =", header)
  394. l = [header] + l;
  395. #print("l = ", l)
  396. '''
  397. tranpose above matrix into form:
  398. Lot,xxx, xxx, xxx,
  399. 1, v, v, v
  400. 2, v, v, v
  401. ...
  402. '''
  403. m, n = len(l), len(l[0])
  404. #print("mxn = ", m, n)
  405. ta = [ [0 for j in range(m)] for i in range(n)]
  406. #print("ta = ", ta)
  407. for i in range(len(l)):
  408. for j in range(len(l[i])):
  409. try:
  410. ta[j][i] = l[i][j]
  411. except Exception as e:
  412. return
  413. #print("TA ", ta)
  414. #print(len(ta), len(ta[0]))
  415. #print("===\n")
  416. #print(beginRow, beginRow + len(ta) - 1, bp, (bp-1) + len(ta[0]))
  417. wsRows = tuple(ws.iter_rows(min_row=beginRow, max_row=beginRow + len(ta) - 1, min_col=bp, max_col=(bp-1)+len(ta[0])))
  418. for i in range(len(wsRows)):
  419. for j in range(len(wsRows[i])):
  420. #print(i,j)
  421. wsRows[i][j].value = ta[i][j]
  422. wsRows[i][j].number_format = '0.00'
  423. bd = Side(style='medium', color="000000")
  424. wsRows[i][j].border = Border(left=bd, top=bd, right=bd, bottom=bd)
  425. if keySize == "size1":
  426. barTitle = pressType1
  427. if keySize == "size2":
  428. barTitle = pressType2
  429. if keySize == "tpresssize":
  430. barTitle = pressType3
  431. ws.cell(1, bp, value = "%s (bar)" % (barTitle))
  432. #bp += len(ta[0]) + 2
  433. #continue
  434. cpos = utils.get_column_letter(bp) + "15"
  435. font_test = drawingText.Font(typeface='Calibri')
  436. cp = CharacterProperties(latin=font_test, sz=1000)
  437. pp = ParagraphProperties(defRPr=cp)
  438. c1 = LineChart()
  439. cp1 = CharacterProperties(latin=font_test, sz=1400)
  440. pp1 = ParagraphProperties(defRPr=cp1)
  441. minValues = Reference(ws, min_row=beginRow+9, min_col=bp+1, max_row=beginRow+9, max_col=(bp-1)+len(ta[0]) )
  442. minSerie = Series(minValues, title="Min")
  443. c1.append(minSerie)
  444. maxValues = Reference(ws, min_row=beginRow+8, min_col=bp+1, max_row=beginRow+8, max_col=(bp-1)+len(ta[0]) )
  445. maxSerie = Series(maxValues, title="Max")
  446. c1.append(maxSerie)
  447. avgValues = Reference(ws, min_row=beginRow+6, min_col=bp+1, max_row=beginRow+6, max_col=(bp-1)+len(ta[0]) )
  448. avgSerie = Series(avgValues, title="Avg")
  449. avgSerie.marker.symbol = "circle"
  450. avgSerie.marker.graphicalProperties.solidFill = "4f81bd" # Marker filling
  451. avgSerie.graphicalProperties.line.solidFill = "4f81bd"
  452. c1.append(avgSerie)
  453. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  454. c1.set_categories(lots)
  455. c1.width = len(ta[0])*3.5
  456. if keySize == "size1":
  457. c1.title = "%s (X Bar) " % (pressType1)
  458. if keySize == "size2":
  459. c1.title = "%s (X Bar) " % (pressType2)
  460. if keySize == "tpresssize":
  461. c1.title = "%s (X Bar) " % (pressType3)
  462. #c1.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  463. if keySize == "tpresssize":
  464. c1.y_axis.title = "Value(mm.)"
  465. else:
  466. c1.y_axis.title = "Value(mg.)"
  467. c1.x_axis.title = "Lot No."
  468. c1.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  469. if c1.y_axis.title != None:
  470. c1.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  471. c1.title.tx.rich.p[0].pPr = pp1# Works!
  472. c1.legend.position = "b"
  473. ws.add_chart(c1, cpos)
  474. cpos = utils.get_column_letter(bp) + "30"
  475. c2 = LineChart()
  476. #c2.title.txPr = RichText(p=[Paragraph(pPr=ParagraphProperties(defRPr=cp), endParaRPr=cp)])
  477. rValues = Reference(ws, min_row=beginRow+7, min_col=bp+1, max_row=beginRow+7, max_col=(bp-1)+len(ta[0]) )
  478. rSerie = Series(rValues, title="R")
  479. c2.append(rSerie)
  480. lots = Reference(ws,min_row=beginRow, min_col=bp+1, max_row=beginRow, max_col=(bp-1)+len(ta[0]))
  481. c2.set_categories(lots)
  482. c2.width = len(ta[0])*3.5
  483. if keySize == "size1":
  484. c2.title = "%s (R) " % (pressType1)
  485. if keySize == "size2":
  486. c2.title = "%s (R) " % (pressType2)
  487. if keySize == "tpresssize":
  488. c2.title = "%s (R) " % (pressType3)
  489. c2.y_axis.title = "Value(mm.)"
  490. c2.x_axis.title = "Lot No."
  491. c2.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  492. c2.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  493. c2.title.tx.rich.p[0].pPr = pp1# Works!
  494. c2.legend.position = "b"
  495. ws.add_chart(c2, cpos)
  496. #move column cursor
  497. bp += len(ta[0]) + 5
  498. #create each size table and chart types
  499. # actual chart
  500. def createPressCP(codeno, filters):
  501. global cursor
  502. global wb
  503. global dateStyle
  504. global codeMap
  505. ws = wb.create_sheet("Press CP")
  506. #find lot in a codeno
  507. sql = generateSQLDataMS(codeno, filters)
  508. sql2 = findProductPress(codeno)
  509. cursor.execute(sql)
  510. row = cursor.fetchall()
  511. cursor.execute(sql2)
  512. row2 = cursor.fetchall()
  513. temp = {}
  514. #map data into lotno list
  515. #find max, min
  516. sizes = {}
  517. stdSizes = {}
  518. #select distinct lot no
  519. bq = '''select ds.code,\
  520. ds.lot_no, max(ds.size1) maxsize1, min(ds.size1) minsize1, max(ds.size2) maxsize2, min(ds.size2) minsize2 ,\
  521. avg(ds.size1) avgSize1 , avg(ds.size2) avgSize2, stdev(ds.size1) sdsize1, stdev(ds.size2) sdsize2, \
  522. empids =
  523. STUFF((SELECT ',' + str(emp_id)
  524. FROM data_ms b
  525. WHERE b.lot_no = ds.lot_no
  526. group by emp_id
  527. FOR XML PATH('')), 1, 2, ''), \
  528. min(ds.created_at) minca,\
  529. pp.Mold_D, pp.Center_D, pp.PressWeight_1, pp.PressWeight_2, pp.PressType_1, pp.PressType_2, pp.UWeight, pp.Press_Ton, pp.PO_Qty \
  530. from data_ms ds \
  531. inner join AllProduct_PressPosition_PressWeight pp on pp.ProductCode = Replace('{0}', '-', '') \
  532. and pp.Lot_No = ds.lot_no \
  533. where \
  534. ds.code = '{0}' and ( (ds.size1 > 0) or (ds.size2 > 0) ) \
  535. group by ds.code, ds.lot_no, pp.Press_Ton, pp.PO_Qty, pp.Mold_D, pp.Center_D, pp.PressWeight_1, pp.PressWeight_2, pp.PressType_1, pp.PressType_2, pp.UWeight'''.format(codeno)
  536. #print("bq ", bq)
  537. cursor.execute(bq)
  538. cp_rows = cursor.fetchall()
  539. #print(cp_rows)
  540. max1Ub = ["Max1 Weight."]
  541. min1Ub = ["Min1 Weight."]
  542. max2Ub = ["Max2 Weight."]
  543. min2Ub = ["Min2 Weight."]
  544. avg1Ub = ["Avg1 Weight."]
  545. avg2Ub = ["Avg2 Weight."]
  546. r1Ub = ["R1"]
  547. r2Ub = ["R2"]
  548. sd1 = ["sd1"]
  549. sd2 = ["sd2"]
  550. w1 = ["Weight(1) std"]
  551. w2 = ["Weight(2) std"]
  552. unitW = ["Unit Weight"]
  553. op = ["Operator"]
  554. press = ["Press M/C"]
  555. holes = ["Hole (mm)"]
  556. dias = ["Dia (mm)"]
  557. qtys = ["QTY"]
  558. lotnos = ["Lot no."]
  559. inspecs = ["Inspection Date"]
  560. for r in cp_rows:
  561. max1Ub.append(r.maxsize1)
  562. min1Ub.append(r.minsize1)
  563. max2Ub.append(r.maxsize2)
  564. min2Ub.append(r.minsize2)
  565. avg1Ub.append(r.avgSize1)
  566. avg2Ub.append(r.avgSize2)
  567. r1Ub.append(r.maxsize1 - r.minsize1)
  568. r2Ub.append(r.maxsize2 - r.minsize2)
  569. sd1.append(r.sdsize1)
  570. sd2.append(r.sdsize2)
  571. w1.append(r.PressWeight_1)
  572. w2.append(r.PressWeight_2)
  573. unitW.append(r.UWeight)
  574. op.append(r.empids)
  575. press.append(r.Press_Ton)
  576. holes.append(r.Mold_D)
  577. dias.append(r.Center_D)
  578. qtys.append(r.PO_Qty)
  579. lotnos.append(r.lot_no)
  580. #print("xdfdsf = "+r.minca.strftime("%m/%d/%Y %H:%M:%S"))
  581. inspecs.append(r.minca.strftime("%m/%d/%Y %H:%M:%S"))
  582. dataArray = [
  583. max1Ub, #0
  584. min1Ub, #1
  585. max2Ub, #2
  586. min2Ub, #3
  587. avg1Ub, #4
  588. avg2Ub,#5
  589. r1Ub, #6
  590. r2Ub,
  591. sd1,
  592. sd2,#9
  593. w1,
  594. w2,
  595. unitW, #12
  596. op,
  597. press,
  598. holes,
  599. dias,
  600. qtys,
  601. lotnos,
  602. inspecs
  603. ]
  604. #print(dataArray)
  605. startRow = 20
  606. startCol = 2
  607. for i, row in enumerate(dataArray):
  608. for j, o in enumerate(row):
  609. cell = ws.cell(startRow + i, startCol +j)
  610. cell.value = o
  611. applyStyleName(cell, "allborder")
  612. lc = LineChart()
  613. lc.title = "Result CP Press Chart"
  614. lc.y_axis.title = "Press.weight (g)"
  615. lc.x_axis.title = "Lot No."
  616. lc.width = len(dataArray[0]) * 2.5
  617. #print("width ", lc.width)
  618. if lc.width <= 5:
  619. lc.width = 10
  620. enables = [0, 1,2,3,4,5, 10,11 ]
  621. for r in enables:
  622. data = Reference(ws, min_row=startRow+r, max_row=startRow+r,
  623. min_col=startCol, max_col=startCol + len(dataArray[0]))
  624. lc.add_data(data, from_rows=True, titles_from_data=True)
  625. lots = Reference(ws, min_row=startRow + 18, max_row=startRow+18, min_col=startCol+1, max_col=startCol+len(dataArray[0]) )
  626. lc.set_categories(lots)
  627. for se in lc.series:
  628. se.graphicalProperties.line.noFill = True
  629. se.marker.symbol = "auto"
  630. lc.series[6].graphicalProperties.line.noFill = False
  631. lc.series[7].graphicalProperties.line.noFill = False
  632. font_test = drawingText.Font(typeface='Calibri')
  633. cp = CharacterProperties(latin=font_test, sz=1000)
  634. pp = ParagraphProperties(defRPr=cp)
  635. cp1 = CharacterProperties(latin=font_test, sz=1400)
  636. pp1 = ParagraphProperties(defRPr=cp1)
  637. lc.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  638. lc.y_axis.title.tx.rich.p[0].pPr = pp# Works
  639. lc.title.tx.rich.p[0].pPr = pp1# Works!
  640. lc.legend.position = "t"
  641. lc.marker = True
  642. ws.add_chart(lc, "B2")
  643. #create press thickness
  644. #find max, min
  645. sizes = {}
  646. stdSizes = {}
  647. #select distinct lot no
  648. bq = '''select ds.code,\
  649. ds.lot_no, max(ds.tpresssize) maxsize1, min(ds.tpresssize) minsize1,\
  650. avg(ds.tpresssize) avgSize1 , stdev(ds.tpresssize) sdsize1, \
  651. empids =
  652. STUFF((SELECT ',' + str(emp_id)
  653. FROM data_ms b
  654. WHERE b.lot_no = ds.lot_no
  655. group by emp_id
  656. FOR XML PATH('')), 1, 2, ''), \
  657. min(ds.created_at) minca,\
  658. pp.Mold_D, pp.Center_D, pp.Press_Ton, pp.PO_Qty, pp.Press_T \
  659. from data_ms ds \
  660. inner join AllProduct_PressPosition_PressWeight pp on pp.ProductCode = Replace('{0}', '-', '') \
  661. and pp.Lot_No = ds.lot_no \
  662. where \
  663. ds.code = '{0}' and ( (ds.size1 > 0) or (ds.size2 > 0) or (ds.tpresssize > 0)) \
  664. group by ds.code, ds.lot_no, pp.Press_Ton, pp.PO_Qty, pp.Mold_D, pp.Center_D, pp.Press_T'''.format(codeno)
  665. #print("bq ", bq)
  666. cursor.execute(bq)
  667. cp_rows = cursor.fetchall()
  668. #print(cp_rows)
  669. max1Ub = ["Max1 Weight."]
  670. min1Ub = ["Min1 Weight."]
  671. avg1Ub = ["Avg1 Weight."]
  672. r1Ub = ["R1"]
  673. sd1 = ["sd1"]
  674. w1 = ["Weight(1) std"]
  675. unitW = ["Unit Weight"]
  676. press_t = ["T Press"]
  677. op = ["Operator"]
  678. press = ["Press M/C"]
  679. holes = ["Hole (mm)"]
  680. dias = ["Dia (mm)"]
  681. qtys = ["QTY"]
  682. lotnos = ["Lot no."]
  683. inspecs = ["Inspection Date"]
  684. for r in cp_rows:
  685. max1Ub.append(r.maxsize1)
  686. min1Ub.append(r.minsize1)
  687. avg1Ub.append(r.avgSize1)
  688. r1Ub.append(r.maxsize1 - r.minsize1)
  689. sd1.append(r.sdsize1)
  690. press_t.append(r.Press_T)
  691. op.append(r.empids)
  692. press.append(r.Press_Ton)
  693. holes.append(r.Mold_D)
  694. dias.append(r.Center_D)
  695. qtys.append(r.PO_Qty)
  696. lotnos.append(r.lot_no)
  697. #print("xdfdsf = "+r.minca.strftime("%m/%d/%Y %H:%M:%S"))
  698. inspecs.append(r.minca.strftime("%m/%d/%Y %H:%M:%S"))
  699. dataArray = [
  700. max1Ub, #0
  701. min1Ub, #1
  702. avg1Ub, #2
  703. r1Ub, #3
  704. sd1, #4
  705. press_t, #5
  706. op,
  707. press,
  708. holes,
  709. dias,
  710. qtys,
  711. lotnos,
  712. inspecs
  713. ]
  714. #print(dataArray)
  715. startRow = 20
  716. startCol = 15
  717. for i, row in enumerate(dataArray):
  718. for j, o in enumerate(row):
  719. cell = ws.cell(startRow + i, startCol +j)
  720. cell.value = o
  721. applyStyleName(cell, "allborder")
  722. lc = LineChart()
  723. lc.title = "Result CP Thickness press Chart"
  724. lc.y_axis.title = "TPress (mm)"
  725. lc.x_axis.title = "Lot No."
  726. lc.width = len(dataArray[0]) * 2.5
  727. #print("width ", lc.width)
  728. if lc.width <= 5:
  729. lc.width = 10
  730. enables = [0, 1,2,3,4,5 ]
  731. for r in enables:
  732. data = Reference(ws, min_row=startRow+r, max_row=startRow+r,
  733. min_col=startCol, max_col=startCol + len(dataArray[0]))
  734. lc.add_data(data, from_rows=True, titles_from_data=True)
  735. lots = Reference(ws, min_row=startRow + 11, max_row=startRow+11, min_col=startCol+1, max_col=startCol+len(dataArray[0]) )
  736. lc.set_categories(lots)
  737. for se in lc.series:
  738. se.graphicalProperties.line.noFill = True
  739. se.marker.symbol = "auto"
  740. lc.series[5].graphicalProperties.line.noFill = False
  741. #lc.series[7].graphicalProperties.line.noFill = False
  742. font_test = drawingText.Font(typeface='Calibri')
  743. cp = CharacterProperties(latin=font_test, sz=1000)
  744. pp = ParagraphProperties(defRPr=cp)
  745. cp1 = CharacterProperties(latin=font_test, sz=1400)
  746. pp1 = ParagraphProperties(defRPr=cp1)
  747. lc.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  748. lc.y_axis.title.tx.rich.p[0].pPr = pp# Works
  749. lc.title.tx.rich.p[0].pPr = pp1# Works!
  750. lc.legend.position = "t"
  751. lc.marker = True
  752. ws.add_chart(lc, "O2")
  753. def applyStyleName(cell, styleName, format=None):
  754. cell.style = styleName
  755. if format is not None:
  756. #print(format)
  757. cell.number_format = format
  758. def createChart(codeno, filters):
  759. global cursor
  760. global wb
  761. global dateStyle
  762. global codeMap
  763. #ws = wb.create_sheet("chart2")
  764. #find lot in a codeno
  765. sql = generateSQLDataMS(codeno, filters)
  766. sql2 = findProductPress(codeno)
  767. #print(filters)
  768. #print(sql)
  769. cursor.execute(sql)
  770. row = cursor.fetchall()
  771. cursor.execute(sql2)
  772. row2 = cursor.fetchall()
  773. temp = {}
  774. #map data into lotno list
  775. #find max, min
  776. sizes = {}
  777. stdSizes = {}
  778. pressType1 = pressType2 = ""
  779. for k in row2:
  780. if k.PressType_1 != "" and k.PressType_1 is not None:
  781. sizes["size1"] = []
  782. stdSizes["size1"] = k
  783. pressType1 = k.PressType_1
  784. if k.PressType_2 != "" and k.PressType_2 is not None:
  785. sizes["size2"] = []
  786. stdSizes["size2"] = k
  787. pressType2 = k.PressType_2
  788. if k.Press_T != "" and k.Press_T is not None:
  789. sizes["tpresssize"] = []
  790. stdSizes["tpresssize"] = k
  791. pressType3 = k.Press_T
  792. for r in row:
  793. #print(r)
  794. if r.lot_no not in temp:
  795. temp[r.lot_no] = []
  796. temp[r.lot_no].append(r)
  797. for k,v in sizes.items():
  798. sizes[k].append(getattr(r, k, None))
  799. #filter only dimensions in master
  800. #print("TEMP == \n")
  801. #print(sizes)
  802. avgSize = {}
  803. minSize = {}
  804. maxSize = {}
  805. for k, v in sizes.items():
  806. if len(v) > 0 and v[0] is not None:
  807. avgSize[k] = sum(v)/len(v)
  808. minSize[k] = min(v)
  809. maxSize[k] = max(v)
  810. #print("avg size \n",avgSize)
  811. #print("min size \n",minSize)
  812. #print("max size \n",maxSize)
  813. for k1,v1 in temp.items():
  814. #print("\nlot %s \n" %( k1))
  815. ws = wb.create_sheet("lot %s actual" %(k1))
  816. i = 0
  817. bp = 1
  818. for k,v in sizes.items():
  819. #print("%s actual" % (k))
  820. data = [
  821. ["Max (%s) size" % (k) ],
  822. ['Min'],
  823. ['Actual'],
  824. ['No.'],
  825. ['Lot No.']
  826. ]
  827. nrow = len(data)
  828. for v2 in v1:
  829. #print("std size ", stdSizes[keySize])
  830. max_min = 0
  831. if k == "size1":
  832. max_min = stdSizes[k].PressWeight_1
  833. if k == "size2":
  834. max_min = stdSizes[k].PressWeight_2
  835. if k == "tpresssize":
  836. max_min = stdSizes[k].Press_T
  837. if max_min is None:
  838. continue
  839. if k == "size1" or k == "size2":
  840. maxMaster = minMaster = float(max_min)
  841. else:
  842. maxMaster = stdSizes[k].Press_T + stdSizes[k].Press_T_Tol
  843. minMaster = stdSizes[k].Press_T - stdSizes[k].Press_T_Tol
  844. data[0].append(maxMaster)
  845. data[1].append(minMaster)
  846. data[2].append(getattr(v2, k))
  847. data[3].append(v2.row_no)
  848. data[4].append(v2.lot_no)
  849. #print(data)
  850. #gen chart
  851. #print("min col ", bp)
  852. wsRows = tuple(ws.iter_rows(min_row=1, max_row=len(data), min_col=bp, max_col= (bp - 1)+len(data[0])))
  853. for i in range(len(wsRows)):
  854. for j in range(len(wsRows[i])):
  855. #print(i,j)
  856. #data[i][j])
  857. #print(wsRows[i][j])
  858. wsRows[i][j].value = data[i][j]
  859. if i != 3:
  860. wsRows[i][j].number_format = '0.00'
  861. bd = Side(style='medium', color="000000")
  862. wsRows[i][j].border = Border(left=bd, top=bd, right=bd, bottom=bd)
  863. cpos = utils.get_column_letter(bp) + "10"
  864. font_test = drawingText.Font(typeface='Calibri')
  865. cp = CharacterProperties(latin=font_test, sz=1000)
  866. pp = ParagraphProperties(defRPr=cp)
  867. cp1 = CharacterProperties(latin=font_test, sz=1400)
  868. pp1 = ParagraphProperties(defRPr=cp1)
  869. c1 = LineChart()
  870. maxValues = Reference(ws, min_row=1, min_col=bp+1, max_row=1, max_col=(bp-1)+len(data[0]) )
  871. maxSerie = Series(maxValues, title="Max")
  872. maxSerie.graphicalProperties.line.solidFill = "FF0000"
  873. c1.append(maxSerie)
  874. minValues = Reference(ws, min_row=2, min_col=bp+1, max_row=2, max_col=(bp-1)+len(data[0]) )
  875. minSerie = Series(minValues, title="Min")
  876. minSerie.graphicalProperties.line.solidFill = "000000"
  877. c1.append(minSerie)
  878. acValues = Reference(ws, min_row=3, min_col=bp+1, max_row=3, max_col=(bp-1)+len(data[0]) )
  879. acSerie = Series(acValues, title="Actual")
  880. acSerie.marker.graphicalProperties.solidFill = "4f81bd" # Marker filling
  881. acSerie.graphicalProperties.line.solidFill = "4f81bd"
  882. acSerie.marker.symbol = "circle"
  883. c1.append(acSerie)
  884. lots = Reference(ws,min_row=4, min_col=bp+1, max_row=4, max_col=(bp-1)+len(data[0]))
  885. c1.set_categories(lots)
  886. c1.width = len(data[0])*1.8
  887. if k == "size1":
  888. c1.title = "%s (X Bar) " % (pressType1)
  889. if k == "size2":
  890. c1.title = "%s (X Bar) " % (pressType2)
  891. if k == "tpresssize":
  892. c1.title = "%s (X Bar) " % ("Thickness press")
  893. c1.y_axis.title = "Value(mm.)"
  894. c1.x_axis.title = "Item No."
  895. c1.x_axis.title.tx.rich.p[0].pPr = pp# Works!
  896. c1.y_axis.title.tx.rich.p[0].pPr = pp# Works!
  897. c1.title.tx.rich.p[0].pPr = pp1# Works!
  898. c1.legend.position = "b"
  899. ws.add_chart(c1, cpos)
  900. bp += len(data[0]) + 2
  901. #print()
  902. #print("M"+str(bp))
  903. #bp += coEndCell[1]+1+10
  904. #print(ws.calculate_dimension())
  905. #create each size table and chart types
  906. # actual chart
  907. def createExcel(lotno, staff, man, env="dev"):
  908. # global cursor
  909. # global wb
  910. # global dateStyle
  911. cnxn = create_db_connection(env)
  912. #wb["Styles"].sheet_state = 'hidden'
  913. ws = wb["Cert"]
  914. codeString = ""
  915. qMsData = """
  916. select * from data
  917. where lot_no = '{0}'
  918. order by updated_at desc, row_no asc
  919. """.format(lotno)
  920. cursor.execute(f"select * from data where lot_no ='{lotno}' order by created_at desc")
  921. r2 = cursor.fetchall()
  922. types = []
  923. for r20 in r2:
  924. if r20.r_type not in types:
  925. types.append(r20.r_type)
  926. #print(types)
  927. cursor.execute(qMsData)
  928. rows = cursor.fetchall()
  929. startRow = 19
  930. codeno = ""
  931. for r in rows:
  932. codeno = r.code
  933. if codeno.find('-') != -1:
  934. codeString = codeno
  935. else:
  936. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  937. break
  938. #print(ws._charts)
  939. cust = findCustomer(codeno.replace("-", ""), lotno)
  940. ws["C8"] = codeno.replace("-", "")
  941. lc = lotno[0:3].lower() + lotno[3:len(lotno)].upper()
  942. ws["C11"] = lc
  943. #print(cust)
  944. cond1 = getConditionRef(cust[0].MI14)
  945. cond2 = getConditionRef(cust[0].MI15)
  946. c1text = ""
  947. for c in cond1:
  948. c1text = c.TIT4NE
  949. c2text = ""
  950. for c in cond2:
  951. c2text = c.TIT4NE
  952. #print(c1text, c2text)
  953. mi17 = ""
  954. if cust[0].MI17 is None:
  955. mi17 = "None"
  956. else:
  957. mi17 = cust[0].MI17
  958. mi16 = str(int(cust[0].MI16)).replace("\\", "")
  959. o1 = cust[0].MI18
  960. o2 = cust[0].MI19
  961. if o2 < o1:
  962. ot = o1
  963. o1 = o2
  964. o2 = ot
  965. mi21 = ""
  966. if cust[0].MI21 is None:
  967. mi21 = "None"
  968. else:
  969. mi21 = cust[0].MI21
  970. mi20 = str(int(cust[0].MI20)).replace("\\", "")
  971. o3 = cust[0].MI22
  972. o4 = cust[0].MI23
  973. if o3 < o4:
  974. ot = o3
  975. o3 = o4
  976. o4 = ot
  977. ws["C16"] = "Hardness: "+ c2text + " " +c1text + f", {types[0]}: {o1:.2f} - {o2:.2f} ({mi16} {mi17.upper()})"
  978. applyStyleName(ws["C16"], "defaultfont")
  979. if cust:
  980. ws["C7"] = cust[0].customer
  981. ws["C10"] = cust[0].sizestring
  982. ws["C9"] = cust[0].spec
  983. #print(cust[0].PRO5)
  984. #print(cust[0].PRO27)
  985. ws["C12"] = str(int(cust[0].PRO5 - cust[0].PRO27)) + " Pcs"
  986. ws["C45"] = staff
  987. ws["G45"] = man
  988. rn = []
  989. for r in rows:
  990. isNG = False
  991. if r.r_type != types[0]:
  992. continue
  993. if r.row_no not in rn:
  994. rn.append(r.row_no)
  995. else:
  996. continue
  997. ws.cell(column=3, row=startRow, value=int(r.row_no))
  998. applyStyleName(ws.cell(column=3, row=startRow), "allborder", "0")
  999. codeno = r.code
  1000. if codeno.find('-') != -1:
  1001. codeString = codeno
  1002. else:
  1003. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  1004. for i in range(0, r.ndata):
  1005. ws.cell(column=3 + i + 1, row=startRow, value=getattr(r, f"p{i+1}"))
  1006. applyStyleName(ws.cell(column=3 + i + 1, row=startRow), "allborder")
  1007. applyStyleName(ws.cell(column=6, row=startRow), "allborder")
  1008. ws.cell(column=7, row=startRow, value=r.avg)
  1009. applyStyleName(ws.cell(column=7, row=startRow), "allborder")
  1010. ws.cell(column=8, row=startRow, value=r.rgrade)
  1011. applyStyleName(ws.cell(column=8, row=startRow), "allborder")
  1012. startRow += 1
  1013. lastRow = r
  1014. if len(types) < 2:
  1015. #ws.delete_rows(26, 5)
  1016. ws.row_dimensions[26].hidden = True
  1017. ws.row_dimensions[27].hidden = True
  1018. ws.row_dimensions[28].hidden = True
  1019. ws.row_dimensions[29].hidden = True
  1020. ws.row_dimensions[30].hidden = True
  1021. else:
  1022. ws["C26"] = "Hardness: "+ c2text + " " +c1text + f", {types[1]}: {o3:.2f} - {o4:.2f} ({mi20} {mi21.upper()})"
  1023. startRow = 29
  1024. rn = []
  1025. for r in rows:
  1026. isNG = False
  1027. if r.r_type != types[1]:
  1028. continue
  1029. if r.row_no not in rn:
  1030. rn.append(r.row_no)
  1031. else:
  1032. continue
  1033. ws.cell(column=3, row=startRow, value=int(r.row_no))
  1034. applyStyleName(ws.cell(column=3, row=startRow), "allborder", "0")
  1035. codeno = r.code
  1036. if codeno.find('-') != -1:
  1037. codeString = codeno
  1038. else:
  1039. codeString = codeno[0] + "-" + codeno[1:5] + "-" + codeno[5:9] + "-" + codeno[9:10]
  1040. for i in range(0, r.ndata):
  1041. ws.cell(column=3 + i + 1, row=startRow, value=getattr(r, f"p{i+1}"))
  1042. applyStyleName(ws.cell(column=3 + i + 1, row=startRow), "allborder")
  1043. applyStyleName(ws.cell(column=6, row=startRow), "allborder")
  1044. ws.cell(column=7, row=startRow, value=r.avg)
  1045. applyStyleName(ws.cell(column=7, row=startRow), "allborder")
  1046. ws.cell(column=8, row=startRow, value=r.rgrade)
  1047. applyStyleName(ws.cell(column=8, row=startRow), "allborder")
  1048. startRow += 1
  1049. lastRow = r
  1050. #ws["C13"] = lastRow.created_at
  1051. ws["C13"] = datetime.datetime.now()
  1052. ws["C13"].number_format = "mmmm,d yyyy"
  1053. ut = int(time.time())
  1054. filename = f"hardness_{lotno.replace('-', '')}_{ut}.xlsx"
  1055. outfile = os.path.join(settings.MEDIA_ROOT, 'excel', filename)
  1056. # Ensure the directory exists
  1057. os.makedirs(os.path.dirname(outfile), exist_ok=True)
  1058. wb.save(filename=outfile)
  1059. return os.path.join('excel', filename) # Return relative path for media URL usage
  1060. if __name__ == "__main__":
  1061. env = sys.argv[1]
  1062. #code = sys.argv[2]
  1063. lotno = sys.argv[2]
  1064. staff = sys.argv[3]
  1065. man = sys.argv[4]
  1066. #print(len(sys.argv))
  1067. global cnxn
  1068. global cursor
  1069. if env == "prod":
  1070. cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=192.168.0.253;DATABASE=OB2011DB;UID=user1;PWD=1234')
  1071. cursor = cnxn.cursor()
  1072. else:
  1073. cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=OB2011DB;UID=admin;PWD=1234')
  1074. cursor = cnxn.cursor()
  1075. #print("code is "+code)
  1076. createExcel(lotno, staff, man)
  1077. #createXRangeChart(code, df)
  1078. ut = int(time.time())
  1079. filename = "hardness{0}_{1}.xlsx".format(lotno.replace("-", ""), ut)
  1080. outfile = './public/excel/'+filename
  1081. wb.save(filename = outfile)
  1082. print(filename)