C# Asp.Net 實現PPT/PDF轉成圖片(不依賴office)


最近公司有個需求,將PPT課件轉成圖片列表,然后在前端展示成輪播圖,於是一開始通過Microsoft.Office.Interop.PowerPoint包實現了這個需求具體代碼如下:

 

/// <summary>
        /// 將PPT轉換為圖片
        /// </summary>
        /// <param name="pptPath"></param>
        /// <param name="imgPath"></param>
        public static List<string> UploadPptImage(HttpRequestBase request)
        {
            var imgUrls = new List<string>();
            var file = request.Files["ppt_file"];
            if (string.IsNullOrEmpty(file.FileName))
            {
                return new List<string>();
            }
            var path = AppDomain.CurrentDomain.BaseDirectory + "imagesfromppt/" + file.FileName;
            var savepath = AppDomain.CurrentDomain.BaseDirectory + "ppt/";

            if (!System.IO.Directory.Exists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            if (!System.IO.Directory.Exists(savepath))
            {
                System.IO.Directory.CreateDirectory(savepath);
            }
            var filepath = Path.Combine(savepath, file.FileName);
            file.SaveAs(filepath);
            Microsoft.Office.Interop.PowerPoint.Application application = null;
            Presentation persentation = null;
            var imagPathList = new List<string>();
            try
            {
                application = new Microsoft.Office.Interop.PowerPoint.Application();
                persentation = application.Presentations.Open(filepath);
                //persentation.Slides[1].Export(path + "\\page" + 1 + ".jpg", "JPG", 800, 600);
                for (var k = 1; k <= persentation.Slides.Count; k++)
                {
                    var imgPath = path + "\\page" + k + ".jpg";
                    imagPathList.Add(imgPath);
                    persentation.Slides[k].Export(imgPath, "JPG", 800, 600);
                }
                imagPathList.ForEach(p =>
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (var fs = new FileStream(p, FileMode.Open))
                        {
                            byte[] buffer = new byte[1024];
                            int result = 0;
                            while ((result = fs.Read(buffer, 0, buffer.Length)) > 0)
                            {
                                ms.Write(buffer, 0, result);
                            }
                        }
                        ms.Seek(0, SeekOrigin.Begin);
                        var fileData = ms.ToArray();
                        string url = ;//此處為雲存儲,不重要,上傳后獲得url
                        imgUrls.Add(url);
                    }
                });
            }
            catch (Exception ex)
            {
                //記錄異常
            }
            finally
            {
                if (persentation != null)
                {
                    persentation.Close();
                    persentation = null;
                }
                if (application != null)
                {
                    application.Quit();
                    application = null;
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
                imagPathList.ForEach(p =>
                {
                    if (File.Exists(p))
                    {
                        File.Delete(p);
                    }
                });
                if (File.Exists(filepath))
                {
                    File.Delete(filepath);
                }
                if (Directory.Exists(path))
                {
                    Directory.Delete(path);
                }
            }
            return imgUrls;
        }

  

  由於我們圖片都是雲存儲,所以存到文件系統后又刪掉了,貌似沒有直接存成流的方式,不重要
  發布到線上后發現服務器沒有安裝office,因此無法正常使用,但又不能在服務器上安裝,因此踩坑一天左右,找到了一些方法

 

一、使用Spire.Presentation
  使用Spire.Presentation可以輕松的將ppt轉換為image,代碼如下
