fastreport中文亂碼問題


  fastreport的中文亂碼問題,確實讓人頭疼,我使用的是delphi6+fastrepport4.7,在4.7版本中,主要表現在以下幾種情況。
  1. 預覽不亂碼,保存亂碼。
  2. 簡體不亂碼,繁體亂碼。
  3. 簡體系統不亂碼,繁體系統亂碼。  
  4. 繁體字,寫死在模板里面不亂碼,但是在數據流中,顯示在Memo中就亂碼了。
     
  或者還有其他種情況,反正各種情況都可能有, 百度下fastreport亂碼,都是說改源碼,但是到對應位置一找,也沒有找到相對的代碼。問題就是這樣的問題,而且fastreport的技術支持完全不行,本地化的機構還得重新交錢才能獲取到技術支持,直接無語了,看了得自己解決了,但是怎么解決呢。仔細思考,大致有這么兩種:
  1. 根本解決,從fastreport源碼里面把這個問題根本解決。由於這個問題異常復雜,而且由於對fastreport工程不了解,從源碼解決費時費力,沒有這個精力,這個方法基本無望。
  2. 曲線救國。這個雖然看起來很牛逼的樣子,但是需要對fastreport的機制相當了解,而且需要對fastreport處理字符的機制出現亂碼問題的根源了解,再考慮躲避方法。看起來很簡單的樣子,其實也是異常繁瑣復雜,但是相對第一種來說,這個還是相對來說比較省時省力。
 
   既然方法已經確定,首先的就是需要對fastreport的運行機制有個大致的了解了。大致的三層架構我就不想說了。這個大家都知道。亂碼問題主要出現在渲染層面上。所以我們需要對這個機制進行了解。這時候麻煩來了,網上壓根就沒有這類資料。怎么辦呢,難道去看代碼,浩大的fastreport工程不是一兩個月能夠熟悉的,如果從這里入手,那么還不如從根本上解決這個問題呢,沒有資料,又不想看源碼,怎么辦呢,只能發揮自己充分的想象力啦。
 
我說下我的思路。如果我們手工畫一張報表,需要怎么做呢,每一個Memo都是我們自己手工一個一個畫上去的吧,如果我們需要把某個memo的字體改掉,只要改這個memo就好了,那么按照軟件設計的常規思路,memo里面應該有能夠設置字體的屬性,字體中應該是帶有編碼的。每次渲染的時候,MasterData是怎么工作的呢,我覺得應該是這樣的,跟我們手動做報表一樣,也是將一個一個memo創建出來然后放到了對應的位置,只不過是MasterData對這些控件進行了抽象。
 
  思路倒是有了,不過都是想象,畢竟沒有跟fastreport的開發人員溝通過,不知道他們是不是原來就是這么設計的,我只是從常規的思路猜測了下,現在就先驗證下思路是否正確。
 
  的確在Memo屬性下找到了字體設置。有編碼也有字體類型。
  按照正常思路,一般設置字體就能夠解決亂碼問題。因為有時候是由於字體只支持單字節導致中文亂碼,把字體改為新宋體,的確解決了簡體的亂碼,保存成PDF都不亂碼了。又發現繁體亂碼,還有編碼可以設置。直接設置成CHINESEBIG5_CHARSET的編碼。繁體也正常了。到這里,亂碼問題的一二三項都解決了。
 
  第四項問題稍微有點頭疼了。我們明明設定好了memo的字體和編碼,理論上只要不是碰上BIG5編碼的時候的簡體字,或者默認編碼下的繁體字,應該不會是亂碼的。經過一番思考,分析如下:
  1. 既然設定好編碼不會亂碼了,證明設定編碼的方式是有效的。
  2. MasterData進行數據展示的時候,Memo控件也是一個個生成的,那么設定好編碼的話,理論上也不會發生亂碼。
 
  由以上分析得出,猜測是動態生成的時候編碼沒有設定好,或者是編碼亂掉了。那么,嘗試解決思路就是如何在動態生成的時候重新設定編碼。然后看到控件meno里面有幾個事件。看事件名字也可以知道大概的執行順序。不過,我們也可以用showmessage這個賴皮招來測試事件的執行順序,這個是個技巧啦。經測試發現,beforeprint->afterdata->afterprint。但是是在afterdata的時候能夠接收到數據。
 
    現在可以在afterdata的時候指定控件的編碼啦。但是有一個問題,發現指定的編碼CHINESEBIG5_CHARSET這個是個宏定義。但是在代碼里面不支持這個宏定義,那么就需要找出這個宏定義是代表什么值了。那么,還是用個笨方法找吧。showmessage。 先把meno的編碼設置成CHINESEBIG5_CHARSET,然后把這個編碼顯示出來就知道了。
在AfterData里面。彈個窗。
 
frxMemoView := TFrxMemoView(Sender);
showmessage(inttostr(frxMemoView.Font.Charset));

  


  通過這個段測試代碼得知CHINESEBIG5_CHARSET是編碼是136;
那么反過來,我們就可以定義如下。
 
procedure DealTraditionalCharset(Sender: TfrxComponent);
var startStr,memoValue:string;
    frxMemoView:TFrxMemoView;    
begin
  frxMemoView := TFrxMemoView(Sender);
  memoValue := frxMemoView.Value;
  if trim(memoValue) = '' then //有些是空值,很奇怪的。過濾掉。
    Exit;
 frxMemoView.Memo.Text := memoValue;                                                                            
 frxMemoView.Font.Charset := 136;    //  CHINESEBIG5_CHARSET                                                      
end;

  


  以上代碼就是動態設置memo為繁體編碼。如果數據流中,簡體和繁體同時存在,目前所發現的編碼中,由於我所使用的4.7版本尚未支持UFT8編碼。所以這個是肯定會有亂碼的。不過,如果繁體和簡體不是同時存在,就是說繁體和簡體不會存在同一段數據流,只是間隔數據流的話,如果在數據流里面加一個字體的標記,那么就可以動態控制memo的編碼使之不亂碼了。
 
  fastreport資料是在是太少了,而且網上估計也有不少人為這個編碼問題頭疼吧。在這個啥資料都沒有的情況下,我覺得突破思路不外乎我這種了,從底層,內部結構開始構思,很多這種沒有資料的東西,就假設如果是你自己開發的fastreport,你會怎么設計呢,也不外乎計算機的原理罷了。理同其理,法同其法,萬物歸一。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM