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