自動化報表功能(Oracle/plsql/Excel/多線程))
我們要去實現(xiàn)那個自動化報表的功能, 這里面的關鍵技術點包括了用plsql來處理數(shù)據(jù), 用Excel來生成表格文件, 并且還要用到多線程的方式來提升處理的效率。更新時間是2019年12月02日 09:58:57 , 作者是。這篇文章主要給大家介紹了關于實現(xiàn)自動化報表的那些事情, 具體提到了相關的/plsql和Excel技術, 還有多線程的知識。整個文章內容寫得非常詳細, 對于大家來說具有一定的參考和借鑒價值。有需要了解這些內容的朋友, 不妨進行一番詳細的閱讀, 可以供你自己來參考使用。在日常工作里, 會有許多需要手動去更新的固定報表, 這篇文章主要就是來講怎么用代碼來實現(xiàn)多線程的運行方式,然后借助特定的包與那個numpy這個庫, 把計算得到的結果寫入到一個指定的那種excel模板里面, 這么做的好處是絕對不會改變模板里面的內容本身, 同時系統(tǒng)能夠自動生成一個嶄新的excel文件給它冠上一個帶有具體日期的名稱, 在整體流程當中還專門加了一個用來記錄運行日志的模塊功能, 除此之外還運用了諸如try…catch那樣的代碼結構來處理異常情況, 意思就是說一旦檢測到有報錯發(fā)生, 系統(tǒng)就會自動去重新執(zhí)行一遍整個任務, 接下來我們將逐步為大家詳細介紹這一整套自動化功能的完整實現(xiàn)步驟和詳細過程。# -*- coding: utf-8 -*-# Create time: 2019-10-16# Update time: 2019-11-28# Version: 1.0# Version: 2.0 增加多線程/出錯自動重新運行模塊# 導入模塊import cx_Oracleimport osimport pandas as pdimport pandas.io.sql as sqlimport timeimport openpyxlimport xlwings as xwimport loggingimport reimport threading# 獲取工作目錄sqlpath os.getcwd() \\ # 獲取當前文件夾目錄,若不正確則使用后面的代碼直接輸入 sqlpath E:\\# 設置運行日志logging.basicConfig(format%(asctime)s - %(pathname)s] - %(levelname)s: %(message)s, levellogging.INFO, filenamesqlpathlog.txt)# 獲取系統(tǒng)日期(用于命名文件)time_starttime.time()date time.strftime(%Y%m%d)# 定義變量name 經(jīng)營日報 # 模版名稱print(開始運行: %s %name)# sql代碼文件名sql1 sqlpath hangxian_ri.sqlsql2 sqlpath hangxian_zhou.sqlsql3 sqlpath hangxian_yue.sql# 定義空DataFrame(函數(shù)中要使用,必須要先定義)result1 pd.DataFrame()result2 pd.DataFrame()result3 pd.DataFrame()# 定義可以讀取運行sql的函數(shù)def read_run_write1(sql_name):global result1 # 調用全局變量result1,使用global才能對全局變量進行修改print(正在運行代碼: %s %sql_name)with open(sql_name,encodingutf-8-sig,moder) as f: # 讀取oracle代碼,中文編碼utf-8-sig,sql_list f.read()sql_list re.sub(r--.*, , sql_list) # 去除注釋connection cx_Oracle.connect(賬號/密碼IP地址/數(shù)據(jù)庫名稱)code sql_list.replace(\n, ).replace(;,) # 將換行符轉為空格,去除分號for i in range(5): # 運行oracle代碼,若運行失敗則10秒自動重新運行try:result1 sql.read_sql(code, connection) # 利用pd包的read_sql函數(shù)運行代碼,返回DataFrame類型的結果break # 代碼運行成功則跳出循環(huán)except:print(代碼%s運行出錯,正在重新運行第%d次 %(sql_name,(i1)))time.sleep(10) # 代碼運行失敗則10秒后再重新運行print(代碼運行完成: %s %sql_name)def read_run_write2(sql_name):global result2print(正在運行代碼: %s %sql_name)with open(sql_name,encodingutf-8-sig,moder) as f:sql_list f.read()sql_list re.sub(r--.*, , sql_list) # 去除注釋connection cx_Oracle.connect(賬號/密碼IP地址/數(shù)據(jù)庫名稱)code sql_list.replace(\n, ).replace(;,) # 將換行符轉為空格,去除分號for i in range(5):try:result2 sql.read_sql(code, connection)breakexcept:print(代碼%s運行出錯,正在重新運行第%d次 %(sql_name,(i1)))time.sleep(10)print(代碼運行完成: %s % sql_name)def read_run_write3(sql_name):global result3print(正在運行代碼: %s %sql_name)with open(sql_name,encodingutf-8-sig,moder) as f:sql_list f.read()sql_list re.sub(r--.*, , sql_list) # 去除注釋connection cx_Oracle.connect(賬號/密碼IP地址/數(shù)據(jù)庫名稱)code sql_list.replace(\n, ).replace(;,) # 將換行符轉為空格,去除分號for i in range(5):try:result3 sql.read_sql(code, connection)breakexcept:print(代碼%s運行出錯,正在重新運行第%d次 %(sql_name,(i1)))time.sleep(10)print(代碼運行完成: %s % sql_name)# 多線程運行sql代碼if __name__ __main__:t1 threading.Thread(targetread_run_write1, args(sql1,)) # 調用函數(shù),并傳遞參數(shù)sql1,注意當只有一個參數(shù)時,參數(shù)后面需要有逗號t2 threading.Thread(targetread_run_write2, args(sql2,))t3 threading.Thread(targetread_run_write3, args(sql3,))t1.start() # 開始運行t2.start()t3.start()t1.join() # 加入線程,若無join()則運行完一個主線程后則會自動跳出,運行下面的代碼,而不會等待其他線程運行完成t2.join()t3.join()# 寫入數(shù)據(jù)print(正在寫入數(shù)據(jù))app xw.App(visibleFalse,add_bookFalse) # visibleFalse后臺打開Excel程序wb app.books.open(sqlpathname.xlsx) # 打開給定只保留標題和公式的空模版wb.sheets[單日].range(A4).options(expandtable).valueresult1[:].values # result[:].values寫法可以去掉索引和標題,將result1寫入到表格單日,從A4單元格開始wb.sheets[滾動一周].range(A4).options(expandtable).valueresult2[:].valueswb.sheets[月累計].range(A4).options(expandtable).valueresult3[:].valuesfilename sqlpathnamedate.xlsx # 命名新生成的excelwb.save(filename) # 另存為新Excel,不改變模版wb.close() # 關閉工作簿print(filename已自動生成)time_endtime.time()print(程序運行時間%.2f s % (time_end-time_start))logging.info(程序運行時間%.2f s % (time_end-time_start)) # 記錄程序運行時間到運行日志log.txt中在自動化工作里, 有一些地方比較難辦。運行結果總結以上所提到的內容, 是小編給大伙兒介紹的有關如何實現(xiàn)自動化報表的方法, 這個涉及到了和Excel以及多線程這些方面, 期望這能幫到每一位讀者朋友, 要是各位在閱讀的過程中遇到了任何讓自己感到疑惑不解的地方, 都請大家隨時給小編留言來提問, 小編會在第一時間及時地回復大家的疑問的, 除此之外在這里還要非常非常地感謝大家對腳本之家這個網(wǎng)站一直以來所提供的支持與幫助