C#解析PDF:客戶化iTextSharp

PDF相關測試一直都是手動進行,自動化測試介入的很少。我們項目,PDF是很重要的一塊,客戶經常需要將報表導出到PDF。導出的可能是表格,也可能是餅圖,條圖,線圖。表格的話,有flat grid,有tree grid。圖的話,花樣就更多了,圖例,座標軸…

最近的迭代有個story,是想要自動化測試能夠判斷表格導出到PDF格式是否正確,看看現在項目用的iTextSharp能否實現這個需求。

iTextSharp是C#的PDF庫,人們經常用它來生成PDF,這個庫裏面有一小塊是解析PDF,這一小塊就是我需要用到的。一番探索之後發現,其實PDF沒有任何結構信息,純粹就是畫圖一般畫出來的。我們項目的PDF,就是先獲取數據,然後根據數據節點,層級結構,生成相應的html文件,最後從html生成PDF。PDF裏面的表格看起來是有結構的,就是一張表,實際上解析之後讀出來的信息毫無結構可言。現有的庫最多可以一行一行把PDF裏面的文字讀出來,離我的預期還很遠。

比如我有如下兩個PDF報表:
這裏寫圖片描述

用現有的iTextSharp讀出來結果如下:
Tree Grid
Fund Asset Class NPV VaR
Fund_A 1234 (2345)
Fixed Income 1234 (2345)
Fund_B 3456 (1234)
Equity 3456 (1234)


Flat Grid
Fund Asset Class NPV VaR
Fund_A 1234 (2345)
Fund_A Fixed Income 1234 (2345)
Fund_B 3456 (1234)
Fund_B Equity 3456 (1234)

每一行的文字,它默認用空格分隔,這樣的話我無從判斷這一行到底導出來幾個單元格,因爲單元格自己的內容就可能有空格。

一開始我認爲這個應該有個string參數,用戶可以設置,然後解析PDF的時候用這個string作爲分隔。google了很久都沒有找到,去stackoverflow上提問了,也沒有人回答。

還好這個工具是開源的,我在github上找到了源代碼:github iTextSharp

原來根本沒有這麼個參數,程序寫死了用空格分隔,詳見SimpleTextExtractionStrategy.cs 的line 145和LocationTextExtractionStrategy.cs的line 193

接下來,把源代碼下下來,在類SimpleTextExtractionStrategy和LocationTextExtractionStrategy裏面添加屬性字段:string separator,賦默認值爲空格符,用戶可以在新建類實例時傳入任何他想要的string來爲它賦值。讀PDF內容的方法增加一個參數,就是類的separator字段。

比如我在新建SimpleTextExtractionStrategy類實例時,傳入參數將separator設置爲++,那麼最後我解析出來的PDF內容如下:


Tree Grid
Fund++Asset Class++NPV++VaR
Fund_A++1234++(2345)
Fixed Income++1234++(2345)
Fund_B++3456++(1234)
Equity++3456++(1234)


Flat Grid
Fund++Asset Class++NPV++VaR
Fund_A++1234++(2345)
Fund_A++Fixed Income++1234++(2345)
Fund_B++3456++(1234)
Fund_B++Equity++3456++(1234)


這樣一來,我就可以以++爲splitter來split每一行內容,繼而判斷PDF格式是否正確。

客戶化開源工具確實能解決自己的問題,但是,後續如果該工具更新了,那麼merge起來也是蠻困難的…只能後續不用這個工具的新版本了…


後話:問題解決了,我去stackoverflow上回答了自己的提問,社區管理員看到之後,也覺得這個不應該寫死,應該expose出來,讓用戶自己設置值,他@了iTextSharp工具的作者。但是不知道作者是否會採納我的建議,並在下一次更新時涵蓋我的改動

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章