聯(lián)動 關(guān)于解決問題的套路摩瞎。
1. 概述
筆者之前的文章關(guān)于解決問題的套路中從理論層面闡述了筆者對于解決問題套路的個人理解和總結(jié)娶牌,但并沒有附上一個相應(yīng)的示例進行對比驗證弱判,正好筆者最近在部門內(nèi)部一個需求比較典型国葬,本文就以這個需求為范例赏半,復(fù)盤筆者在整個問題解決過程的思路义起。
2. 背景
在這段解決問題的經(jīng)歷中砌左,筆者是作為救火隊員介入的脖咐。初次接觸到問題時候,得到的問題描述是"在進行附件打印時汇歹,附件格式由HTML轉(zhuǎn)換到PDF時文搂,下圖所示的特殊繁體字無法顯示"。3. 獲取更為詳盡的問題上下文
在知曉問題的大致情況后秤朗,經(jīng)過與一線人員的進一步溝通煤蹭,獲得如下額外信息:
- 上面這個繁體字只有在一種情況下(安裝Sogo輸入法)能夠在文本編輯器和IE瀏覽器中顯示出來,但轉(zhuǎn)換到的PDF中依然無法正常顯示這個字取视。
- 在安裝Sogo輸入法之后硝皂,IE瀏覽器可以正常顯示該文字,但在Chrome下卻依然無法正常顯示作谭。一旦卸載稽物,則IE和Chrome均無法正常顯示該文字。
4. 初步分析
- 首先根據(jù)需求折欠,我們要求一線人員將包含該繁體字的HTML頁面直接保存到本地并發(fā)送過來贝或,搭建快速測試環(huán)境吼过。
- 對上面保存在本地的HTML頁面,分別用多個不同類型的瀏覽器打開咪奖,排除瀏覽器的影響盗忱。最終結(jié)果:各個瀏覽器上均無法正常顯示。
- 直接使用Notepad++ / Notepad編輯器打開本地HTML頁面羊赵,觀察其是否存在差異(查看是否在某一端無法顯示趟佃,而其他端正常),排除編輯器的影響昧捷。最終結(jié)果:在不安裝Sogo輸入法的前提下闲昭,各端均無法正常顯示。
- 將本地HTML在其他研發(fā)人員電腦上打開測試靡挥,排除電腦環(huán)境的影響序矩。最終結(jié)果:相關(guān)人員上也無法顯示。
- 安裝Sogo輸入法跋破,觀察繁體字是否正常顯示贮泞。最終結(jié)果:正常顯示。
- 在上一步的基礎(chǔ)上幔烛,不斷刪減Sogo安裝包中的內(nèi)容,直到只剩下"強力刪除"功能都無法根除的文件囊蓝。最終結(jié)果:字體依然正常顯示饿悬。
- 上一步的基礎(chǔ)上,直接卸載Sogo輸入法聚霜。最終結(jié)果:字體不能正常顯示狡恬。
- 對比安裝Sogo輸入法前后Windows字體庫(C:/Windows/Fonts文件夾下)字體數(shù)量的變化。在接到這個需求的第一時間蝎宇,筆者就感覺問題應(yīng)該出在字體上弟劲,但這個字體是哪一種?筆者在安裝Sogo輸入法之前就在Windows的默認字體庫下匯總了現(xiàn)有字體庫的數(shù)量姥芥,但是在Sogo輸入法安裝完畢之后兔乞,發(fā)現(xiàn)數(shù)量沒有變化。證明這條路是死胡同凉唐。
- 在以上多次嘗試均告失敗之后庸追,不得不祭出人類解決問題的常見套路之一 —— "小步前進,頻繁測試"台囱。 通過查找資料淡溯,找到使用Total Uninstall監(jiān)控軟件安裝了什么文件,修改了哪些注冊表簿训,然后暫停手上的一切其他事情咱娶,關(guān)閉其他所有非必要應(yīng)用米间,只開啟打開著本地HTML的Notepad++和Total Uninstall軟件,按照操作步驟將Sogo安裝前后的操作系統(tǒng)變化匯總出來膘侮,然后通過"按名稱猜測"+"折半刪除"來不斷縮小范圍屈糊,輔助以每一小步操作之后直接重啟電腦的方式確保操作影響的真實反饋,并且在每次刪除操作之前記錄刪除的項喻喳,并記錄操作帶來的影響另玖。最終筆者定位到一個名為 EUDC 的注冊表項。
- 通過網(wǎng)上搜索EUDC的名稱定義(End-User-Defined-Characters)表伦,大幅增加了對其導(dǎo)致問題的懷疑谦去,然后從注冊表中刪除該鍵值對并重啟電腦,通過往復(fù)嘗試最終確定Sogo引入的EUDC能夠修復(fù)該繁體字無法顯示的問題蹦哼。
- 在確定了EUDC的作用之后鳄哭,再次查找資料,確定在Java語言的第三方Office類庫Aspose下如何實現(xiàn)對于EUDC的引用纲熏,最終實現(xiàn)對于繁體字在PDF下的正常顯示妆丘。
5. 優(yōu)化
在上一步中,我們采取Java代碼方式轉(zhuǎn)換出來的PDF布局方面都存在比較大的缺陷局劲,而相比較之下采用 wkhtmltopdf 工具轉(zhuǎn)換出來的PDF不論在轉(zhuǎn)換效率還是保真度方面都著非常大的優(yōu)勢勺拣。
因此現(xiàn)在我們有了兩種選擇:
- 使用Java第三方庫進行的PDF轉(zhuǎn)換。優(yōu)點是繁體字可以正常顯示鱼填,缺點是需要進行PDF美觀度調(diào)整药有,但我們對該第三方庫的掌握并不熟練,調(diào)整耗時上不好評估苹丸。
- 使用wkhtmltopdf進行轉(zhuǎn)換愤惰。優(yōu)點是轉(zhuǎn)換效率和保真度方面都著非常大的優(yōu)勢;缺點則是無法正常顯示繁體字赘理,而我們經(jīng)過查看該EXE工具的可配置參數(shù)發(fā)現(xiàn)其并沒有提供直接的字體配置選項宦言。
通過以上清單我們可以看出兩個方案各有千秋,這里就存在我們在解決問題時候經(jīng)常會陷入的一種情況:在多個可行性方法之間猶豫商模,而這些方法彼此之間都會對問題本身的某個方面有自己獨到的優(yōu)勢奠旺,這種情況隨著我們在挑選出其中一個方法進行深入研究過程中遇到困難無法前進時候,我們會更加懷疑自己正在進行的決策施流,以及強烈的切換方案的沖動凉倚。在已選方案的沉沒成本和未知前景,以及另外一個同樣未知前景的方法之間反復(fù)糾結(jié)嫂沉,這會導(dǎo)致大量時間被浪費在躊躇之中稽寒。
這里不得不說,筆者在上面兩種方法之間趟章,其實并不是在一開始就認準(zhǔn)了一種方法然后一條路走到黑的:
- 筆者一開始是打算按照Java第三庫的方式進行樣式調(diào)整杏糙,但發(fā)現(xiàn)該第三方庫天朝局域網(wǎng)內(nèi)相關(guān)資料稀少不說慎王,即使是官方文檔也是很難找到相應(yīng)的范例,而源碼方面也是被混淆過宏侍,難以閱讀赖淤。而且筆者一開始是在Aspose.PDF相關(guān)的文檔中尋找解決方案,后來查找資料的過程中又接觸到可能需要使用他家的Aspose.HTML谅河,在這些方案細節(jié)之間的來回切換也是耗費了筆者不少時間的咱旱。
- 而對于wkhtmltopdf工具,筆者一開始并未選擇它绷耍,畢竟在筆者看來吐限,其作為一個EXE,封裝度遠高于JAVA第三方庫褂始,找到突破口的可能性相較于前者應(yīng)該低不少诸典。
事情的轉(zhuǎn)機來自于筆者在搜索EUDC的過程中發(fā)現(xiàn)的[Font]使用者自造字(EUDC)成功轉(zhuǎn)到 PDF 的方式 和 [Font]讓瀏覽器顯示使用者自造字(EUDC)的方式兩篇文章。這里需要介紹下筆者發(fā)現(xiàn)這兩篇文章的經(jīng)歷:
筆者首先找到的是第一篇"[Font]使用者自造字(EUDC)成功轉(zhuǎn)到 PDF 的方式"崎苗,但讀者如果查看過這篇文章就會發(fā)現(xiàn)狐粱,文章中的圖片和指示性鏈接都無法正常展示,最終結(jié)果是筆者在閱讀其中內(nèi)容時候雖然大致認同其說明的問題與筆者面臨的問題關(guān)聯(lián)性較高胆数,但文章本身的信息缺失度過高肌蜻,導(dǎo)致無法重建出文章作者的解決過程。而且這個時候筆者并沒有意識到第一篇文章中的“選取'讓瀏覽器顯示使用者自造字(EUDC)的方式'中產(chǎn)生出來的 自造字 TTF 檔”這一句其實是指向上面第二個參考連接的必尼。
機緣巧合之下蒋搜,筆者在搜索引擎上找到了[Font]讓瀏覽器顯示使用者自造字(EUDC)的方式,看到此文的時候胰伍,筆者并沒有第一時間將其和前一篇博文聯(lián)系起來,但在此文中筆者注意到一句非常有意思的文字:“可以發(fā)現(xiàn)在 IE 上完全沒有問題酸休,但是在 Chrome 及 Edge 就掛了骂租,完全出不來”。結(jié)合最開始我們提到的問題場景斑司,再結(jié)合文章的標(biāo)題渗饮,讓筆者萌生出了參考該篇博文,將該繁體字在Chrome中展示出來的念頭宿刮。到此其實筆者并沒有想過"將該繁體字在Chrome瀏覽器中顯示出來能對問題的推進有什么幫助?"的進一步考慮互站,只是潛意識地認為如果能夠在Chrome中正常顯示該繁體字,那是不是能夠在使用wkhtmltopdf工具進行轉(zhuǎn)化時候也能正常顯示了僵缺。(注意此念頭在當(dāng)時的筆者看來還只是一個潛意識的懷疑胡桃,并不能被落在計劃清單里)。
-
參照[Font]讓瀏覽器顯示使用者自造字(EUDC)的方式磕潮,筆者主要做了兩件事:
a. 下載 FontForge翠胰,使用其 File > Execute Script 功能執(zhí)行上述博文中給出的腳本,將TTE轉(zhuǎn)換為 TTF。(筆者原本使用FontForge是為了將EUDC合并到Windows常用字體中[參考[Font]使用者自造字(EUDC)成功轉(zhuǎn)到 PDF 的方式 ]十性,而且一開始筆者是按照博文建議的采用命令行進行的合并操作熊尉,但因為在合并之后導(dǎo)出來的TTF在放入Fonts時無法被Windows識別,導(dǎo)致一直對該TTF的正確性存在懷疑锻狗。而FontForge的 Execute Script 正是在筆者挨個查看FontForge的菜單過程中發(fā)現(xiàn)的满力,畢竟筆者直到今天才知道這個軟件的存在)。
b. 下載 Chrome-Stylish插件執(zhí)行上述博文中提供的CSS腳本轻纪。(注意該腳本有個坑....我們之后再說)油额。關(guān)于這一步筆者也不是一開始就找到的這個插件,而是在參考了博文之后桐磁,發(fā)現(xiàn)作者就"透過 Chrome 來執(zhí)行CSS腳本悔耘,就可以正常顯示自造字了"的截圖喜聞樂見地404了,迫不得已筆者通過搜索“Chrome修改樣式”找到了知乎答案 - Chrome 如何修改字體我擂?衬以,不得不說多虧了這篇答案。 上一步的舉措并不順利校摩,首先是插件安裝時候一開始的版本有問題看峻,經(jīng)過一些風(fēng)波之后很快解決,然后就是上面提供的CSS腳本一開始是不生效的衙吩,這個時候筆者通過Chrome中多個Table頁對比互妓,以及簡化CSS腳本的方式,最終確定必須采用web服務(wù)器的方式訪問頁面才能讓Chrome-Stylish插件生效坤塞。于是筆者又在本機上啟動了一個Nginx代碼服務(wù)器冯勉。
結(jié)合第三步獲得的TTF文件(注意此時筆者并不能確定其是否有效)以及上面提供的CSS腳本進行本地化適配——主要是修改woff和ttf文件的所在路徑(此時筆者并不了解CSS腳本中的@font-face的確切含義),最終在Chrome中將繁體字正常顯示出來了摹芙。(至此筆者終于能夠肯定之前轉(zhuǎn)換出來的TTF是有效的)
其實到了這一步灼狰,筆者有些迷茫了 —— 接下來呢? 迷茫之下筆者再次拾起wkhtmltopdf工具浮禾,心懷幻想著"現(xiàn)在Chrome下能夠正常顯示了交胚,那你應(yīng)該能夠正常轉(zhuǎn)換了吧?"盈电,最終果然是外甥打燈籠——照舊蝴簇。期間筆者還不死心地多試了幾次。
筆者在上一步的嘗試中匆帚,再次查看了wkhtmltopdf工具的詳細參數(shù)熬词,注意到其有一個
--user-style-sheet
參數(shù),而我們在第三步中提到的CSS樣式不正好可以用嗎吸重?上一步經(jīng)過筆者的反復(fù)驗證荡澎,最終宣告失敗均践。筆者接下來的想法是既然外部引入CSS樣式不行,那我直接把這段CSS寫死在HTML文件里呢摩幔?
上一步的猜想最終還是失敗了彤委。筆者再次查看wkhtmltopdf工具的詳細參數(shù),猜測使用
--allow
參數(shù)來告知wkhtmltopdf工具可以訪問哪些目錄或衡,依然失敗焦影。筆者回想起第五步中必須使用靜態(tài)訪問服務(wù)器地址的方式讓字體在Chrome下正常顯示,難道wkhtmltopdf工具也需要這樣封断?反正也沒有路了斯辰,直接上吧。
上一步依然失敗坡疼。筆者灰心之下彬呻,再次回到wkhtmltopdf工具GitHub的ISSUE區(qū),通過關(guān)鍵字"font chinese"定位到GitHub-wkhtmltopdf-ISSUE-chinese柄瑰,從中找到了一篇引導(dǎo)性鏈接 @font-face 解決wkhtmltopdf的中文顯示問題闸氮,正是這篇2013年發(fā)表的文章奠定了成功的基石。
在上一步找到的文章基礎(chǔ)上教沾,筆者再次回顧第三步中的CSS腳本:既然GitHub ISSUE中當(dāng)事人說明自己解決了蒲跨,而且他的解決方案與我們找到的如此相似,而且我們使用該方法使繁體字在Chrome下也正常展示出來了授翻,那么為什么我們會卡谆虮? 基于以上疑問堪唐,筆者在參考上一步找到的鏈接中的CSS腳本巡语,對第三步引入的腳本進行不斷刪減,并在此期間對CSS3的
@font-face
含義進行了初步的了解淮菠。最終在將第三步引入的CSS腳本刪減到第十一步中的CSS雷同男公,并且將TTF地址由本地文件地址切換為WEB靜態(tài)文件地址之后,PDF正常展示了繁體字效果兜材。(這就是上面說的第三步CSS腳本的坑點理澎,它定義的 font-family 屬性配置了太多的值逞力,導(dǎo)致我們自定義的EDUC無法發(fā)揮作用)
/* 導(dǎo)致失敗的原CSS腳本 */
@font-face {
font-family: EUDC;
src:url('http://localhost/SGPYEUDC_1.woff?v=1.0.0');
src:url('http://localhost/SGPYEUDC_1.woff?v=1.0.0') format('woff'), url('http://localhost/SGPYEUDC_1.ttf?v=1.0.0') format('truetype');
}
body {
font-family:"Microsoft JhengHei", "新細明體", "細明體", Arial, "EUDC";
}
/* 最終成功的CSS腳本 */
@font-face {
font-family: EUDC;
url('http://localhost/SGPYEUDC_1.ttf?v=1.0.0');
}
body {
font-family: EUDC;
}
6. 回頭看
事情解決之后回頭看曙寡,我們發(fā)現(xiàn)如果:
- 知道EUDC的定義,及其生效方式(注冊表)寇荧。
- 知道 topdf.exe設(shè)置字體的方式(通過CSS樣式在HTML中設(shè)置)举庶。
- 一開始就能在wkhtmltopdf工具的GitHub ISSUE區(qū)多找一會,如果能夠?qū)khtmltopdf工具多一些信心揩抡。
我們將能省卻很多彎路的時間户侥,這就是所謂的基礎(chǔ)不牢镀琉,地動山搖;聯(lián)想到不少研發(fā)人員宣稱的"等用到的時候蕊唐,我自然會去學(xué)了"屋摔,execuse me?
7. 最后
7.1 問題解決之后的收尾操作
正如OOP中對象的創(chuàng)建替梨,使用和銷毀一樣钓试,我們在解決問題的時候也要參考這個思路,問題解決之后我們還要進行現(xiàn)場的清理工作:
- 刪除中間數(shù)據(jù)副瀑。例如在進行wkhtmltopdf工具轉(zhuǎn)換時候的中間文件和文件夾弓熏,下載的一些工具軟件等等。
- 對解決問題過程中找到的資料進行匯總?cè)霗n糠睡,為下一個問題積累工具集和思路挽鞠。
7.2 唯心論
這一小節(jié)筆者想談一些與理性思考比較遠的內(nèi)容。例如"信心"狈孔,也就是對于眼前問題一定能夠被你解決這事情的把握信认。對此筆者個人觀點是:一定要對此抱著120%的信心,信心可以來源于對自己過去多年的刻意沉淀除抛,也可以來自對于眼前問題的深刻理解狮杨,但這里筆者要補充的是:哪怕你是毫無根據(jù)的信心,只要你真的能夠讓自己打心底去認可到忽,這也是非常值得鼓勵的行為橄教。很多時候支撐人們熬過成功前最為艱難的那段歲月的,除了無路可退外喘漏,剩下的絕大部分歸因可以交付給"信心"护蝶。
8. 參考
- [Font]使用者自造字(EUDC)成功轉(zhuǎn)到 PDF 的方式
- [Font]讓瀏覽器顯示使用者自造字(EUDC)的方式。
- Chrome-Stylish插件
- wkhtmltopdf官網(wǎng)
- wkhtmltopdf-GitHub-ISSUE-關(guān)于中文顯示
- @font-face 解決wkhtmltopdf的中文顯示問題
- 教你如何監(jiān)控軟件都安裝了什么文件,對注冊表有什么改動
- fontforge軟件
- html頁面導(dǎo)出為pdf(jsPDF翩迈、iText持灰、wkhtmltopdf)
- [.NET]透過 Aspose.Words 將 Word 轉(zhuǎn)出 PDF 時,自造字(EUDC) 可以顯示出來