控制网复测平面基准归算程序(包含控制网复测平面基准计算,平面控制网稳定性计算,水准测段高差稳定计算三个程序功能)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GCExport.py 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. import time
  2. import openpyxl
  3. import pandas as pd
  4. import sqlite3
  5. import os
  6. from PySide6.QtWidgets import QMessageBox
  7. from openpyxl.styles import Font, NamedStyle, Alignment
  8. from openpyxl.utils.dataframe import dataframe_to_rows
  9. from openpyxl import Workbook
  10. def export_combined_data(ui, utf_en, db_path, export_folder, file_name):
  11. try:
  12. # 解码 utf_en
  13. decoded_utf_en = utf_en.decode('utf-8') if isinstance(utf_en, bytes) else utf_en
  14. # 创建一个新的 Excel 工作簿
  15. wb = Workbook()
  16. # 导出初始数据到第一个 sheet
  17. ws_initial = wb.active
  18. ws_initial.title = "初始高差数据"
  19. # 合并指定的单元格
  20. merge_cells = ['A1:B1', 'D1:E1', 'F1:G1', 'I1:J1']
  21. for cell_range in merge_cells:
  22. ws_initial.merge_cells(cell_range)
  23. # 设置合并单元格后的居中对齐
  24. for cell_range in merge_cells:
  25. cell = ws_initial[cell_range.split(':')[0]]
  26. cell.alignment = Alignment(horizontal='center', vertical='center')
  27. # 连接数据库
  28. conn = sqlite3.connect(db_path)
  29. cursor = conn.cursor()
  30. # 查询 GC_Input_Param 表获取 ObservationLevel, Last_ResultName, New_ResultName, Ms_Station 字段
  31. query_observation_level = "SELECT ObservationLevel, Last_ResultName, New_ResultName, Ms_Station FROM GC_Input_Param WHERE TableName=?"
  32. cursor.execute(query_observation_level, (utf_en,))
  33. result = cursor.fetchone()
  34. if result:
  35. observation_level, last_result_name, new_result_name, ms_station = result
  36. else:
  37. observation_level = "未找到"
  38. last_result_name = "未找到"
  39. new_result_name = "未找到"
  40. ms_station = "未找到"
  41. # 填写表头信息
  42. ws_initial['A1'] = '观测等级'
  43. ws_initial['C1'] = observation_level # 将 ObservationLevel 写入 C1 单元格
  44. ws_initial['A2'] = '序号'
  45. ws_initial['B2'] = '起点'
  46. ws_initial['C2'] = '终点'
  47. ws_initial['D2'] = '高差(m)'
  48. ws_initial['E2'] = '路线长(km)'
  49. ws_initial['F1'] = '测站全中误差(mm)'
  50. ws_initial['F2'] = '序号'
  51. ws_initial['G2'] = '起点'
  52. ws_initial['H2'] = '终点'
  53. ws_initial['I2'] = '高差(m)'
  54. ws_initial['J2'] = '路线长(km)'
  55. # 写入 Last_ResultName, New_ResultName, Ms_Station 到相应的单元格
  56. ws_initial['D1'] = last_result_name
  57. ws_initial['I1'] = new_result_name
  58. ws_initial['H1'] = ms_station
  59. # 设置 H1 单元格的数值格式为保留两位小数
  60. ws_initial['H1'].number_format = '0.00'
  61. # 查询数据库表为DataFrame,添加 TableName 条件
  62. query = "SELECT * FROM GC_Input_Point WHERE TableName=?"
  63. cursor.execute(query, (utf_en,))
  64. rows = cursor.fetchall()
  65. # 获取列名
  66. column_names = [description[0] for description in cursor.description]
  67. # 定义需要的列索引
  68. last_id_index = column_names.index('Last_ID')
  69. last_spname_index = column_names.index('Last_SPName')
  70. last_epname_index = column_names.index('Last_EPName')
  71. last_hdiff_index = column_names.index('Last_HDiff')
  72. last_rlen_index = column_names.index('Last_RLen')
  73. new_id_index = column_names.index('New_ID')
  74. new_spname_index = column_names.index('New_SPName')
  75. new_epname_index = column_names.index('New_EPName')
  76. new_hdiff_index = column_names.index('New_HDiff')
  77. new_rlen_index = column_names.index('New_RLen')
  78. # 填充数据到Excel
  79. for idx, row in enumerate(rows, start=3):
  80. ws_initial.cell(row=idx, column=1, value=row[last_id_index])
  81. ws_initial.cell(row=idx, column=2, value=row[last_spname_index])
  82. ws_initial.cell(row=idx, column=3, value=row[last_epname_index])
  83. ws_initial.cell(row=idx, column=4, value=row[last_hdiff_index])
  84. ws_initial.cell(row=idx, column=5, value=row[last_rlen_index])
  85. ws_initial.cell(row=idx, column=6, value=row[new_id_index])
  86. ws_initial.cell(row=idx, column=7, value=row[new_spname_index])
  87. ws_initial.cell(row=idx, column=8, value=row[new_epname_index])
  88. ws_initial.cell(row=idx, column=9, value=row[new_hdiff_index])
  89. ws_initial.cell(row=idx, column=10, value=row[new_rlen_index])
  90. # 设置 D, E, I, J 列为强制保留六位小数
  91. ws_initial.cell(row=idx, column=4).number_format = '0.000000'
  92. ws_initial.cell(row=idx, column=5).number_format = '0.000000'
  93. ws_initial.cell(row=idx, column=9).number_format = '0.000000'
  94. ws_initial.cell(row=idx, column=10).number_format = '0.000000'
  95. # 设置B,C,G,H的列宽为9.25
  96. ws_initial.column_dimensions['B'].width = 9.25
  97. ws_initial.column_dimensions['C'].width = 9.25
  98. ws_initial.column_dimensions['G'].width = 9.25
  99. ws_initial.column_dimensions['H'].width = 9.25
  100. # 设置 D, E, I, J 列的列宽为11.5
  101. ws_initial.column_dimensions['D'].width = 11.5
  102. ws_initial.column_dimensions['E'].width = 11.5
  103. ws_initial.column_dimensions['I'].width = 11.5
  104. ws_initial.column_dimensions['J'].width = 11.5
  105. # 导出成果数据到第二个 sheet
  106. ws_result = wb.create_sheet(title="成果高差数据")
  107. # 查询数据库表为DataFrame,添加 TableName 条件
  108. query = "SELECT * FROM GC_Output_Point WHERE TableName=?"
  109. df = pd.read_sql_query(query, conn, params=(utf_en,))
  110. # 检查是否有匹配的数据
  111. if df.empty:
  112. QMessageBox.warning(ui, '警告', '没有找到匹配的数据进行导出')
  113. conn.close()
  114. return
  115. # 假设 TableName 字段是以字节序列存储的 UTF-8 编码字符串
  116. if 'TableName' in df.columns:
  117. try:
  118. df['TableName'] = df['TableName'].apply(lambda x: x.decode('utf-8') if isinstance(x, bytes) else x)
  119. except Exception as e:
  120. QMessageBox.critical(ui, '错误', f'TableName 字段解码失败: {str(e)}')
  121. conn.close()
  122. return
  123. # 删除 TableName 列
  124. if 'TableName' in df.columns:
  125. df.drop(columns=['TableName'], inplace=True)
  126. # new HDiff 保留小数点后6位
  127. if 'New_HDiff' in df.columns:
  128. df['New_HDiff'] = df['New_HDiff'].round(6)
  129. # New_RLen 保留小数点后6位
  130. if 'New_RLen' in df.columns:
  131. df['New_RLen'] = df['New_RLen'].round(6)
  132. # Correct_Factor 保留小数点后2位
  133. if 'Correct_Factor' in df.columns:
  134. df['Correct_Factor'] = df['Correct_Factor'].round(2)
  135. # Period_Diff 保留小数点后2位
  136. if 'Period_Diff' in df.columns:
  137. df['Period_Diff'] = df['Period_Diff'].round(2)
  138. # 重命名指定的列
  139. column_mapping = {
  140. 'New_ID': '序号',
  141. 'New_ResultName': '结果期数',
  142. 'New_SPName': '起点',
  143. 'New_EPName': '终点',
  144. 'New_HDiff': '高差',
  145. 'New_RLen': '路线长',
  146. 'Correct_Factor': '修正数',
  147. 'Period_Diff': '期间差异',
  148. 'Dis_Ass': '变形判定'
  149. }
  150. df.rename(columns=column_mapping, inplace=True)
  151. # 查询 GC_Input_Param 表获取 Correct_Factor 字段
  152. query_param = "SELECT Correct_Factor FROM GC_Input_Param WHERE TableName=?"
  153. correct_factor_df = pd.read_sql_query(query_param, conn, params=(utf_en,))
  154. correct_factor = correct_factor_df.iloc[0]['Correct_Factor']
  155. # 在E1单元格添加内容“修正系数”
  156. ws_result.cell(row=1, column=1, value="序号")
  157. ws_result.cell(row=1, column=2, value="结果期数")
  158. ws_result.cell(row=1, column=3, value="起点")
  159. ws_result.cell(row=1, column=4, value="终点")
  160. ws_result.cell(row=1, column=5, value="修正系数")
  161. ws_result.cell(row=1, column=6, value=correct_factor)
  162. ws_result.cell(row=1, column=7, value="修正数")
  163. ws_result.cell(row=1, column=8, value="期间差异")
  164. ws_result.cell(row=1, column=9, value="变形判定")
  165. # 将 DataFrame 写入工作表
  166. for r in dataframe_to_rows(df, index=False, header=True):
  167. ws_result.append(r)
  168. # 定义自定义样式
  169. style_0_000000 = NamedStyle(name="style_0_000000", number_format='0.000000')
  170. style_0_00 = NamedStyle(name="style_0_00", number_format='0.00')
  171. # 添加样式到工作簿
  172. wb.add_named_style(style_0_000000)
  173. wb.add_named_style(style_0_00)
  174. # 应用样式到相应列
  175. hdiff_col_index = df.columns.get_loc('高差') + 1 # 获取“高差”列的索引(+1 因为 Excel 列索引从 1 开始)
  176. rlen_col_index = df.columns.get_loc('路线长') + 1 # 获取“路线长”列的索引
  177. correct_factor_col_index = df.columns.get_loc('修正数') + 1 # 获取“修正数”列的索引
  178. period_diff_col_index = df.columns.get_loc('期间差异') + 1 # 获取“期间差异”列的索引
  179. for row in range(2, ws_result.max_row + 1): # 从第二行开始,因为第一行为标题行
  180. ws_result.cell(row=row, column=hdiff_col_index).style = style_0_000000
  181. ws_result.cell(row=row, column=rlen_col_index).style = style_0_000000
  182. ws_result.cell(row=row, column=correct_factor_col_index).style = style_0_00
  183. ws_result.cell(row=row, column=period_diff_col_index).style = style_0_00
  184. # 设置 Dis_Ass 列为“变形”的行的字体颜色为红色
  185. red_font = Font(color="FF0000")
  186. dis_ass_col_index = df.columns.get_loc('变形判定') + 1 # 获取“变形判定”列的索引
  187. for row in range(2, ws_result.max_row + 1): # 从第二行开始,因为第一行为标题行
  188. cell_value = ws_result.cell(row=row, column=dis_ass_col_index).value
  189. if cell_value == '变形':
  190. for col in range(1, ws_result.max_column + 1):
  191. ws_result.cell(row=row, column=col).font = red_font
  192. # 设置列宽
  193. ws_result.column_dimensions['E'].width = 12
  194. ws_result.column_dimensions['F'].width = 12
  195. # 保存 Excel 文件之前添加单元格合并操作
  196. merge_cells = ['A1:A2', 'B1:B2', 'C1:C2', 'D1:D2', 'G1:G2', 'H1:H2', 'I1:I2']
  197. for cell_range in merge_cells:
  198. ws_result.merge_cells(cell_range)
  199. # 设置合并单元格后的居中对齐
  200. for cell_range in merge_cells:
  201. cell = ws_result[cell_range.split(':')[0]]
  202. cell.alignment = Alignment(horizontal='center', vertical='center')
  203. # 获取当前时间并格式化为字符串,例如:20231010_143000
  204. timestamp = time.strftime("%Y%m%d", time.localtime())
  205. # 设置文件名
  206. excel_filepath = os.path.join(export_folder, file_name)
  207. # 保存 Excel 文件
  208. wb.save(excel_filepath)
  209. QMessageBox.information(ui, '成功', f'数据文件已导出到 {export_folder}')
  210. except Exception as e:
  211. if isinstance(e, PermissionError) or (isinstance(e, OSError) and e.errno == 13):
  212. QMessageBox.critical(ui, '错误', '请确认文件没有被其他程序(如Excel、文本编辑器等)打开。')
  213. else:
  214. QMessageBox.critical(ui, '错误', f'导出过程中发生错误: {str(e)}')
  215. print(e)
  216. finally:
  217. # 关闭数据库连接
  218. conn.close()
  219. def export_example_data(ui, utf_en, db_path, export_folder, file_name):
  220. try:
  221. # 解码 utf_en
  222. decoded_utf_en = utf_en.decode('utf-8') if isinstance(utf_en, bytes) else utf_en
  223. # 创建一个新的 Excel 工作簿
  224. wb = Workbook()
  225. ws = wb.active
  226. # 合并指定的单元格
  227. merge_cells = ['A1:B1', 'D1:E1', 'F1:G1', 'I1:J1']
  228. for cell_range in merge_cells:
  229. ws.merge_cells(cell_range)
  230. # 设置合并单元格后的居中对齐
  231. for cell_range in merge_cells:
  232. cell = ws[cell_range.split(':')[0]]
  233. cell.alignment = Alignment(horizontal='center', vertical='center')
  234. # 连接数据库
  235. conn = sqlite3.connect(db_path)
  236. cursor = conn.cursor()
  237. # 查询 GC_Input_Param 表获取 ObservationLevel, Last_ResultName, New_ResultName, Ms_Station 字段
  238. query_observation_level = "SELECT ObservationLevel, Last_ResultName, New_ResultName, Ms_Station FROM GC_Input_Param WHERE TableName=?"
  239. cursor.execute(query_observation_level, (utf_en,))
  240. result = cursor.fetchone()
  241. if result:
  242. observation_level, last_result_name, new_result_name, ms_station = result
  243. else:
  244. observation_level = "未找到"
  245. last_result_name = "未找到"
  246. new_result_name = "未找到"
  247. ms_station = "未找到"
  248. # 填写表头信息
  249. ws['A1'] = '观测等级'
  250. ws['C1'] = observation_level # 将 ObservationLevel 写入 C1 单元格
  251. ws['A2'] = '序号'
  252. ws['B2'] = '起点'
  253. ws['C2'] = '终点'
  254. ws['D2'] = '高差(m)'
  255. ws['E2'] = '路线长(km)'
  256. ws['F1'] = '测站全中误差(mm)'
  257. ws['F2'] = '序号'
  258. ws['G2'] = '起点'
  259. ws['H2'] = '终点'
  260. ws['I2'] = '高差(m)'
  261. ws['J2'] = '路线长(km)'
  262. # 写入 Last_ResultName, New_ResultName, Ms_Station 到相应的单元格
  263. ws['D1'] = last_result_name
  264. ws['I1'] = new_result_name
  265. ws['H1'] = ms_station
  266. # 设置 H1 单元格的数值格式为保留两位小数
  267. ws['H1'].number_format = '0.00'
  268. # 连接数据库
  269. conn = sqlite3.connect(db_path)
  270. cursor = conn.cursor()
  271. # 查询数据库表为DataFrame,添加 TableName 条件
  272. query = "SELECT * FROM GC_Input_Point WHERE TableName=?"
  273. cursor.execute(query, (utf_en,))
  274. rows = cursor.fetchall()
  275. # 获取列名
  276. column_names = [description[0] for description in cursor.description]
  277. # 定义需要的列索引
  278. last_id_index = column_names.index('Last_ID')
  279. last_spname_index = column_names.index('Last_SPName')
  280. last_epname_index = column_names.index('Last_EPName')
  281. last_hdiff_index = column_names.index('Last_HDiff')
  282. last_rlen_index = column_names.index('Last_RLen')
  283. new_id_index = column_names.index('New_ID')
  284. new_spname_index = column_names.index('New_SPName')
  285. new_epname_index = column_names.index('New_EPName')
  286. new_hdiff_index = column_names.index('New_HDiff')
  287. new_rlen_index = column_names.index('New_RLen')
  288. # 填充数据到Excel
  289. for idx, row in enumerate(rows, start=3):
  290. ws.cell(row=idx, column=1, value=row[last_id_index])
  291. ws.cell(row=idx, column=2, value=row[last_spname_index])
  292. ws.cell(row=idx, column=3, value=row[last_epname_index])
  293. ws.cell(row=idx, column=4, value=row[last_hdiff_index])
  294. ws.cell(row=idx, column=5, value=row[last_rlen_index])
  295. ws.cell(row=idx, column=6, value=row[new_id_index])
  296. ws.cell(row=idx, column=7, value=row[new_spname_index])
  297. ws.cell(row=idx, column=8, value=row[new_epname_index])
  298. ws.cell(row=idx, column=9, value=row[new_hdiff_index])
  299. ws.cell(row=idx, column=10, value=row[new_rlen_index])
  300. # 设置 D, E, I, J 列为强制保留六位小数
  301. ws.cell(row=idx, column=4).number_format = '0.000000'
  302. ws.cell(row=idx, column=5).number_format = '0.000000'
  303. ws.cell(row=idx, column=9).number_format = '0.000000'
  304. ws.cell(row=idx, column=10).number_format = '0.000000'
  305. # 设置B,C,G,H的列宽为9.25
  306. ws.column_dimensions['B'].width = 9.25
  307. ws.column_dimensions['C'].width = 9.25
  308. ws.column_dimensions['G'].width = 9.25
  309. ws.column_dimensions['H'].width = 9.25
  310. # 设置 D, E, I, J 列的列宽为11.5
  311. ws.column_dimensions['D'].width = 11.5
  312. ws.column_dimensions['E'].width = 11.5
  313. ws.column_dimensions['I'].width = 11.5
  314. ws.column_dimensions['J'].width = 11.5
  315. # 设置文件名
  316. # excel_filename = f"{os.path.splitext(decoded_utf_en)[0]}.xlsx"
  317. excel_filepath = os.path.join(export_folder, file_name)
  318. # 保存 Excel 文件
  319. wb.save(excel_filepath)
  320. QMessageBox.information(ui, '成功', f'示例文件已成功导出到 {export_folder}')
  321. except Exception as e:
  322. if isinstance(e, PermissionError) or (isinstance(e, OSError) and e.errno == 13):
  323. QMessageBox.critical(ui, '错误', '请确认文件没有被其他程序(如Excel、文本编辑器等)打开。')
  324. else:
  325. QMessageBox.critical(ui, '错误', f'导出初始数据过程中发生错误: {str(e)}')
  326. print(e)
  327. def process_utf_en(utf_en):
  328. # 确保 utf_en 是字节字符串
  329. if not isinstance(utf_en, bytes):
  330. utf_en = utf_en.encode('utf-8')
  331. # 将字节字符串解码为普通字符串
  332. file_name = utf_en.decode('utf-8')
  333. # 检查文件后缀名并进行相应处理
  334. if file_name.endswith('.xls'):
  335. # 去掉 .xls 后缀并添加 .xlsx 后缀
  336. file_name = file_name[:-4] + '.xlsx'
  337. # 将处理后的字符串重新编码为字节字符串
  338. utf_en = file_name.encode('utf-8')
  339. return utf_en
  340. def main_function_example(ui, utf_en, db_path, export_folder, file_name):
  341. # 调用导出初始数据函数
  342. export_example_data(ui, utf_en, db_path, export_folder, file_name)
  343. def main_function_combined(ui, utf_en, db_path, export_folder, file_name):
  344. export_combined_data(ui, utf_en, db_path, export_folder, file_name)