• 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文件转换为图片,这里也贴出一些常见的文章链接:
      文章中使用的方法我没有全试,总结一下优缺点:

    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;
            }
    

      速度还可以,没有水印,不需要存储到服务器,基本都是流操作,完美!!!

  • 相关阅读:
    Oracle最大连续访问天数
    oracle中MINUS
    sql中含有中文,export oralce编码格式的环境变量
    alternate_file_dcol_rollback
    oracle查询分区表
    hive创建表sql
    使用ANSI改变终端输出样式
    Golang中的空字符,似花不是花
    程序员必看 Linux 常用命令(重要)
    MongoDB入门介绍与案例分析
  • 原文地址:https://www.cnblogs.com/CoderLinkf/p/14841533.html
Copyright © 2020-2023  润新知