Crystal Report 匯出 PDF 搭配非作業系統內預設字型的相關安裝問題
這一陣子因為工作上的原因,開始來使用 Crystal Report,雖然很久之前有使用過 Crystal Report 2005 的版本,但都過了快 20 年了,忽然再次接觸,有點陌生的感覺。好在 Crystal Report 從 2008 版本之後,似乎沒有太多的改版,因此測試一下 Crystal Report 2020,似乎 UI 比較美觀,但功能上都還算雷同,因此算是很快就上手了。
但就覺得一切都那麼美好的時候,就遇到一些字型的問題,因此趕快整理一下免得忘記…
首先就是有關於 思源黑體 和 Google 的 Noto Sans 字型支援的問題,因為一些客戶都會覺得微軟內建的字型不夠好看 ( 雖然我實在看不出來當要印 9 號字的時候,真的有那麼大的差異嗎 ? ),又不想花錢去買一些商用字型,就會來選擇這類的免費字型。當我選擇下載這些字型之後,可以在該字型檔上面 Double Click ,就會出現視窗讓我進行安裝

當我們安裝好字型之後,也可以很順利的將該字型設定在 Crystal Report 內來做使用。從下圖中可以看出我們在報表上設定這三種不同的字型

這些字型也可以搭配印表機來做印出,似乎一切都是那麼美好。

但如果我們要匯出 PDF 檔案( 這裡指的是用 Crystal Report 的匯出功能,而非使用「 Microsoft Print to PDF」這個虛擬印表機來產生 PDF 檔案 ),在 Crystal Report 上則會出現以下的訊息

但是如果我用類似以下的程式碼
using (ReportDocument rpt = new ReportDocument())
{
rpt.Load("C:\\Temp\\init.rpt");
rpt.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, "C:\\Windows\\Temp\\init2.pdf");
}
檔案看起來可以匯出 PDF,但是如果眼尖的朋友,應該可以看到雖然可以顯示,但似乎字的樣式跟我們設計時候所看到的,好像有點不大相同。看起來 Crystal Report 是用作業系統預設的字型「細明體」去將原本設定使用 Noto Sans 的字型換成細明體去嵌入在 PDF 的檔案內,因此雖然還是可以看到那幾個字,但字型卻不是我們所想要的。

而解釋完上述的狀況,還有一種就是多語言的問題,特別是一些跨國的企業,很有可能同一份報表內會有好幾種語言的存在。當在這樣的情況下,字體選擇就有點困難了,到底要選用甚麼樣的字型,才可能同時支援中文、日文、越文和泰文呢 ? 有些朋友可能會想到用「Arial Unicode MS」的字型 ( 維基百科上的說明 ),或者是一些第三方的字型來使用,這裡我先用 Arial Unicode MS 字型來作範例,當我們設計報表格式檔案的時候採用該字型

而從測試的結果看起來似乎也可以正常列印,看起來蠻符合我們所要的。

假如這樣的報表,我們想透過瀏覽器來瀏覽,因此可能會寫一段 asp.net 的網頁程式,類似以下的程式碼來作呈現
protected void Page_Load(object sender, EventArgs e)
{
using (ReportDocument rd = new ReportDocument())
{
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
rd.Load(Server.MapPath("./init.rpt"));
rd.ExportToHttpResponse(ExportFormatType.PortableDocFormat, Response, false, "init.pdf");
Response.End();
}
}
當我們寫好之後,我們執行一下程式,可以在畫面上看到以下的結果,看起來似乎怪怪的。雖然中文和日文都能呈現,但是字體是不正確的;而越文有些正常有些不正常,泰文就沒有辦法正常呈現了

而同樣的程式我們放在 Windows Server 2016 上面執行是正常的,只有程式和字型放在 Windows Server 2019 或 Windows Server 2022 上面才沒有正常顯示,那到底這個算是 Crystal Report 的問題還是 Windows Server 的問題呢 ?
在花了一天建立數個不同的環境和安裝方式,總算找到一個原因。原來在 Windows Server 2019 和其之後的版本,如果我們要安裝字型,"不是"在字型上面點選「安裝」的按鈕去安裝,因為那樣只能給目前登入作業系統安裝的人來做使用。

必須在檔案總管下,選擇該字型檔案,按下滑鼠右鍵,選擇「為所有使用者安裝」

這樣安裝好字型之後,我們再重新執行網頁,此時會看到結果就比較是我們所想要的

花了幾天跟這些字型奮鬥,總算是有個好的結果,希望有朋友如果也是使用 Crystal Report 或相關的報表時候,當在搭配這些字型的時候可以避開這些問題,免得浪費大家寶貴的時間囉。