/// <summary>
        /// 將PPT轉換為圖片
        /// </summary>
        /// <param name="pptPath"></param>
        /// <param name="imgPath"></param>
        public static List<string> UploadPptImage(HttpRequestBase request)
        {
            var imgUrls = new List<string>();
            var file = request.Files["ppt_file"];
            if (string.IsNullOrEmpty(file.FileName))
            {
                return new List<string>();
            }
            Presentation ppt = new Presentation();
            ppt.LoadFromStream(file.InputStream, FileFormat.Auto);
            var slidescount = ppt.Slides.Count;
            try
            {
                if (slidescount > 0)
                {
                    for (int i = 0; i < slidescount; i++)
                    {
                        ppt.Slides[i].SaveAsImage();//把ppt轉換成emf格式圖片
                        Image image = ppt.Slides[i].SaveAsImage();
                        using (var ms = new MemoryStream())
                        {
                            image.Save(ms, ImageFormat.Png);
                            ms.Seek(0, SeekOrigin.Begin);
                            var fileData = ms.ToArray();
                            string url = ;//雲存儲,返回url
                            imgUrls.Add(url);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //記錄異常
            }
            return imgUrls;
        }

  

  可以看到,代碼簡單,並且不需要存儲到服務器上,但是Spire.Presentation是商用的,免費使用有10頁的限制,並且會有水印
  於是繼續尋找方法
二、最后解決方案是,先將PPT轉換為pdf(這里使用Aspose.Slides),然后將pdf文件轉換為圖片,這里也貼出一些常見的文章鏈接:
  pdf轉成圖片的方法: https://blog.csdn.net/shi0090/article/details/7262199
  文章中使用的方法我沒有全試,總結一下優缺點:

1、O2S.Components.PDFRender4NET.dll

  該dll可用,雖然免費版有水印但是網上還是能找到破解的,這里不貼了,但ppt中使用了png格式的圖片,會丟失,並且使用圖片清晰度調大會很卡

2、Acrobat.dll

  該dll在asp .net環境下,直接無法添加引用,不知道是不是我自己的問題

3. PDFLibNet.dll

  該dll只支持32位的,我嘗試過,沒有成功,報錯了,可能是我自己的問題

4. Ghostscript

  網上很多人都采用這個方法(貌似功能很強大),博主覺得代碼復雜,沒有深入研究。不適用
上面是我試過的方法,可能是我自己的原因,最后不盡如人意,於是我繼續找,看到了一篇文章:
文章使用 PdfiumViewer包來實現,參照代碼寫了一下,原代碼是winform的。
最后引用了nuget包PdfiumViewer,但是報錯:找不到一個叫PDFium的dll文件,於是我找到了github,發現有人改源代碼實現了,但是我比較菜,自己改不動,於是放棄
后面又嘗試了一遍,發現nuget中這個包的作者有上傳了另外兩個包,看起來是用來處理這個問題的,於是我嘗試引用了其中一個,還不行,引用另一個,可以了:
包名是PdfiumViewer.Native.x86.v8-xfa和PdfiumViewer.Native.x86_64.v8-xfa
最后貼出代碼:
/// <summary>
        /// 將PPT轉換為圖片
        /// </summary>
        /// <param name="pptPath"></param>
        /// <param name="imgPath"></param>
        public static List<string> UploadPptImage(HttpRequestBase request)
        {
            var imgUrls = new List<string>();
            var file = request.Files["ppt_file"];
            if (string.IsNullOrEmpty(file.FileName))
            {
                return new List<string>();
            }
            Presentation ppt = new Presentation(file.InputStream);

            using (var mspdf = new MemoryStream())
            {
                var pageCount = ppt.Slides.Count;
                ppt.Save(mspdf, Aspose.Slides.Export.SaveFormat.Pdf);

                using (var pdf = PdfDocument.Load(mspdf))
                {
                    try
                    {
                        var pagesizes = pdf.PageSizes;
                        for (int i = 0; i < pdf.PageCount; i++)
                        {
                            Size size = new Size();
                            size.Height = (int)pagesizes[(i)].Height;
                            size.Width = (int)pagesizes[(i)].Width;
                            using (var image = pdf.Render(i, size.Width, size.Height, PdfRenderFlags.Annotations))
                            {
                                using (var ms = new MemoryStream())
                                {
                                    image.Save(ms, ImageFormat.Png);
                                    ms.Seek(0, SeekOrigin.Begin);
                                    var fileData = ms.ToArray();
                                    string url = ;//雲存儲,返回url
                                    imgUrls.Add(url);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        //異常記錄
                    }
                }
            }
            return imgUrls;
        }

  速度還可以,沒有水印,不需要存儲到服務器,基本都是流操作,完美!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM