[C#]MS Word 轉存為圖檔

MS Word 轉存為圖檔

不管什麼類型的檔案在電腦裡就都是由01組成,之前也做過一些功能常常用到Stream、FileStream、MemoryStream...等,但也只是「複製貼上&改一改」,C#提供了這些類別讓我們對資料的操作更加方便但從來沒有認真得了解這到底是什麼,最近因為工作的關係,認真的去了解Stream、FileStream、MemoryStream到底是什麼,接著就想嘗試一下將Word轉換成圖片

本篇文章記錄一下將Word檔案轉存為圖片,並無特別底層的說明

要將Word轉存成圖片大致上我往兩個方向嘗試:

1.使用Microsoft.Office.Interop.Word

以這樣的方式去實作這個功能最大的優點就是便宜,因為只要在方案引用Microsoft.Office.Interop.Word

但缺點就是Server上需要安裝Word甚至是MS Office,其實說穿了就是叫用Word的元件服務而已,現在其實想是對Excel很多都改以NPOI來進行操作,其實就是Server上不要安裝MS Office,在這樣的情況下要使用這個方式就行不通了,然而MS Office本來就不是提供來開發用的軟件用這樣的方式相對可能造成資源沒有釋放的問題,如果是為求穩定的案子這並不是個很好的方式。

「不果過我相信很多專案基於成本考量一定會用這個方式XD」

2.使用專門處理MS Office相關操作的套件,例如:Aspose

優點:不用在Server上不要安裝MS Office,程式碼非常乾淨,簡短幾行程式碼就完成功能

缺點:好貴、心裡不踏實,感覺像是別人寫好這功能!

 


接著就來看一下程式碼吧!

1.使用Microsoft.Office.Interop.Word將Word轉存成PNG

記得要引用

string docPath = @"D:\DocToImg\Source.docx"; //Doc檔案路徑
string outPutByOfficePath = @"D:\DocToImg\PrintByOffice_Page_"; //Doc圖片輸出路徑 by Office
var msWordApp = new Microsoft.Office.Interop.Word.Application();
msWordApp.Visible = true;
//開啟該Word檔,天啊! 真的開起Word,我真得是醉了
Microsoft.Office.Interop.Word.Document doc = msWordApp.Documents.Open(docPath);
//Opens the word document and fetch each page and converts to image
foreach (Microsoft.Office.Interop.Word.Window window in doc.Windows)
{
    foreach (Microsoft.Office.Interop.Word.Pane pane in window.Panes)
    {
        for (var i = 1; i <= pane.Pages.Count; i++)
        {
            var page = pane.Pages[i];
            object bits = page.EnhMetaFileBits;//Returns a Object that represents a picture 【Read-only】
            //以下Try Catch區段為將圖片的背景填滿為白色,不然輸出的圖片背景會是透明的
            try
            {
                using (var ms = new MemoryStream((byte[])bits)){
                    System.Drawing.Image image = System.Drawing.Image.FromStream(ms);

                    using (var backGroundWritePNG = new Bitmap(image.Width, image.Height))
                    {
              //設定圖片的解析度
                        backGroundWritePNG.SetResolution(image.HorizontalResolution, image.VerticalResolution);

                        using (Graphics graphis = Graphics.FromImage(backGroundWritePNG))
                        {
                            graphis.Clear(Color.White);
                            graphis.DrawImageUnscaled(image, 0, 0);
                        }
                        string outPutFilePath = Path.ChangeExtension(outPutByOfficePath+i, "png");
                        backGroundWritePNG.Save(outPutFilePath, ImageFormat.Png);//輸出圖片
                    }
                }
            }
            catch (Exception ex){
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
//關閉Word,釋放資源
doc.Close(Type.Missing, Type.Missing, Type.Missing);
msWordApp.Quit(Type.Missing, Type.Missing, Type.Missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
System.Runtime.InteropServices.Marshal.ReleaseComObject(msWordApp);

輸出結果如下:


2.使用Aspose.Word將Word轉存成PNG

Aspose是收費套件而且不便宜,但有提供試用版的,但第一頁的上方會加上「EvaLuation Only. Created with Aspose.Word. Copyright 2003-2016 Aspose Pty Ltd.」的字樣,心理特別不舒服,以下程式碼在官方得文件應能得到相應的說明,這邊也只是記錄一下

string docPath = @"D:\DocToImg\Source.docx"; //Doc檔案路徑
string outPutByAsposePath = @"D:\DocToImg\PrintByAxxxxe_Page_";// Doc圖片輸出路徑 by Aspose

Aspose.Words.Document wordDoc = new Aspose.Words.Document(docPath);
Aspose.Words.DocumentBuilder docBuilder = new Aspose.Words.DocumentBuilder(wordDoc);
//docBuilder.InsertBreak(BreakType.PageBreak); //我發現第一頁插入空白頁後,第1、2頁都會有「EvaLuation Only. Created with Aspose.Word. Copyright 2003-2016 Aspose Pty Ltd.」

//設定圖片儲存的類型
ImageSaveOptions imageSaveOptions = new ImageSaveOptions(Aspose.Words.SaveFormat.Png);
//128 = JPG、130 = PNG 
imageSaveOptions.Resolution = 130;

int pageindex = 0;
int pagecount = wordDoc.PageCount;
for (int i = 0; i < pagecount; i++)
{
    try
    {
        string imgpath = outPutByAsposePath + (i + 1) + ".png";
        if (!File.Exists(imgpath))
        {
            imageSaveOptions.PageIndex = pageindex;
            wordDoc.Save(imgpath, imageSaveOptions);
            pageindex++;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

輸出結果如下:


以上這些紀錄希望對一些要做Word預覽功能的同業有所幫助

這邊提供的想法是將Word轉成MemoryStream輸出到HTML的Img.然後搭上ColorBox或FancyBox這類的燈箱套件就能達到文件檔內容預覽得效果,可以再針對燈箱加上一些JavaScript與Jqury就能達到放大縮小的功能

類似的效果可以參考以下網址(這是之前做的一個功能,超好玩的,可能有Bug不准笑!):

https://kmweb.coa.gov.tw/ebook/publication/CartoonGame.aspx?TabType=CartoonGame
 

 

egan2608@gmail.com