[.NET]進行簡/繁體文字的轉換

當公司拓展海外業務的時候,第一個發現的問題,就是原本是繁體的系統,需要轉換成簡體使用
簡繁字互轉,其實在Microsoft Word裡已經有提供相關的功能了
但是要將他轉到網頁上使用,似乎不是很容易

進年來,由於許多企業轉移到大陸發展,當然我自己任職的公司也不例外
所以當公司拓展海外業務的時候,第一個發現的問題,就是原本是繁體的系統,需要轉換成簡體使用

簡繁字互轉,其實在Microsoft Word裡已經有提供相關的功能了
但是要將他轉到網頁上使用,似乎不是很容易
因為有一些麻煩的地方,例如文字欄位的呈現,頁面文字的轉換等等的

透過Jimmy的程式碼,我稍微作了一點修改

原程式碼出處:http://www.dotblogs.com.tw/jimmyyu/archive/2009/04/20/8072.aspx

所以,我整裡了兩種方式,可以提供大家作為簡/繁互換的功能,讓大家參考一下

1.單一文字,字詞的轉換

Windows之中,其實已經內建的簡繁互換的元件可以呼叫,而且不用安裝或是參考任何的元件使用
直接呼叫底層元件就可以了


// 使用OS的kernel.dll做為簡繁轉換工具,只要有裝OS就可以使用,不用額外引用dll,但只能做逐字轉換,無法進行詞意的轉換,所以無法將電腦轉成計算機
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int LCMapString(int Locale, int dwMapFlags, string lpSrcStr, int cchSrc, [Out] string lpDestStr, int cchDest);

// 透過OS層的元件進行轉換的動作 
public static string Convert(string strSource, CharsetType enumCharsetType)
{
    String strTarget = new String(' ', strSource.Length);
    int tReturn = LCMapString((int)CharsetType.Default, (int)enumCharsetType, strSource, strSource.Length, strTarget, strSource.Length);
    return strTarget;
}

// 轉換的語系型別
public enum CharsetType
{
    Default = 0x0800,
    Simplified = 0x02000000,
    Traditional = 0x04000000,
}

可是,這樣的轉換法雖然方便,但是會有一個很嚴重的問題,就是他只是去作逐字的翻譯,而無法進行字詞的轉換,像是"電腦"這樣的字詞,就無法轉成"計算機"
要解決這樣的問題,就必須透過Word的元件進行轉換,但是這樣的缺點,就是在伺服器上必須要安裝Microsoft Word才可以

2.透過Microsoft Word進行轉換

下面的程式碼,可以透過Microsoft Word的元件進行整個字詞的轉換,使用起來很方便,但是前提是Server上必須安裝Microsoft Word


using Microsoft.Office.Interop.Word;
using System.Reflection;

Document doc = new Document();
doc.Content.Text = strSource;

if (enumCharsetType == CharsetType.Simplified)
    doc.Content.TCSCConverter(WdTCSCConverterDirection.wdTCSCConverterDirectionTCSC, true, true);
else if (enumCharsetType == CharsetType.Traditional)
    doc.Content.TCSCConverter(WdTCSCConverterDirection.wdTCSCConverterDirectionSCTC, true, true);

ret = doc.Content.Text;
object saveChanges = false;
object originalFormat = Missing.Value;
object routeDocument = Missing.Value;
doc.Close(ref saveChanges, ref originalFormat, ref routeDocument);
Response.Write(ret);

而我自己在測試的過程中發現,又發生了一個錯誤

嗯...沒錯,我忘了伺服器上沒安裝Microsoft Word...
但是,當我安裝了Microsoft Office 2007在伺服器上之後,還是會發生同樣的問題
問題在於一開始在開發時,透過Visual Studio參考進來的Microsoft.Office.Interop.Word元件是2010版本
所以當我在Server上只安裝Office 2007時,一樣會發生無法執行的錯誤

為了解決這樣的問題,我在程式之中,加上一個判斷伺服器安裝Office版本的判斷


// 判斷Office的元件是否已經存在GAC之中
string[] strVersions = { "8", "9", "10", "11", "12", "13", "14", "15" };
string strAssemblyName = "Microsoft.Office.Interop.Word, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";

bool blHaveOfficeGAC = false;
for (int i = 0; i < strVersions.Length; i++)
{
    // 如果GAC不存在,才需要一直找,已經是true,代表找到了,就不用再找了
    if (!blHaveOfficeGAC)
    {
        try
        {
            blHaveOfficeGAC = Assembly.Load(string.Format(strAssemblyName, strVersions[i])).GlobalAssemblyCache;
        }
        catch
        {

        }
    }
}

如果有在GAC中找到Assembly的註冊,blHaveOfficeGAC才會等於true,程式才使用Office的元件進行轉換
為了方便大家瀏覽,我將整個function的程式碼放在下面


public static string ConvertByWord(string strSource, CharsetType enumCharsetType, bool blShowNoneConvert)
{
    // 判斷Office的元件是否已經存在GAC之中
    string[] strVersions = { "8", "9", "10", "11", "12", "13", "14", "15" };
    string strAssemblyName = "Microsoft.Office.Interop.Word, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";

    bool blHaveOfficeGAC = false;
    for (int i = 0; i < strVersions.Length; i++)
    {
        // 如果GAC不存在,才需要一直找,已經是true,代表找到了,就不用再找了
        if (!blHaveOfficeGAC)
        {
            try
            {
                blHaveOfficeGAC = Assembly.Load(string.Format(strAssemblyName, strVersions[i])).GlobalAssemblyCache;
            }
            catch
            {
            }
        }
    }

    // 如果有找到Office的GAC,才顯示Office翻譯的結果
    string ret = "";
    if (blHaveOfficeGAC)
    {
        Document doc = new Document();
        doc.Content.Text = strSource;

        if (enumCharsetType == CharsetType.Simplified)
            doc.Content.TCSCConverter(WdTCSCConverterDirection.wdTCSCConverterDirectionTCSC, true, true);
        else if (enumCharsetType == CharsetType.Traditional)
            doc.Content.TCSCConverter(WdTCSCConverterDirection.wdTCSCConverterDirectionSCTC, true, true);

        ret = doc.Content.Text;
        object saveChanges = false;
        object originalFormat = Missing.Value;
        object routeDocument = Missing.Value;
        doc.Close(ref saveChanges, ref originalFormat, ref routeDocument);
    }

    return ret;
}

這樣一來,不管伺服器安裝的版本是哪一種,都可以進行轉換的動作了

不過,上面的程式碼算是很片段的內容,所以還是提供一下檔案下載的功能,讓大家可以實際套用在自己的系統上吧

檔案下載:CharsetConvert.rar