王 超
(遼寧省交通規(guī)劃設(shè)計院有限責任公司公路養(yǎng)護技術(shù)研發(fā)中心 沈陽市 110111)
針對當前遼寧省安全監(jiān)測系統(tǒng)中,依靠人工做成月度報告存在的效率低、容易出錯的問題,提出一套highcharts結(jié)合phantomjs的技術(shù)方案,開發(fā)了遼寧省高速公路橋梁安全監(jiān)測系統(tǒng)月度報告生成系統(tǒng),解決了需要通過前端網(wǎng)頁請求才能生成安全監(jiān)測月度數(shù)據(jù)統(tǒng)計圖片,使安全監(jiān)測月度報告通過程序自動生成,提高了報告做成的效率,對安全監(jiān)測系統(tǒng)的推廣應用提供了保障。
多年來,橋梁結(jié)構(gòu)的安全狀況一直是公眾特別關(guān)心的問題。橋梁結(jié)構(gòu)在服役期間,不可避免地要受到自然環(huán)境(大氣腐蝕、溫濕度變化、地震、風)和使用環(huán)境(荷載作用頻率增加、材料與結(jié)構(gòu)的疲勞)的影響,必然會逐漸產(chǎn)生損壞現(xiàn)象,進而導致自身結(jié)構(gòu)性能降低,可能導致橋梁發(fā)生倒塌等事故;在橋梁上安裝安全監(jiān)測系統(tǒng),是指利用現(xiàn)場安裝的且對結(jié)構(gòu)安全無損的傳感器元件,對橋梁結(jié)構(gòu)進行長期的在線監(jiān)測,實時地監(jiān)控橋梁結(jié)構(gòu)的運營狀態(tài),并做成月度報告和年度報告對橋梁上所有傳感器的變化趨勢進行展示和分析,及時客觀地評價橋梁結(jié)構(gòu)的狀況,進一步提高橋梁的運營安全性。
在安裝安全監(jiān)測系統(tǒng)時,會在橋梁的不同位置上安裝很多傳感器,如圖1所示。
圖1 安全監(jiān)測系統(tǒng)傳感器布置圖
做橋梁安全監(jiān)測月度報告的時候,需要技術(shù)人員登錄橋梁安全監(jiān)測管理系統(tǒng),手動查詢每個傳感器的月度的數(shù)據(jù)變化圖,并且收集每個月傳感器典型日的特定時間的數(shù)據(jù),做成對比表格,將傳感器變化圖和數(shù)據(jù)對比表格添加到Word中。隨著安裝安全監(jiān)測系統(tǒng)的橋梁數(shù)量越來越多,人工做成安全監(jiān)測月度報告效率低,容易出錯的缺陷越來越突出,如何提高安全監(jiān)測月度報告的做成效率成為亟待考慮和解決的問題。
MicoSoft Word提供的強大的編程接口技術(shù)使得我們利用編程工具通過程序?qū)ord進行控制,自動添加數(shù)據(jù)生成報告成為了可能:添加COM引用,將word的類庫DLL組件導入到C#.net中,在源代碼中引入相應的命名空間,這樣就可以調(diào)用各種Word的操作函數(shù)。
生成橋梁安全監(jiān)測月度報告的時候,主程序首先需要創(chuàng)建一個空白的Word文檔,將模板中的內(nèi)容拷貝到空白Word文檔中,模板通過書簽規(guī)定了不同類型傳感器數(shù)據(jù)在Word中的放置位置,根據(jù)用戶選擇的橋梁,連接部署該橋梁安全監(jiān)測系統(tǒng)的下位機,從下位機中取得所有傳感器的月度數(shù)據(jù),利用phantomjs[1],將傳感器的月度數(shù)據(jù)生成統(tǒng)計圖片,再利用Word類庫組件中的操作函數(shù)[2],將統(tǒng)計圖片插入到文檔對應位置中,然后再將傳感器典型日的特定時間的數(shù)據(jù),利用Word類庫組件中的操作函數(shù),做成對比表格插入到Wrod文檔中,完成后,將安全監(jiān)測報告保存到服務器端以便用戶下載使用,系統(tǒng)處理流程如圖2所示。
圖2 安全監(jiān)測報告生成流程
以上便是安全監(jiān)測報告生成的主要邏輯框架,在下一節(jié)中將具體說明主要部分的實現(xiàn)方法。
根據(jù)系統(tǒng)設(shè)計,生成橋梁安全監(jiān)測月度報告主要包含了如下的幾個操作:創(chuàng)建打開Word空白文檔,拷貝模板數(shù)據(jù)[3];通過定位書簽位置確定月度數(shù)據(jù)統(tǒng)計圖需要插入的Word中的位置;取得傳感器月度數(shù)據(jù),生成統(tǒng)計圖,插入到Word中;插入典型日的對比數(shù)據(jù)表格;關(guān)閉及下載安全監(jiān)測報告,下面分別介紹這些操作的實現(xiàn)方法。
創(chuàng)建、獲取一個Word文檔對象是對Word操作的基礎(chǔ),再生成Wrod報告的時候,需要首先在內(nèi)存中創(chuàng)建一個Word文檔對象,關(guān)鍵的調(diào)用函數(shù)如下:
using MsWord =Microsoft.Office.Interop.Word;
MsWord.Application WordApp = new MsWord.ApplicationClass();
使用Word文檔對象,創(chuàng)建一個Word文檔,關(guān)鍵的調(diào)用函數(shù)如下:
MsWord.Document WordDoc = WordApp.Documents.Add(missing, missing, missing, missing);
將監(jiān)測報告模板中的內(nèi)容拷貝到新建的Wrod文檔中,并打開Word文檔,關(guān)鍵的調(diào)用函數(shù)如下:
File.Copy(TemplateFile, FileName);
WordDoc = WordApp.Documents.Open(Obj_FileName, missing, ReadOnly, missing);
WordDoc.Activate();
程序使用了Word的標簽將不同傳感器數(shù)據(jù)插入到檢測報告不同的位置,向監(jiān)測報告模板中添加標簽的方法:將光標定位在監(jiān)測報告文檔相應的位置,然后選擇Word菜單中的“插入”->“書簽”,定義書簽名,點擊“添加”按鈕,書簽添加成功,這里需要注意,“書簽名”是書簽的唯一標識,不允許重復。
定位書簽位置的時候,首先需要取得書簽名,即首先確定當前的數(shù)據(jù)或者圖片需要添加在監(jiān)測報告的位置,調(diào)用Word文檔對象定位書簽位置,關(guān)鍵的調(diào)用函數(shù):
object BookMarkName = strBookMarkName;
WordDoc.ActiveWindow.Selection.GoTo(ref what, ref missing, ref missing, ref BookMarkName);
安全監(jiān)測系統(tǒng)中使用highcharts插件進行圖表展示[4],人工做成安全監(jiān)測月度報告時,通過操作安全監(jiān)測系統(tǒng)中的按鈕來向后臺發(fā)起請求,后臺獲取到圖片的SVG信息時,生成對應的圖片,也就是說圖片生成必須依賴前端來觸發(fā)。
自動生成安全監(jiān)測報告時,沒有系統(tǒng)前端,如果通過模擬前端自動向后臺發(fā)送請求,效率非常的差。經(jīng)過充分的調(diào)研,系統(tǒng)通過引入phantomjs來解決這個問題,它是個javascript引擎庫,基于webkit內(nèi)核,能解析前臺的HTML及javascript并生成對應的圖片,而且能夠以服務的形式獨立運行在后端,不需要前端觸發(fā)。
調(diào)用phantomjs的關(guān)鍵函數(shù)如下:
Process p = new Process();
p.StartInfo.FileName=System.AppDomain.CurrentDomain.BaseDirectory+"jsphantomjs.exe";
string ExcuteArg = System.AppDomain.CurrentDomain.BaseDirectory + "jshighcharts-convert.js-infile " + infile + "-outfile " + outfile + "-scale 2.5-width 300-constr Chart";
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
infile是輸入圖片的參數(shù),是json文件,將json的路徑傳入,phantomjs會根據(jù) highcharts-convert.js 去解析json文件生成圖片,json模板文本格式比較常見,由于篇幅限制不再列出。
首先連接部署該橋梁安全監(jiān)測系統(tǒng)的下位機,從下位機中取得傳感器的月度數(shù)據(jù),替換json模板文件中的數(shù)據(jù),以溫度傳感器SCT001為例,統(tǒng)計數(shù)據(jù)圖中的橫坐標為時間,需要將時間按如下格式′(1-1)0:00:00′添加到j(luò)son模板文件的xAxis-> categories標簽中,該傳感器的采集頻率為1min,下一條數(shù)據(jù)為′(1-1)0:01:00′,依次類推,以“,”分割數(shù)據(jù);統(tǒng)計數(shù)據(jù)圖中的縱坐標為溫度,取得橫坐標所有時刻對應的溫度數(shù)據(jù),添加到j(luò)son模板文件的series-> data標簽中,在更新完橫坐標和縱坐標的數(shù)據(jù)后,還需要取得縱坐標中所有溫度數(shù)據(jù)的最大值和最小值,加權(quán)后,添加到j(luò)son模板文件的gridLineDashStyle-> max/min標簽中,如何不設(shè)置這個內(nèi)容,會因為圖中顯示的最大值/最小值過大,導致統(tǒng)計數(shù)據(jù)是一條橫線,看不出變化趨勢。
做成json文件后,調(diào)用phantomjs.exe 傳入圖片生成的路徑、json文件,即可在指定的路徑下,生成如圖3所示的圖片:
圖3 傳感器月度數(shù)據(jù)統(tǒng)計圖
接下來,取得要插入統(tǒng)計數(shù)據(jù)圖片位置的書簽名,調(diào)用Word文檔對象將生成的圖片插入到對應位置,調(diào)用的關(guān)鍵函數(shù):
WordDoc.Application.ActiveDocument.InlineShapes.AddPicture(outfile, ref LinkToFile, ref SaveWithDocument, ref Anchor);
生成月度圖片添加到Word文檔中的詳細處理流程如圖4所示。
圖4 生成圖片流程圖
需要說明的是:將WebService部署到IIS上時,IIS上通常運行的賬戶是“NetWork Service”,權(quán)限比較小,使用賬戶“NetWrok Service”無法正常啟動phantomjs.exe進程生成統(tǒng)計數(shù)據(jù)圖片,所以需要將IIS程序池中運行賬戶修改為管理員。修改IIS程序池中運行賬戶的方法:打開IIS,選擇你要更改的應用程序池,右鍵選擇“高級設(shè)置”,“標識”,“自定義賬戶”,“設(shè)置”,輸入本機中有管理員權(quán)限的用戶即可。
向Word中插入文字的方法比較簡單,調(diào)用Word文檔對象TypeText函數(shù)即可,調(diào)用的關(guān)鍵函數(shù)如下:
WordDoc.ActiveWindow.Selection.TypeText(reader["PictureName"].ToString());
向Word中插入一個二維表格,其形式如表1所示:
表1 典型時刻數(shù)據(jù)統(tǒng)計表格
首先根據(jù)表格的行數(shù)和列數(shù),在文檔的光標位置插入一個二維表格,調(diào)用的關(guān)鍵函數(shù)如下所示:
Microsoft.Office.Interop.Word.Table newTable = WordDoc.Tables.Add(WordApp.Selection.Range, iRowCount, iColumnCount, ref missing, ref missing);
創(chuàng)建表格后,循環(huán)遍歷每一行,對當前行中各個列的數(shù)據(jù)設(shè)置內(nèi)容,調(diào)用的關(guān)鍵函數(shù)如下所示:
for(int iLoop = StartRowIndex + 1; iLoop <= iRowCount; iLoop++)
{
newTable.Cell(iLoop, 1).Range.Text =(iCurrentMonth).ToString()+ "月";
newTable.Cell(iLoop, 2).Range.Text = strSensorName;
newTable.Cell(iLoop, 3).Range.Text = listFittingContainer2.First().Value.YValue;
}
在對單元格合并的時候,記錄開始單元格位置和結(jié)束單元格位置,直接進行合并,則會將從開始單元格位置到結(jié)束單元格位置的所有單元格合并成一個單元格,關(guān)鍵函數(shù)如下:
newTable.Cell(1, 1).Merge(newTable.Cell(1, 3));
在報告做成之后,需要關(guān)閉Word文檔,關(guān)鍵的調(diào)用函數(shù):
WordDoc.Close(ref missing, ref missing, ref missing);
WordApp.Quit(ref missing, ref missing, ref missing);
然后將Word保存在服務器的指定位置,用戶在使用的時候,需要下載到本地,下載Word文檔的關(guān)鍵的調(diào)用函數(shù):
FileInfo fileInfo = new FileInfo(FileName);
Response.WriteFile(fileInfo.FullName);
Response.Flush();
本文列舉的所有程序使用Visual Studio 2010和Micosoft word2007調(diào)試通過。
利用C#.net開發(fā)工具可以高效地操作Word文檔,為自動生成專業(yè)格式的Word報告提供了可能,本文利用highcharts結(jié)合phantomjs,以服務的形式獨立運行在后端,不需要前端觸發(fā)即可生成傳感器的月度數(shù)據(jù)統(tǒng)計圖片,然后利用C#.net對Word的控制技術(shù),向Word報告中插入傳感器數(shù)據(jù)統(tǒng)計圖片和變化統(tǒng)計表格,自動生成遼寧省公路橋梁安全監(jiān)測月度報告。解決了人工做成橋梁安全監(jiān)測月度報告效率低,容易出錯的問題,為安全監(jiān)測系統(tǒng)的推廣應用提供了有效的保障。