轉帖|使用教程|編輯:王香|2019-01-16 11:23:31.000|閱讀 1149 次
概述:SpreadJS導出PDF是一個強大的功能,解決了很多用戶的實際問題,但是在導出PDF時有些問題始終困擾著很多開發者,例如排版、字體亂碼等問題。那么本文就著重講解一下字體亂碼的解決辦法。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
SpreadJS導出PDF是一個強大的功能,解決了很多用戶的實際問題,但是在導出PDF時有些問題始終困擾著很多開發者,例如排版、字體亂碼等問題。那么本文就著重講解一下字體亂碼的解決辦法。
有些朋友會有疑問,同樣是使用了printInfo實例來調整樣式,為什么瀏覽器打印看著好好的字體,導出到PDF就亂碼了呢?
這是由PDF文件的特殊性造成的。PDF是Portable Document Format的簡稱,意為“便攜式文檔格式”,它原生僅僅帶有英文字體,不包含任何中文字體,因此當導出的內容中含有中文字體編碼時,一定會顯示亂碼,所以通常情況下,我們都需要為PDF進行字體注冊操作。
Spread JS 對于導出PDF時的字體亂碼的處理方式,分為兩個部分,一是表格內容,二是頁眉頁腳。下面我將利用一個代碼示例來說明如何處理亂碼。
點此下載字體文件,下載文件如下圖所示:
下載完畢后,將得到的zip包解壓到您系統的任意目錄下,本例是直接解壓到D盤根目錄下。 這個示例是純前端工程,可以直接運行,但是JS訪問目錄下的字體文件時,很大概率會被瀏覽器的安全策略所限制,這是前端語言無法避免的問題,所以我們先把項目部署到服務器。 本例直接采用了Win10系統的IIS服務器來部署。
部署成功后,訪問localhost:[port num]/index.html即可訪問到示例頁面,本例設置端口是8899,即://localhost:8899/index.html
為了把問題考慮得更全面,本例采用了多種字體和多種注冊方法來全面展示如何解決導出PDF的亂碼問題,字體包括微軟雅黑和宋體,注冊方法分為前端注冊和Ajax訪問后端字體文件注冊兩種方式。
1、前端字體注冊:
要實現前端注冊字體,需要獲取到對應字體文件的base64編碼字符串,示例目錄下的data/fonts.js中有兩種字體的base64編碼,分別是MTCORSVA和simkai,代碼如下:
function addFontsToFontManager(fontsObj) { var fonts = { normal: fontsObj["simkai.ttf"] }; GC.Spread.Sheets.PDF.PDFFontsManager.fallbackFont = function (font) { var fontInfoArray = font.split(' '); var fontName = fontInfoArray[fontInfoArray.length - 1]; if (fontName === 'mtcorsva') { return fonts.normal; } } }
其中參數fontsObj就是fonts.js中定義的字體編碼實例。此處實現了將simkai注冊到PDF中,除此之外還將默認字體設置為mtcorsva。
2、 訪問后臺字體文件執行注冊:
由于字體文件通常比較大,而前端注冊字體的方法要求在頁面加載時就要加載進來,這會導致前端加載時間長,影響性能。而且字體文件的base64編碼通常也需要事先生成,這給開發同學們帶來了不小的麻煩。
后臺字體文件注冊可以解決這些問題,字體文件在服務器上存儲,只有當需要導出PDF時才執行加載操作,簡直完美解決問題!
先看代碼:
function registerServerFont(name, type, serverPath) { var xhr = new XMLHttpRequest(); xhr.open('GET', serverPath, true); xhr.responseType = 'blob'; xhr.onload = function (e) { if (this.status == 200) { // get binary data as a response var blob = this.response; //將Blob 對象轉換成 ArrayBuffer var reader = new FileReader(); reader.onload = function (e) { var fontrrayBuffer = reader.result; var fonts = GC.Spread.Sheets.PDF.PDFFontsManager.getFont(name) || {}; fonts[type] = fontrrayBuffer; GC.Spread.Sheets.PDF.PDFFontsManager.registerFont(name, fonts); } reader.readAsArrayBuffer(blob); } }; xhr.send(); }
OK,熟悉Ajax的同學就明白了這里實際上采用了XMLHttpRequest對象的數據流讀取了blob格式的字體文件,然后把這個流直接注冊到PDFFontsManager中,實現了字體注冊操作。 調用方法很簡單,如下:
registerServerFont('微軟雅黑', 'normal', 'font/msyh.ttf');
第一個參數對應了PDF中的字體名稱,最后一個參數指定了字體文件的相對路徑(這就是為什么要先部署后才能訪問)。
如果設置的字體在后臺字體庫中沒有怎么辦?其實解決方法也很簡單,我們的客戶需要的首先應該是一個能夠閱讀的PDF文件,當服務器端沒有對應的字體文件時,可以指定別的字體庫來代替,例如:
registerServerFont('Times New Roman', 'normal', 'font/simsun.ttf');
這是我們小伙伴遇到的一個實際的問題,客戶的Excel中顯示的中文字體是Times New Roman,但是Times New Roman本身是英文字體庫,并不包含中文,在這種情況下瀏覽器會自動指定一個字體,比如簡宋,那么我們在注冊PDF字體時也可以靈活應用。
3、頁眉頁腳亂碼怎么辦:
有同學發現,導出PDF時如果設置了頁眉頁腳,這里出現亂碼怎么解決呢?其實學習指南里有代碼示例,只是不在PDF導出里,而是在自定制打印的“描述”標簽頁的最下邊,如圖:
其中的printInfo.headerCenter("&\"Comic Sans MS\"System Information");的參數中是以“ & ”開頭,后面的Comic Sans MS被雙引號引起來了,這里就制定了字體名稱。 在本例中,我們稍稍修改一下代碼,驗證一下這個方法: 在432行處添加一行:
<input type="text" id="headerCenter" value="表頭內容" class="input" style="font-size: 16px">
在168行處添加一行:
printInfo.headerCenter('&"simsun"' + $("#headerCenter").val());
再執行導出
注意:導出的PDF中仍會有一處亂碼,這是有意留下的,這里的字體示例中沒有注冊,留給同學們練手。
純前端表格控件SpreadJS,是市面上布局與功能都與 Excel 高度類似的一款表格控件,全中文操作界面,適用于.NET、Java、移動端等多個平臺的類 Excel 數據開發,備受華為、中通、民航飛行學院等國內知名企業客戶青睞。
購買SpreadJS 正版授權,請點擊“”喲!
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn