fastreport中文乱码问题
生活随笔
收集整理的這篇文章主要介紹了
fastreport中文乱码问题
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
fastreport的中文亂碼問題,確實(shí)讓人頭疼,我使用的是delphi6+fastrepport4.7,在4.7版本中,主要表現(xiàn)在以下幾種情況。
預(yù)覽不亂碼,保存亂碼。 簡體不亂碼,繁體亂碼。 簡體系統(tǒng)不亂碼,繁體系統(tǒng)亂碼。 ? 繁體字,寫死在模板里面不亂碼,但是在數(shù)據(jù)流中,顯示在Memo中就亂碼了。
或者還有其他種情況,反正各種情況都可能有, 百度下fastreport亂碼,都是說改源碼,但是到對應(yīng)位置一找,也沒有找到相對的代碼。問題就是這樣的問題,而且fastreport的技術(shù)支持完全不行,本地化的機(jī)構(gòu)還得重新交錢才能獲取到技術(shù)支持,直接無語了,看了得自己解決了,但是怎么解決呢。仔細(xì)思考,大致有這么兩種:
根本解決,從fastreport源碼里面把這個(gè)問題根本解決。由于這個(gè)問題異常復(fù)雜,而且由于對fastreport工程不了解,從源碼解決費(fèi)時(shí)費(fèi)力,沒有這個(gè)精力,這個(gè)方法基本無望。 曲線救國。這個(gè)雖然看起來很牛逼的樣子,但是需要對fastreport的機(jī)制相當(dāng)了解,而且需要對fastreport處理字符的機(jī)制出現(xiàn)亂碼問題的根源了解,再考慮躲避方法。看起來很簡單的樣子,其實(shí)也是異常繁瑣復(fù)雜,但是相對第一種來說,這個(gè)還是相對來說比較省時(shí)省力。
? 既然方法已經(jīng)確定,首先的就是需要對fastreport的運(yùn)行機(jī)制有個(gè)大致的了解了。大致的三層架構(gòu)我就不想說了。這個(gè)大家都知道。亂碼問題主要出現(xiàn)在渲染層面上。所以我們需要對這個(gè)機(jī)制進(jìn)行了解。這時(shí)候麻煩來了,網(wǎng)上壓根就沒有這類資料。怎么辦呢,難道去看代碼,浩大的fastreport工程不是一兩個(gè)月能夠熟悉的,如果從這里入手,那么還不如從根本上解決這個(gè)問題呢,沒有資料,又不想看源碼,怎么辦呢,只能發(fā)揮自己充分的想象力啦。 我說下我的思路。如果我們手工畫一張報(bào)表,需要怎么做呢,每一個(gè)Memo都是我們自己手工一個(gè)一個(gè)畫上去的吧,如果我們需要把某個(gè)memo的字體改掉,只要改這個(gè)memo就好了,那么按照軟件設(shè)計(jì)的常規(guī)思路,memo里面應(yīng)該有能夠設(shè)置字體的屬性,字體中應(yīng)該是帶有編碼的。每次渲染的時(shí)候,MasterData是怎么工作的呢,我覺得應(yīng)該是這樣的,跟我們手動做報(bào)表一樣,也是將一個(gè)一個(gè)memo創(chuàng)建出來然后放到了對應(yīng)的位置,只不過是MasterData對這些控件進(jìn)行了抽象。 思路倒是有了,不過都是想象,畢竟沒有跟fastreport的開發(fā)人員溝通過,不知道他們是不是原來就是這么設(shè)計(jì)的,我只是從常規(guī)的思路猜測了下,現(xiàn)在就先驗(yàn)證下思路是否正確。
的確在Memo屬性下找到了字體設(shè)置。有編碼也有字體類型。
按照正常思路,一般設(shè)置字體就能夠解決亂碼問題。因?yàn)橛袝r(shí)候是由于字體只支持單字節(jié)導(dǎo)致中文亂碼,把字體改為新宋體,的確解決了簡體的亂碼,保存成PDF都不亂碼了。又發(fā)現(xiàn)繁體亂碼,還有編碼可以設(shè)置。直接設(shè)置成CHINESEBIG5_CHARSET的編碼。繁體也正常了。到這里,亂碼問題的一二三項(xiàng)都解決了。
第四項(xiàng)問題稍微有點(diǎn)頭疼了。我們明明設(shè)定好了memo的字體和編碼,理論上只要不是碰上BIG5編碼的時(shí)候的簡體字,或者默認(rèn)編碼下的繁體字,應(yīng)該不會是亂碼的。經(jīng)過一番思考,分析如下:既然設(shè)定好編碼不會亂碼了,證明設(shè)定編碼的方式是有效的。 MasterData進(jìn)行數(shù)據(jù)展示的時(shí)候,Memo控件也是一個(gè)個(gè)生成的,那么設(shè)定好編碼的話,理論上也不會發(fā)生亂碼。
由以上分析得出,猜測是動態(tài)生成的時(shí)候編碼沒有設(shè)定好,或者是編碼亂掉了。那么,嘗試解決思路就是如何在動態(tài)生成的時(shí)候重新設(shè)定編碼。然后看到控件meno里面有幾個(gè)事件。看事件名字也可以知道大概的執(zhí)行順序。不過,我們也可以用showmessage這個(gè)賴皮招來測試事件的執(zhí)行順序,這個(gè)是個(gè)技巧啦。經(jīng)測試發(fā)現(xiàn),beforeprint->afterdata->afterprint。但是是在afterdata的時(shí)候能夠接收到數(shù)據(jù)。
現(xiàn)在可以在afterdata的時(shí)候指定控件的編碼啦。但是有一個(gè)問題,發(fā)現(xiàn)指定的編碼 CHINESEBIG5_CHARSET這個(gè)是個(gè)宏定義。但是在代碼里面不支持這個(gè)宏定義,那么就需要找出這個(gè)宏定義是代表什么值了。那么,還是用個(gè)笨方法找吧。showmessage。 先把meno的編碼設(shè)置成CHINESEBIG5_CHARSET,然后把這個(gè)編碼顯示出來就知道了。 在AfterData里面。彈個(gè)窗。
frxMemoView := TFrxMemoView(Sender); showmessage(inttostr(frxMemoView.Font.Charset));
通過這個(gè)段測試代碼得知 CHINESEBIG5_CHARSET是編碼是136; 那么反過來,我們就可以定義如下。
procedure DealTraditionalCharset(Sender: TfrxComponent); var startStr,memoValue:string;frxMemoView:TFrxMemoView; beginfrxMemoView := TFrxMemoView(Sender);memoValue := frxMemoView.Value;if trim(memoValue) = '' then //有些是空值,很奇怪的。過濾掉。Exit;frxMemoView.Memo.Text := memoValue; frxMemoView.Font.Charset := 136; // CHINESEBIG5_CHARSET end;
以上代碼就是動態(tài)設(shè)置memo為繁體編碼。如果數(shù)據(jù)流中,簡體和繁體同時(shí)存在,目前所發(fā)現(xiàn)的編碼中,由于我所使用的4.7版本尚未支持UFT8編碼。所以這個(gè)是肯定會有亂碼的。不過,如果繁體和簡體不是同時(shí)存在,就是說繁體和簡體不會存在同一段數(shù)據(jù)流,只是間隔數(shù)據(jù)流的話,如果在數(shù)據(jù)流里面加一個(gè)字體的標(biāo)記,那么就可以動態(tài)控制memo的編碼使之不亂碼了。
fastreport資料是在是太少了,而且網(wǎng)上估計(jì)也有不少人為這個(gè)編碼問題頭疼吧。在這個(gè)啥資料都沒有的情況下,我覺得突破思路不外乎我這種了,從底層,內(nèi)部結(jié)構(gòu)開始構(gòu)思,很多這種沒有資料的東西,就假設(shè)如果是你自己開發(fā)的fastreport,你會怎么設(shè)計(jì)呢,也不外乎計(jì)算機(jī)的原理罷了。理同其理,法同其法,萬物歸一。
? 既然方法已經(jīng)確定,首先的就是需要對fastreport的運(yùn)行機(jī)制有個(gè)大致的了解了。大致的三層架構(gòu)我就不想說了。這個(gè)大家都知道。亂碼問題主要出現(xiàn)在渲染層面上。所以我們需要對這個(gè)機(jī)制進(jìn)行了解。這時(shí)候麻煩來了,網(wǎng)上壓根就沒有這類資料。怎么辦呢,難道去看代碼,浩大的fastreport工程不是一兩個(gè)月能夠熟悉的,如果從這里入手,那么還不如從根本上解決這個(gè)問題呢,沒有資料,又不想看源碼,怎么辦呢,只能發(fā)揮自己充分的想象力啦。 我說下我的思路。如果我們手工畫一張報(bào)表,需要怎么做呢,每一個(gè)Memo都是我們自己手工一個(gè)一個(gè)畫上去的吧,如果我們需要把某個(gè)memo的字體改掉,只要改這個(gè)memo就好了,那么按照軟件設(shè)計(jì)的常規(guī)思路,memo里面應(yīng)該有能夠設(shè)置字體的屬性,字體中應(yīng)該是帶有編碼的。每次渲染的時(shí)候,MasterData是怎么工作的呢,我覺得應(yīng)該是這樣的,跟我們手動做報(bào)表一樣,也是將一個(gè)一個(gè)memo創(chuàng)建出來然后放到了對應(yīng)的位置,只不過是MasterData對這些控件進(jìn)行了抽象。 思路倒是有了,不過都是想象,畢竟沒有跟fastreport的開發(fā)人員溝通過,不知道他們是不是原來就是這么設(shè)計(jì)的,我只是從常規(guī)的思路猜測了下,現(xiàn)在就先驗(yàn)證下思路是否正確。
的確在Memo屬性下找到了字體設(shè)置。有編碼也有字體類型。
按照正常思路,一般設(shè)置字體就能夠解決亂碼問題。因?yàn)橛袝r(shí)候是由于字體只支持單字節(jié)導(dǎo)致中文亂碼,把字體改為新宋體,的確解決了簡體的亂碼,保存成PDF都不亂碼了。又發(fā)現(xiàn)繁體亂碼,還有編碼可以設(shè)置。直接設(shè)置成CHINESEBIG5_CHARSET的編碼。繁體也正常了。到這里,亂碼問題的一二三項(xiàng)都解決了。
第四項(xiàng)問題稍微有點(diǎn)頭疼了。我們明明設(shè)定好了memo的字體和編碼,理論上只要不是碰上BIG5編碼的時(shí)候的簡體字,或者默認(rèn)編碼下的繁體字,應(yīng)該不會是亂碼的。經(jīng)過一番思考,分析如下:
由以上分析得出,猜測是動態(tài)生成的時(shí)候編碼沒有設(shè)定好,或者是編碼亂掉了。那么,嘗試解決思路就是如何在動態(tài)生成的時(shí)候重新設(shè)定編碼。然后看到控件meno里面有幾個(gè)事件。看事件名字也可以知道大概的執(zhí)行順序。不過,我們也可以用showmessage這個(gè)賴皮招來測試事件的執(zhí)行順序,這個(gè)是個(gè)技巧啦。經(jīng)測試發(fā)現(xiàn),beforeprint->afterdata->afterprint。但是是在afterdata的時(shí)候能夠接收到數(shù)據(jù)。
現(xiàn)在可以在afterdata的時(shí)候指定控件的編碼啦。但是有一個(gè)問題,發(fā)現(xiàn)指定的編碼 CHINESEBIG5_CHARSET這個(gè)是個(gè)宏定義。但是在代碼里面不支持這個(gè)宏定義,那么就需要找出這個(gè)宏定義是代表什么值了。那么,還是用個(gè)笨方法找吧。showmessage。 先把meno的編碼設(shè)置成CHINESEBIG5_CHARSET,然后把這個(gè)編碼顯示出來就知道了。 在AfterData里面。彈個(gè)窗。
frxMemoView := TFrxMemoView(Sender); showmessage(inttostr(frxMemoView.Font.Charset));
通過這個(gè)段測試代碼得知 CHINESEBIG5_CHARSET是編碼是136; 那么反過來,我們就可以定義如下。
procedure DealTraditionalCharset(Sender: TfrxComponent); var startStr,memoValue:string;frxMemoView:TFrxMemoView; beginfrxMemoView := TFrxMemoView(Sender);memoValue := frxMemoView.Value;if trim(memoValue) = '' then //有些是空值,很奇怪的。過濾掉。Exit;frxMemoView.Memo.Text := memoValue; frxMemoView.Font.Charset := 136; // CHINESEBIG5_CHARSET end;
以上代碼就是動態(tài)設(shè)置memo為繁體編碼。如果數(shù)據(jù)流中,簡體和繁體同時(shí)存在,目前所發(fā)現(xiàn)的編碼中,由于我所使用的4.7版本尚未支持UFT8編碼。所以這個(gè)是肯定會有亂碼的。不過,如果繁體和簡體不是同時(shí)存在,就是說繁體和簡體不會存在同一段數(shù)據(jù)流,只是間隔數(shù)據(jù)流的話,如果在數(shù)據(jù)流里面加一個(gè)字體的標(biāo)記,那么就可以動態(tài)控制memo的編碼使之不亂碼了。
fastreport資料是在是太少了,而且網(wǎng)上估計(jì)也有不少人為這個(gè)編碼問題頭疼吧。在這個(gè)啥資料都沒有的情況下,我覺得突破思路不外乎我這種了,從底層,內(nèi)部結(jié)構(gòu)開始構(gòu)思,很多這種沒有資料的東西,就假設(shè)如果是你自己開發(fā)的fastreport,你會怎么設(shè)計(jì)呢,也不外乎計(jì)算機(jī)的原理罷了。理同其理,法同其法,萬物歸一。
總結(jié)
以上是生活随笔為你收集整理的fastreport中文乱码问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 9本4月程序员新书,Python书就占了
- 下一篇: php 数组课件,php学习 数组课件第