Office系列(1)---將Office檔案(Word、PPT、Excel)轉換為PDF檔案
需求: 將Office檔案作為文章並在網頁上預覽,主要為(Word、PPT、Excel)3種類型檔案。
研究了一下,找到了兩種解決方案
- 直接呼叫微軟的線上預覽功能實現(預覽前提:預覽資源必須可以直接通過公網訪問到)微軟介面文件
https://view.officeapps.live.com/op/view.aspx?src=http%3a%2f%2fvideo.ch9.ms%2fbuild%2f2011%2fslides%2fTOOL-532T_Sutter.pptx
在src
後面拼接的就是要預覽的檔案地址(上面地址為官方預覽案例,可以直接在網頁中檢視)
- 將Office轉換為PDF在網頁中預覽
基於Office實現的解決方案
實現方式:在本地伺服器上安裝Microsoft Office,通過C#程式碼呼叫伺服器上的COM介面,將Office檔案轉換為PDF(類似於用Office軟體開啟Word文件,然後另存為PDF檔案)。
通過Nuget包管理器安裝需要的包(這些包只能在.Net FrameWork
版本專案中使用)
Microsoft.Office.Interop.Word
Microsoft.Office.Interop.PowerPoint
Microsoft.Office.Interop.Excel
程式碼:
public class OfficeHelper { static Word.Application wordApplication = new Word.Application(); static Excel.Application excelApplication = new Excel.Application(); static PowerPoint.Application pptApplication = new PowerPoint.Application(); /// <summary> /// 將Word文件轉換成PDF格式 /// </summary> /// <param name="sourcePath">原始檔路徑</param> /// <param name="targetPath">目標檔案路徑</param> /// <returns></returns> public static bool WordConvertPDF(string sourcePath, string targetPath) { bool result; Word.Document wordDocument = null; try { wordDocument = wordApplication.Documents.Open(ref sourcePath); if (wordDocument != null) { wordDocument.SaveAs2(targetPath, WdExportFormat.wdExportFormatPDF); //wordDocument.ExportAsFixedFormat(targetPath, WdExportFormat.wdExportFormatPDF); result = true; } } catch (Exception ex) { result = false; LogHelper.Log($"檔案:{sourcePath} 生成失敗,原因:{ex.Message}", ex.StackTrace); } finally { if (wordDocument != null) { wordDocument.Close(); wordDocument = null; } } return result; } /// <summary> /// 將Excel文件轉換成PDF格式 /// </summary> /// <param name="sourcePath">原始檔路徑</param> /// <param name="targetPath">目標檔案路徑</param> /// <returns></returns> public static bool ExcelConvertPDF(string sourcePath, string targetPath) { bool result; Workbook workBook = null; try { workBook = excelApplication.Workbooks.Open(sourcePath); if (workBook != null) { workBook.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, targetPath); result = true; } } catch (Exception ex) { result = false; LogHelper.Log($"檔案:{sourcePath} 生成失敗,原因:{ex.Message}", ex.StackTrace); } finally { if (workBook != null) { workBook.Close(); workBook = null; } } return result; } /// <summary> /// 將PPT文件轉換成pdf格式 /// </summary> /// <param name="sourcePath">原始檔路徑</param> /// <param name="targetPath">目標檔案路徑</param> /// <returns></returns> public static bool PPTConvertPDF(string sourcePath, string targetPath) { bool result; object missing = Type.Missing; Presentation persentation = null; try { persentation = pptApplication.Presentations.Open(sourcePath, MsoTriState.msoTrue, MsoTriState.msoFalse, MsoTriState.msoFalse); if (persentation != null) { persentation.SaveAs(targetPath, PpSaveAsFileType.ppSaveAsPDF, Microsoft.Office.Core.MsoTriState.msoTrue); //persentation.ExportAsFixedFormat(targetPath, PpFixedFormatType.ppFixedFormatTypePDF); result = true; } } catch (Exception ex) { result = false; LogHelper.Log($"檔案:{sourcePath} 生成失敗,原因:{ex.Message}", ex.StackTrace); } finally { if (persentation != null) { persentation.Close(); persentation = null; } } return result; } }
Office COM API提供SaveAs
和ExportAsFixedFormat
兩個方法來生成文件,需要注意呼叫時引數不同,大部分使用預設值就可以了(介面文件地址)。
上面程式碼中將wordApplication
作為一個靜態變數提出來,每次在載入檔案時,再通過它開啟(相當於一直開著Office.Word程式)。在我本地測試時,本地安裝的是Microsoft Office 2016版本,程式碼執行一直正常。當我把程式給發給別人使用時,發現只有在第一次處理Word檔案時轉換成功,之後的檔案轉換都失敗了。
經檢查,由於對方電腦上安裝的是Office365版本,有可能是在第一次處理完檔案後wordApplication
Word.Application
(相當於重新開啟一遍Office.Word程式),雖然每次例項化導致效率很低,但是所有檔案都處理成功了。最神奇的是同一環境下pptApplication
的連續呼叫是正常的,目前還不知道問題的具體原因,有了解的小夥伴可以告訴我一下。
基於第三方外掛實現的解決方案
這裡主要介紹下Spire和GemBox兩個外掛,他們都可以在伺服器上沒有安裝Office軟體的情況下直接處理檔案。
PS: 正式版收費使用,不然生成的文件中會帶有水印。免費版會有一些限制,比如建立或讀取Office
檔案時有頁數限制,若超出限制直接拋異常。
這裡簡單介紹下程式碼,詳細的api可以到外掛官網文件中去探索。
- Free Spire.Doc for .NET
public static void WordConvertPDF(string sourcePath, string targetPath)
{
using (var doc = new Document(sourcePath))
{
doc.SaveToFile(targetPath, Spire.Doc.FileFormat.PDF);
}
}
- GemBox.Document free version
public static void WordConvertPDF(string sourcePath, string targetPath)
{
// If using Professional version, put your serial key below.
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
DocumentModel document = DocumentModel.Load(sourcePath);
document.Save(targetPath, SaveOptions.PdfDefault);
}
基於WPS實現的解決方案
這個和基於Office的解決方案一樣,通過程式碼呼叫COM介面,實現檔案的轉換。當然需要提前在伺服器上安裝WPS軟體。
在本地的WPS安裝目錄中,找到以下幾個dll檔案,並將其引用到專案中,
wpsapi.dll
wpsapiex.dll
程式碼:
public static void WordConvertPDF(string sourcePath, string targetPath)
{
var app = new Word.Application();
var doc = app.Documents.Open(sourcePath,Visible: MsoTriState.msoFalse);
doc.SaveAs2(targetPath, Word.WdExportFormat.wdExportFormatPDF);
doc.Close();
app.Close();
}
其中Word
是wpsapi.dll
新增到程式中後,程式集名稱空間名稱。
呼叫WPS轉換文件我也只是在本機執行成功了,並沒有實際的應用,只能說是多做了一下了解和嘗試吧。
總結
將Office檔案轉為PDF檔案已經成功了,在網頁中預覽PDF檔案就簡單了,甚至有的瀏覽器直接預設可以開啟預覽PDF檔案。這個網上的解決方案已經很多了,最後選擇了通過pdf.js
在頁面上預覽。預覽檔案已經有了,剩下的就差一個封面了,乾巴巴的標題太枯燥,圖文並茂才是王道,標題黨也需要一些“切合實際”的圖片來烘托一下氣氛吧!
所以自然而然就有了這個問題,如何給文件設定一個合適的封面圖呢?馬上想到一個辦法自己挑一張順眼的圖片作為封面(好吧這是廢話)。認真思考一下有下面幾種解決方案:
- 獲取Office檔案內部的圖片作為封面
- 獲取PDF預覽檔案的第一頁作為封面
預知後事如何,且聽下回分解(畢竟我也還沒有寫完啊!~~~~)