程序員在使用FastrReport控件導出PDF時,時常會出現報表文字亂碼的情況,是由于程序讀取中文字體名稱時錯誤,導致寫入到PDF文件中的字體名稱錯誤,所以當用Adobe Acrobat等PDF閱讀器打開PDF時,要讀取PDF文件中的字體名稱,從而調用系統中對應的安裝字體來展示時就會報錯。
找到FastReport安裝包中的“frxExportPDF.pas”文件,
2.找到函數GetFontName,用一下的代碼,替換原函數中的代碼
function TfrxPDFFont.GetFontName: AnsiString;
var
s: AnsiString;
function HexEncode7F(Str: WideString): AnsiString;
var
s: AnsiString;
t: AnsiString; //添加一個變量
Index, Len: Integer;
begin
s :='';
t :=Str; //將字體名稱賦值給該變量,此時就將參數字體名稱的widestring類型轉換為AnsiString,因為很多字體是中文
//字體,漢字是雙字節,所以用Asnsistring類型進行長度判斷時才能正確顯示字體的長度
//例:字符串“ 宋體”A:Length(widestring)=2 B: Length(ANSIString)=4,所以根據長度來判斷
//是否為漢字時,因為字符串長度的差異,導致讀取漢字的錯誤,
//用widestring傳遞字符時,Length(widestring)是不能真實反應字符串的長度的,
//特別是針對漢字韓文日文等雙字節字體時,僅能反應英文德文等單字節字符串
Len :=Length(t); //獲取字體名稱字符串長度
Index :=0;
while Index < Len do
begin
Index :=Index + 1;
if Byte(t[Index]) > F then //當ASCII碼的值大于F時,表示該字符是漢字的某一個字節
//如果是漢字的某一個字節,則添加#將連個字節連接,形成雙字節已正確顯示漢字,
s :=s + '#' + AnsiString(IntToHex(Byte(t[Index]), 2))
else
//如果不是漢字(單字節字符)則直接根據序號讀取字符串中的字符,
s :=s + AnsiString(t[Index]);
end;
Result :=s;
end;
3.然后重新編譯該安裝包后,重新安裝FastReport即可。
原因就是判斷漢字字體名稱長度時(注:漢字為雙字節字符),AnsiString才能正確獲得漢字長度,原函數中的WideString只適合單字節的字符長度。
正好我在用,而且從 win10 開始,到現在的 win11 用了 2 年。
目前使用,有少部分冷門軟件會出現亂碼。
當時用這玩意的原因很簡單:我們有很多做開發的小伙伴用的 Linux 系統,如果發給他們 win 下打的壓縮包會亂碼。
win 10 時期到現在,大部分軟件是可以用的,比如 Axure 、Adobe 全家桶、 Office 全家桶 、QQ 、微信......
這些軟件都是正常的:
?
什么破解軟件、視頻轉碼工具箱之類的會亂碼。
但是 DiskGenius 、AS SSD Benchmark 、 HD Tune 這些工具都正常:
?
不適合財務和金融人員用,因為銀行的客戶端會亂碼,證券客戶端也會亂碼。
?
?
游戲正常運行,Steam 上的游戲,現在還沒遇到問題,除非你是玩魔獸3 這種老游戲。
從 MACOS 或者 Linux 的壓縮包,不會擔心中文亂碼了。
總的來說,UTF-8 不怎么適合普通人,出了問題也不知道怎么回事。
對于電腦有一定基礎的人來說,可以嘗試,而對于大多數用戶來說,如果沒有特殊需求的話不需要嘗試這個。