zoukankan      html  css  js  c++  java
  • Office系列---将Office文件(Word、PPT、Excel)转换为PDF文件,提取Office文件(Word、PPT)中的所有图片

    1、Office系列—将Office文件(Word、PPT、Excel)转换为PDF文件

    将Office文件作为文章并在网页上预览,主要为(Word、PPT、Excel)3种类型文件。

    将Office转换为PDF在网页中预览:

    1.1 基于Office实现的解决方案

    实现方式:在本地服务器上安装Microsoft Office,通过C#代码调用服务器上的COM接口,将Office文件转换为PDF(类似于用Office软件打开Word文档,然后另存为PDF文件)。

    不要直接调Office的COM组件,用NetOffice间接调:https://netoffice.io

    通过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程序)。

    直接调Office的COM组件有版本兼容的问题,可以采用NetOffice间接调用。
    通过Nuget安装NetOffice,不同的Office文件需要引用不同的Apidll。

    using NetOffice;
    using NetOffice.PowerPointApi;
    
    public static void PPTConvertPDF(string sourcePath, string targetPath)
    {
        using (Application _pptApp = new Application())
        {
            var pres = _pptApp.Presentations.Open(sourcePath, NetOffice.OfficeApi.Enums.MsoTriState.msoCTrue, NetOffice.OfficeApi.Enums.MsoTriState.msoFalse, NetOffice.OfficeApi.Enums.MsoTriState.msoFalse);
            pres.SaveAs(targetPath, NetOffice.PowerPointApi.Enums.PpSaveAsFileType.ppSaveAsPDF);
            pres.Close();
        }
    }
    

    1.2 基于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添加到程序中后,程序集命名空间名称。

    2、提取Office文件(Word、PPT)中的所有图片

    2.1 基于OpenXml的解决方案

    Office Open XML 是由Microsoft开发的一种以XML为基础并以ZIP格式压缩的电子文件规范,支持文件、表格、备忘录、幻灯片等文件格式。

    简单来说一个PPT文件(.pptx后缀),其实是一个ZIP格式压缩的电子文件,压缩文件内通过XML标记了文档的内容,比如,引用的图片、文字的排列方式等等。
    常用的几种Office文件中的,Word文件有.doc和.docx两种后缀,PowerPoint文件有.ppt和.pptx两种后缀,Excel文件有.xls和.xlsx两种后缀。这其实就是文件版本的差异。 OpenXml也只能用在2007及以后的文件版本中(后缀为.docx、.pptx、.xlsx)。

    测试:准备同一PPT文件分别另存为.ppt和.pptx两个版本,直接修改文件后缀为.zip。
    在这里插入图片描述
    通过Nuget包管理安装需要用到的包

    DocumentFormat.OpenXml
    
    using DocumentFormat.OpenXml.Packaging;
    
    /// <summary>
    /// 导出PPT文件中所有图片
    /// </summary>
    /// <param name="sourcePath">源文件路径</param>
    /// <param name="targetDir">目标文件存放目录</param>
    /// <returns></returns>
    public static void ExportPPTImages(string sourcePath,string targetDir)
    {
        using (PresentationDocument presentationDocument = PresentationDocument.Open(sourcePath, isEditable: false))
        {
            PresentationPart presentationPart = presentationDocument.PresentationPart;
            DocumentFormat.OpenXml.Presentation.Presentation presentation = presentationPart.Presentation;
            List<ImagePart> list = new List<ImagePart>();
            foreach (DocumentFormat.OpenXml.Presentation.SlideId item in presentation.SlideIdList.OfType<DocumentFormat.OpenXml.Presentation.SlideId>())
            {
                SlidePart slidePart = presentationPart.GetPartById(item.RelationshipId) as SlidePart;
                list.AddRange(slidePart.ImageParts);
            }
            List<IGrouping<string, ImagePart>> list2 = list.GroupBy(d => d.Uri.OriginalString).ToList();
    
            //导出PPT所有的图片
            for (int i = 0; i < list2.Count; i++)
            {
                ImagePart imagePart = list2[i].FirstOrDefault();
                string tempFileName = Path.Combine(targetDir, $"image_{i}.jpg");
                using (Stream stream = imagePart.GetStream(FileMode.Open))
                {
                    using (Bitmap bitmap = new Bitmap(stream))
                    {
                        bitmap.Save(tempFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                }
            }
            //presentation.Save();
        }
    }
    
    /// <summary>
    /// 导出Word文件中所有图片
    /// </summary>
    /// <param name="sourcePath">源文件路径</param>
    /// <param name="targetDir">目标文件存放目录</param>
    /// <returns></returns>
    public static void ExportWordImages(string sourcePath,string targetDir)
    {
        using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(sourcePath, isEditable: false))
        {
            var list2 = wordDocument.MainDocumentPart.ImageParts.GroupBy(d => d.Uri.OriginalString).ToList();
            for (int i = 0; i < list2.Count; i++)
            {
                ImagePart imagePart = list2[i].FirstOrDefault();
                string tempFileName = Path.Combine(targetDir, $"image_{i}.jpg");
                using (Stream stream = imagePart.GetStream(FileMode.Open))
                {
                    using (Bitmap bitmap = new Bitmap(stream))
                    {
                        bitmap.Save(tempFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                    }
                }
            }
        }
    }
    

    2.2 基于第三方插件的解决方案

    Spire,用Spire正式版插件导出来的图片没有水印。

    using Spire.Presentation;
    
    /// <summary>
    /// 导出PPT文件中所有图片
    /// </summary>
    /// <param name="sourcePath">源文件路径</param>
    /// <param name="targetDir">目标文件存放目录</param>
    /// <returns></returns>
    public static void ExportPPTImages2(string sourcePath, string targetDir)
    {
        using (Presentation pres = new Presentation())
        {
            pres.LoadFromFile(sourcePath);
            for (int i = 0; i < pres.Images.Count; i++)
            {
                Image image = pres.Images[i].Image;
                string tempFileName = Path.Combine(targetDir, $"image_{i}.jpg");
                image.Save(tempFileName);
            }
        }
    }
    
  • 相关阅读:
    java把指定文字输出为图片流,支持文字换行
    java根据图片和文字生成自定义图片
    eclipse中10个最有用的快捷键组合
    关于版本号:alpha、beta、rc、stable
    Maven内置属性及使用
    Linux终端执行shell脚本,提示权限不够的解决办法
    执行tsung时报"Maximum number of concurrent users in a single VM reached
    SSIS连接SAPBI
    SharePoint 2013连接非默认端口的SQL Server
    SQL Server数据库损坏、检测以及简单的修复办法
  • 原文地址:https://www.cnblogs.com/aixing/p/13327204.html
Copyright © 2011-2022 走看看