因客戶需要實現PDF的預覽處理,在網上找了一些PDF線上預覽的解決方案,有的用PDFJS的線上預覽方式,有的使用PDFObject的嵌入式顯示,有的通過轉換JPG/PNG方式實現間接顯示的方式,開始是想通過簡單的方式,能夠使用JS插件實現預覽最好,可是線上預覽總是有一些不足,如不同瀏覽器的相容問題,... ...
因客戶需要實現PDF的預覽處理,在網上找了一些PDF線上預覽的解決方案,有的用PDFJS的線上預覽方式,有的使用PDFObject的嵌入式顯示,有的通過轉換JPG/PNG方式實現間接顯示的方式,開始是想通過簡單的方式,能夠使用JS插件實現預覽最好,可是線上預覽總是有一些不足,如不同瀏覽器的相容問題,甚至不同的手機平臺中展示的效果也不一樣,不過最好還是採用了間接的方式,把PDF轉換為圖片展示效果,達到客戶的要求。
1、線上實現預覽的方式
一開始我還是很傾向使用這種方式,希望能採用一個較為好的JS插件的方式,實現PDF的線上預覽(通過Web預覽),因此在Github上找到排名比較高的PDF插件
一看排名還是很高的,那麼採用它應該不錯,查看自帶的PDF文件,效果還是杠杠的。
不過客戶的要求是顯示正常的發票PDF文件,換一下文件地址,有部分信息顯示不了,找了一下沒有看到解決方法,所以效果不達標。
連基本的發票也顯示不了,那我這個就不能用它來顯示發票PDF文件了。
最後,測試了使用PDFObject(https://pdfobject.com/ )的方式實現線上嵌入PDF顯示的方式,這個JS插件也是不錯的,同樣可以在GitHub上可以找到。
它的使用也是很簡單的,如下代碼所示。
<script src="/js/pdfobject.js"></script> <script>PDFObject.embed("/pdf/sample-3pp.pdf", "#example1");</script>
如果需要設置預覽視窗的大小,通過設置樣式即可。
<style> .pdfobject-container { height: 500px;} .pdfobject { border: 1px solid #666; } </style>
顯示的效果是正常的了,不過我在蘋果手機打開Safari瀏覽器測試發現,不能正常顯示。
因此也不能使用來進行預覽顯示。
在實際的測試中,發現安卓手機的瀏覽器對於預覽PDF也是支持不一,有些直接下載PDF,不支持預覽顯示。
為了避免這些問題,最好找了一個折中的方案,把PDF轉換為圖片進行顯示,圖片在不同的瀏覽器中顯示可是沒有問題的。
2、PDF轉換圖片進行顯示
把PDF轉換為圖片也有很多控制項處理,例如Aspose.Pdf、Spire.Pdf、 pdfiumviewer 等等,不同的第三方類庫使用的方法有所差異,不過思路都很類似。
本來傾向於使用Aspose.Pdf的,不過發現轉換後的發票信息還是缺失了某些中文字元或者亂碼,導致不能正常顯示。
後來尋找Spire.Pdf 版本以及對應的綠色版本,終於能夠轉換為正確的格式了,因此也就使用這個第三方控制項進行轉換圖片使用了。
至於線上預覽,我們在第一次請求PDF預覽文件的時候,生成對應的圖片文件,後面直接返迴路徑即可。
實現的預覽效果如下所示。
由於我們是在asp.net MVC的項目上進行顯示的,因此需要修改控制器的處理邏輯,對圖片的生成進行判斷處理即可。
控制器後臺的實現代碼如下所示。
//判斷是否存在PDF生成的圖片文件, //生成的jpg文件名為附件的ID string pdfjpgPath = string.Format("/GenerateFiles/pdf/{0}.jpg", info.ID); string pdfjpg = Server.MapPath(pdfjpgPath); //PDF文件路徑,相對目錄即可 string pdfPath = @"/Content/Template/fapiao.pdf"; string pdfRealPath = Server.MapPath(pdfPath); //如果不存在,則生成,否則返回已生成的文件 if(!FileUtil.IsExistFile(pdfjpg)) { //破解 ModifyInMemory_Spire.ActivateMemoryPatching(); PdfDocument doc = new PdfDocument(pdfRealPath); var image = doc.SaveAsImage(0, Spire.Pdf.Graphics.PdfImageType.Bitmap, 300, 300); FileUtil.BytesToFile(ImageHelper.ImageToBytes(image), pdfjpg); } //存儲一個路徑 info.SavePath = pdfjpgPath;//修改使用這個屬性返回使用
最後返回對應的Json信息即可
//序列號返回對象信息 string result = JsonConvert.SerializeObject(info, Formatting.Indented); return Content(result);
我們在頁面視圖中,通過ajax請求處理即可實現圖片的動態顯示了。
//刷新列表 var ID = ''; function Refresh() { var filename = $("#WHC_FileName").val(); //獲取或生成對應的PDF文件,根據路徑顯示 $.getJSON("/PdfView/FindByFileName?r=" + Math.random() + "&name=" + filename, function (info) { if (info != '') { //獲取圖片路徑,設置顯示 $("#imgfapiao").attr("src", info.SavePath); } }); }
最後實現了圖片的預覽展示。
上面就是我的一個解決思路,如果您有更好的方式解決PDF線上預覽問題,歡迎彼此交流。