Redmine之報表應用研究

meteorlwj發表於2010-05-27

近來將RedMine的原始碼下下來進行研究,主要目的是研究它的Report功能是如何實現的

目前研究結果總結為幾點:

1)Remine介面上支援PDF,CSV,HTML輸出,但沒有單獨的報表執行中心,只有在Issue及Gant介面有報表輸出功能

2)新建兩個使用者a和b,a使用者在建立時預設語言選擇“English”,b使用者選擇"Chinese(Simple)",進行報表列印時發現第一個使用者列印出來的PDF報表中文顯示為亂碼,第二個使用者列印的PDF報表中文顯示正常

 

對於以上兩點,進行了程式碼跟蹤,得出了以下結論

1)報表輸出的程式碼寫在IssuesController,關鍵程式碼如下:

 

程式碼中很清晰看到CSV、PDF 的輸出呼叫的是 issues_to_csv,issues_to_pdf(Gant介面的報表呼叫的是gant_to_pdf)

從名字可猜測Redmine中的報表列印並不通用,只是針對特定的報表進行了固定的輸出處理

 

issue_to_pdf,issues_to_pdf,gant_to_pdf都包含在pdf.rb中,程式碼如下:

 

而issues_to_csv包含在IssuesHelper中

 

由以上的程式碼可以得出結論:RedMine中只有甘特圖、問題介面支援報表輸出,而且不是每一個地方都支援PDF與CSV兩種格式的

 

2)為什麼預設語言型別不同的使用者輸出相同的報表會得到不一樣的結果(關於中文亂碼)

要解釋這個問題,重點在pdf.rb中

RedMine中對PDF的輸出用的是FPDF,FPDF中支援中文輸出,它內嵌了GB、Big5字型,對於中文的輸出需要做兩步

1、在輸出PDF之前設定輸出字型為 GB或Big5

2、對於中文在輸出之前進行字符集轉換,從UTF-8轉換成支援中文的字符集(如GBK,GB2312)

 

那麼PDF是怎麼做的呢?

首先,看以下程式碼:

 

對於預設語言為“English”的使用者,登陸後觀察current_language的值,發現為"en"

對於預設語言為"Chinese(Simple)"的使用者,登陸後觀察current_language的值,發現為"zh"

 

那麼current_language的值是怎麼得到的呢?

在Redmine中有些配置檔案,其中涉及到default_language的設定,預設都設定為"en",嘗試改為"zh",發現current_language的值沒有發生改變

在研究了其他的原始碼發現current_language的值與資料表users中的LANGUAGE欄位關聯

在ApplicationController中發現以下程式碼:

 

既然a使用者和b使用者因為預設語言不一樣導致current_language不一樣,那麼如果在PDF.initilize中將current_language強制設定為"zh",是否就能得到一樣的結果呢?測試結果發現,即使這樣設定,a使用者列印的PDF報表中文仍然是亂碼,不同的是,亂碼與之前的不一樣。

 

問題到底出在哪呢?

繼續研究,發現PDF中的Cell方法(FPDF輸出的關鍵方法之一)中有這麼一句:

 

原來在這裡進行了字符集轉換,那麼a使用者與b使用者得到的 l(:general_pdf_encoding)是否用相同呢,測試發現,

a使用者進入系統後得到的值為"ISO-8859-1"

b使用者進入系統後得到的值為"gb18030"

 

單獨FPDF輸出報表進行測試,發現

在選擇 GB 字型的情況下,

Iconv.conv("gb18030","UTF-8","測試")與 Iconv.conv("ISO-8859-1","UTF-8","測試")得到的結果不一樣,前者是正常顯示中文,後者則顯示亂碼

 

至此,以上兩點疑問都得到了解釋,這些就是到目前研究RedMine報表應用得到的結論

 

 

相關文章