每個童話故事最後面都是說王子和公主最後過著幸福美滿的日子,然後就沒了,但是我發現在RoR版的童話故事內,王子再也不需要公主在一起了,反而是自己一個人以高貴的身份自居!!
好吧,真是難笑的爛梗,我也覺得不好笑。
最近因為一些需求,所以我改負責開發PDF輸出的部分,因為團隊的人很懶,不想要自己手動做一個需要一直變動且漂漂亮亮的Excel檔,所以這個大任就跑到我身上了。
經過了一兩天的Hacking,終於找到一個很屌的東西,叫做Prince,套一下網站上的Slogan,『Prince , a great way of getting web content onto papaer』,果真就像它上面寫的一樣,真的超好用的。
最重要的部分就是可以「直接把XML或是HTML轉成PDF」,沒錯,比以前用PDFlib手繪還屌。因為我們大部分的產品都是以Web的方式呈現,所以大量的資料和檔案都是存成HTML的格式,有這樣子的東西就很方便啦,接下來要開始進入Hacking的部份了(也許會有點多,可能也會有些錯誤,不過就請你有耐心的看下去)
一開始當然是來到Prince的官方網站挑個符合自己作業系統的Prince程式吧。
裝好後,其實你就已經可以自己利用Prince把HTML轉成PDF了,如果我只寫到這邊我大概會被打死,所以我還是講一下要如何把它和RoR做個結合。
Princely是一個把Prince包裝起來的好用套件,它可以讓你把Prince和你的程式碼結合成一起,輕鬆呈現。所以也要安裝這個Plugin,那就來去你的Application的根目錄來安裝它,輸入:
http://gist.github.com/416933.js?file=gistfile1.txt
OK,目前你已經完成整個童話故事的劇情了,但是你知道,現實世界的童話故事總是不會這麼的完全,如果就這樣結束的話那我就不用寫這篇來提醒自己了 = = 。
http://gist.github.com/416939.js?file=gistfile1.builder
這個是Pricely官方的範例檔,我們只要在render的時候下兩個重要的symbol就可以。一個是「:pdf」,它代表的是該pdf被下載時的檔名,而「:stylesheets」則是代表說你原本的HTML file所引入的css檔檔名。這邊要注意一下,如果你直接在Views下用HTML的方式,或是用Rails內建的「stylesheet_link_tag」來引入,都是沒有用的。一定要在這邊下「:stylesheets」來讓Prince去額外引入那個css檔。
對了,忘了在這邊提一下,我測試的時候發現到一個問題,就是如果在Views用「image_tag」來設定相對路徑的話,圖會出不來,所以要把它改寫成絕對路徑。(因為在RoR的Conventions有特別說到這點,為了可移植性,這邊要用相對的方式讓RoR自動去對應那個圖片的路徑)
接下來就是最大的麻煩,害我花了將近一整天的時間沒去上課。就是有關中文呈現的問題。在預設的情況下,所有的中文字都會變成「???」。我原本差點因為這個問題崩潰,不過之後還是解決了,就來看一下要怎麼處理,如果沒有發生這種情況或是不需要輸出中文字的人就先恭喜你啦,你已經幫王子寫下最後的結局了,所以就這樣子啦。
不過如果你真的和我一樣可憐,那你就要先打死這個Bug才行。在Prince官方有提到,如果一直出現「prince: internal error: no fallback glyph for character U+00XX」,就代表沒有相對應的字型可以去匹配中文字,所以通常,像我Server這邊,是因為沒有裝「msttcorefonts」這個package,所以要去這邊來安裝這個package。
如果還是有問題,那就改用官方建議的另外一個方法,
去找出安裝Prince時的fonts.css設定檔,修改它並重新定義css的generic font families去map到你自定的字型上去,以我為例,我這邊的檔案是放在「/usr/lib/prince/style/fonts.css」。
下面是我自己設定的部分:
http://gist.github.com/416972.js?file=gistfile1.css。我就把css內的「font-family: “verdana”;」 map到蘋果儷黑體的實體路徑,所以Prince就會把我HTML那邊設定的「font-family: “verdana”」以蘋果儷黑的字型寫入PDF。
以上就是這次的小Hacking,大致上是沒有什麼太大的問題,如果有什麼更新的話我會再直接在這邊做註解的。大概就是這樣啦,大家掰,我們下次見。