前面兩篇文章已經展示了Data Solution的設計目標和為達到此目標而設計的應用程式,這一篇繼續細化對它的介紹,講解Data Solution如何對檔案進行掃描,轉換,儲存,檢索。
本機磁碟的檔案格式通常是doc/docx,pdf,pst/ost/eml,htm/mht,txt/rtf,這幾種格式是電腦中常用的格式。要達到在同一個編輯器Editor中可以對它們進行編輯,再整理,需要選擇一種通用的格式,把其它的格式轉化為這種通用格式,對這種格式進行編輯。DOC/DOCX格式功能強大,有很多開源類型庫對它進行讀寫,RTF格式也包含了豐富資料資料,重要的一點是RTF格式,是一種開放的格式。可以到微軟的網站上下載《Microsoft Office Word 2003 Rich Text Format (RTF) Specification》,以熟悉這種檔案格式。開放格式的好處之一是,在後續的進一步開發中,可以找到很多現有的功能和代碼,包括開放的源碼。所以,Data Solution選擇RTF格式作為檔案儲存體的標準格式。
下一個目標就是要找到RTF格式的編輯工具,通過Google可以找到很多RTF格式的編輯器,對RTF格式進行直接編輯,儲存和轉換。因為是開放格式,微軟的.NET Framework內建了RichTextBox,可用於RTF格式的編輯。不過,這個控制項還需要強化,可以到CodeProject.com上找到一些工具和文章。
這兩個關鍵的步驟解決了,下面就是設計資料庫和設計資料讀寫代碼。建立Document資料庫,文檔表的指令碼如下
CREATE TABLE [dbo].[DOCUMENT]( [RECNUM] [int] IDENTITY(1,1) NOT NULL, [SUBJECT] [nvarchar](2000) NULL, [BODY_TYPE] [nvarchar](50) NULL, [BODY] [nvarchar](max) NULL, [CREATE_DATE] [datetime] NULL, [CREATE_BY] [nvarchar](50) NULL, [REVISED_Date] [datetime] NULL, [REVISED_BY] [nvarchar](50) NULL, [CATEGORY] [int] NULL, [COMPUTER] [nvarchar](200) NULL, [PATH] [nvarchar](2000) NULL, CONSTRAINT [PK_DOCUMENT] PRIMARY KEY CLUSTERED ( [RECNUM] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
Body就是儲存文檔的表欄位,設計它為NVARCHAR(MAX)類型,CATEGORY用於文檔的分類尋找,SUBJECT可存放關鍵字或是標題,BODY_TYPE用於全文檢索搜尋,儲存文件類型副檔名。COMPUTER和PATH用於在本機掃描中,指定原始文檔的路徑,可用於追蹤。
Data Solution系統選擇LLBL Gen Framework作為資料庫訪問層的代碼產生器,產生解決方案的代碼如
來看一下,對文檔進行儲存的一段代碼,它是標準的LLBL Gen Framework的routine代碼
public DocumentEntity SaveDocument(DocumentEntity doc){ using (DataAccessAdapter adapter = GetDataAccessAdapter()) { try { adapter.StartTransaction(IsolationLevel.ReadCommitted, "SaveDocument"); adapter.SaveEntity(doc, true, false); adapter.Commit(); } catch { adapter.Rollback(); throw; } } return doc;}
所謂routine代碼,就是代碼可以由模板產生的,就好比上下班打卡一樣,是很平常的簡單的行為。
注意這裡的throw代碼,它沒有寫成這樣
catch(Exception ex){ adapter.Rollback(); throw ex;}
在《.NET架構程式設計》一書中,解釋了這兩個throw的區別,它們會產生不同的stack trace,異常的起始點不同。
基礎層面的問題解決了,下面的應用程式就水到渠成,以不同的方式匯入文件到資料庫中。
Batch Import 批次匯入指定目錄的檔案到資料庫中
Doc Scanner 批次匯入指定格式的檔案到資料庫中
PDF Watcher 專用於PDF檔案格式的轉換,匯入,因為是Watcher,所以你肯定會想到是個FileSystemWatcher
Doc Loader 適用於單個文檔的轉換,匯入,一次只處理一個文檔
再來看資料庫中的文檔的展示,Document Explorer會展現匯入進資料庫的原始檔案,在這裡可以進行預覽,刪除,分類。分類之後,這個文檔就好比打上了合格的標籤一樣,可以在以後的程式中進一步使用。否則,不分類的檔案都會只停留在這裡,後繼的步驟無法處理。這是個文檔流程上的的Policy,如果不喜歡這個步驟,可以去掉。
Document Browser 分類查看文檔
左邊是樹型結構,右邊是從屬於這個分類的文檔。如果要對掃描進資料庫中的檔案進行分類,可以這樣操作
在Document Explorer中選中一個或多個檔案,點擊右鍵Category Document
在Document Browser的左邊的樹中,右鍵Paste Document
之後就看到了效果,在.NET結點下面,展示了所Paste的文檔及其屬性
Document Browser左邊的樹是文檔的分類,可對它對進新增子節點,新增加一個分類的效果如
Category是取自資料庫中的類別表,它的指令碼定義如下
CREATE TABLE [dbo].[CATEGORY]( [RECNUM] [int] IDENTITY(1,1) NOT NULL, [NAME] [nvarchar](200) NULL, CONSTRAINT [PK_CATEGORY] PRIMARY KEY CLUSTERED ( [RECNUM] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
這顆文檔分類樹,它的結構定義是放到本地的XML檔案中,中所看到的樹的格式定義如下
如所示,tag就是從資料庫中擷取的分類定義,依據這個標識,以檢索分類的文檔。在Document Browser表單的開啟與關閉時,它會持久化樹的結構定義,代碼如下
protected override void OnClosed(EventArgs e){ base.OnClosed(e); TreeViewSerializer serializer = new TreeViewSerializer(); serializer.SerializeTreeView(this.treeView, treeFile);}protected override void OnLoad(EventArgs e){ treeView.ImageList = this.imageList; TreeNode root=treeView.Nodes[0]; if (File.Exists(treeFile)) { treeView.Nodes.Clear(); TreeViewSerializer serializer = new TreeViewSerializer(); serializer.DeserializeTreeView(this.treeView, treeFile); treeView.ExpandAll(); }}
如果你對如何把樹節點定義儲存到檔案系統中感興趣,可以用關鍵字TreeViewSerializer在CodeProject中尋找,這裡的代碼就是取自其中一篇文章的代碼。
還有另一個地方,會用到樹型結構分類,在Editor編輯器的開啟檔案對話方塊中,如所示
這裡的效果,與Document Browser的效果是完全一樣的。原來以為是可以用Custom Open File Dialog來解決Open File對話方塊的Place Bar的問題,也就是中看到的左邊的樹的分類,也是如中紅色邊框包圍的地方
要達到重寫紅色地區,Windows有規定的路徑,並且會驗證這個路徑,這個辦法沒有通過,無奈之下才用的自訂對話方塊。之前見到過的軟體,SharePoint Designer重寫過這個Place Bar地區,可惜沒有領悟它的實現原理。
寫到這裡,還沒有完成,這裡還需要一點OFFICE 二次開發的知識,在OFFICE軟體中,寫入一個外掛程式,可以把正在瀏覽的文檔,直接匯入到我的文件資料庫中,如所示
這裡已經安裝了兩個外掛程式,Nitro PDF Professional和Acrobat,用於把當前DOC/DOCX文檔轉換為PDF檔案。所以,還需要寫一個把當前的DOC/DOCX文檔轉存到文檔資料庫中的外掛程式。
在把PDF轉化為可以編輯的RTF格式過程中,遇到了不少的麻煩。把DOC/DOCX轉換成PDF,這個行為,有很多開原始碼可以借用,但是,倒過來,把PDF轉換成DOC/DOCX,這個組件卻不好找。有一種方案是把PDF轉化為TIFF,然後再用OCR軟體系統(ABBYY FineReader 9)來轉成DOC/DOCX檔案。我們做程式員的窮,沒有那麼多銀子買昂貴的SDK License,轉向尋找Crack或是Patch之類的,也沒有結果。這些業界領先的技術,連Trial版本都不會出現在網上,根本沒有機會Trial一把,或是把它放到虛擬機器裡面,永遠以Trial的方式來使用。有的組件,比如PDF Focus.NET,可以試用一把,可是轉換出來的檔案,要麼加上了Trial的浮水印,要麼只能轉換前三頁,後面的都不能轉換。或者有的是ActiveX版本的控制項,OCX方式註冊到系統中,總有這樣那樣的問題。杯具,想想以後要離開對Microsoft .NET Framework的依賴,離開對SQL Server的依賴,以這次的經驗來看,這日子是沒法過了。儘管我已經解決了這裡的所有問題,仍然不願意麵對,在非資料庫開發的領域,技術和知識是很值錢的。因為我們已經習慣了在資料庫領域的開發,技術和知識是一文不值的,只有做出的產品才值錢,悲劇。