牛鶴寧 高小堯
(1.中國電子信息產業集團有限公司第六研究所 北京市 102209 2.北京市南水北調信息中心 北京市 100195)
作為產品檢驗人員,工作中需要處理大量的文檔,如檢驗記錄,檢驗報告等。而這些記錄和報告往往具有統一的模板?;诖诵枨缶帉懥艘豢钺槍Ξa品檢驗的文檔處理系統。近些年,隨著 Python 逐漸火熱,國內外使用 Python 主流 Web 框架 Django開發的互聯網軟件也愈發增多。國內比較出名的有豆瓣,海報網,新浪,扇貝網,貝太廚房等[5]。Django 具有簡潔、清晰、高效、安全的開發特點,非常適合小型系統的開發。
Django使用forms表單的形式與后臺邏輯進行交互,主要完成以下工作:
(1)根據用戶輸入提交表單。
(2)根據檢驗申請單和檢驗大綱導入,提取字段后提交表單。
(3)對提交的數據進行校驗,查看數據庫中是否有重復數據。
(4)如果出現重復數據,則提示用戶是否刪除舊數據,若刪除,則自動更新成新提交數據,若不刪除,則需用戶重新輸入提交數據。
(5)自動生成檢驗記錄和檢驗報告。
(6)用戶輸入數據及導入數據均存入數據庫。
(7)條件查詢功能,可根據工程令號,產品名稱,檢驗人員繼續組合查詢。
(8)根據查詢列表導出檢驗臺賬。
2.1.1 Django ORM(對象數據映射)
Django ORM與數據庫映射的關系表現為Django中的一個數據模型(Model)映射一個數據庫表。其基本情況是:類(Django.db.models.Model)映射到數據庫表,類的屬性映射為數據庫表字段,類的實例對象則映射為數據行[3]。
ORM封裝了SQL語句的功能,通過統一的業務邏輯代碼來操作數據庫。因此它在語法上與SQL語句有很大差別。
2.1.2 條件查詢
數據查詢可實現 3 種關鍵詞(工程令號,產品名稱,檢驗人員)的組合查詢,選擇或錄入查詢關鍵詞,點擊搜索按鈕即可將數據庫中的信息按條件可視化地展示在數據網格中。查詢出的數據自動分頁展示,用戶可自定義按照時間順序正序或倒序排列數據,檢驗結果中的不合格檢驗項目以紅底色顯現。由此,用戶在遠程計算機上即可實現測試數據的網絡化查詢。
跨表多條件查詢分為2步,第一步是跨表查詢,第二步是多條件查詢。
(1)結果字段跨表查詢:
取得跨表查詢字段值得形式為“外鍵+雙下劃線+關聯表的字段名”,如shenqing__projectname,shenqing為數據表Jianyaninfo中的外鍵,定義為shenqing = models.ForeignKey(JianyanShenqingdan, default="",on_delete=models.CASCADE),通過外鍵shenqing關聯到JianyanShenqingdan中的字段projectname。
查詢通過內置函數values()返回一個字典查詢列表,列表每一項為字典型、鍵名為字段名,值為字段值。如下面代碼所示,所有需要查詢的結果生成一個結果列表:

(2)多條件查詢:
在上述結果列表的基礎上,增加條件查詢,并通過filter函數過濾條件。因為存在多個條件,所以先把所有條件組成一個數據字典,如下代碼所示:

字典中只保留不為空的值,根據字典查詢結果,如下代碼所示:

2.2.1 根據模板生成文檔
Python中有豐富的資源庫,其中docxtpl就是一個很強大的庫,它通過對docx文檔模板加載,使用jinja2網頁模板開發的語法對其進行修改。Jinja2使用{{}}聲明模板中的變量,將docx模板中需要替換的內容使用{{…}}手動標注起來。從導入的word文檔中讀取值或者從界面寫入值,并把這些值傳到前臺與docx模板中預設的變量名對應起來,使用docxtpl庫中的DocTemplate.Render完成模板替換,輸出替換后的docx,從而自動生成word文檔。

圖1:tables模板

圖2:導入界面
實現代碼如下:

2.2.2 循環生成多個表格
本文除了用到了docxtpl包,還與docx包進行了合并使用,實現循環生成多個表格。通過for循環操作,具體做法如下:在文檔中生成另一個文檔,定義變量sd = tpl.new_subdoc(),并且給變量增加段,sd.add_paragraph('(' + str(i+1) + ')'),添加表格,table = sd.add_table(rows=rows, cols=0, style='Style3'),并把此變量通過context賦予DocxTemplate類型的變量,然后使用docxtpl庫中的DocTemplate.Render完成模板替換,輸出替換后的docx,從而自動生成word文檔。context的格式為'tables': sd,'tables'即為word模板中的字段。
tables字段在模板的對應位置如圖1所示。
實現代碼如下:

把上述循環列表sd加入對應字段context中,并通過tpl.render(context)完成模板替換,并保存。
本系統涉及對文件進行導入導出操作的有三處,分別是對檢驗申請單和檢驗大綱的導入、檢驗報告和檢驗記錄的導出、臺賬導出為Excel文件。
2.3.1 檢驗申請單和檢驗大綱的導入
本系統對檢驗申請單和檢驗大綱的導入是通過Ajax異步傳輸的方式,不重新加載頁面的情況下,與后端服務器交換數據并更新部分網頁內容。導入界面如圖2所示,
實現過程如下:
(1)JavaScript:首先創建formdata對象,append()的第二個參數應為文件對象,利用ajax把formdata對象異步傳輸給后臺服務器。上傳后,服務器端代碼需要使用從查詢參數名為file獲取文件輸入流對象。因為中聲明的name=”file”[7]。實現代碼此處略。
(2)在dapru應用的view.py中新建視圖函Supload(request),通過request.FILES來獲取上傳文件并保存上傳文件到static/files文件夾內。
2.3.2 導出檢驗記錄和檢驗報告
Django導出文件有三種方式:HttpResponse,StreamingHttp Response,FileResponse。本文主要介紹FileResponse實現方式。FileResponse方法是SteamingHttpResponse的子類,我們只需要將連接地址傳給FileResponse函數,就可以實現下載功能,然而這個方法目前尚需完善,因為用戶只要獲取了文件的鏈接地址,就可以通過此接口直接訪問那些文件。后續開發中會實現文件私有化以及限定文件類型等功能。
實現代碼如下:

2.3.3 Excel臺賬的導出
Excel文件的導出需要使用到三個模塊,openpyxl,BytesIO,urlquote。openpyxl庫是用來用Python代碼操作Excel表的庫;BytesIO可以實現在內存中讀寫bytes;urlquote用來解決導出Excel文件無法使用中文文件名的問題[6]。
主要實現代碼如下:

基于Django的Web編程是非常高效的,開發周期大大減少,可以在短時間內完成中小型網站的開發工作。產品檢驗文檔處理系統的實現使得產品檢驗中的文檔編寫工作化繁為簡,大大節省了工作時間,提高了工作效率。此項目中所有工作均獨立完成。項目中的部分功能實現還需進一步完善,頁面也需進一步優化,后續將繼續完善系統,擴展更多的功能模塊。