文档转换程序-PPT转视频Word和PDF转图片

最近写了一个文档转换项目,其功能是将PPT文件转换成视频文件,word文件转换成PNG图片,PDF文件转换为PNG图片。采用的方案是调用Office的组件和Adobe Acrobat的组件进行转换。

系统运行的先行条件是:

1. 在windows 平台下运行。

2. 安装了Microsoft Office 2010 或以上版本。

3. 安装了Adobe Acrobat 9或以上(其他版本为测试过)。

项目添加的引用如下图所示:

文档转换程序-PPT转视频Word和PDF转图片

将PPT转换为WAV视频文件,核心代码为:

PowerPoint.Application pptApplication = new PowerPoint.Application();

PowerPoint.Presentation ppt = pptApplication.Presentations.Open(fileName,

                        Microsoft.Office.Core.MsoTriState.msoTrue,

                        Microsoft.Office.Core.MsoTriState.msoFalse,

                        Microsoft.Office.Core.MsoTriState.msoFalse);

PowerPoint.PpSaveAsFileType format = PowerPoint.PpSaveAsFileType.ppSaveAsWMV;

ppt.SaveAs(pathwmv, format, Microsoft.Office.Core.MsoTriState.msoFalse);

ppt.Close();       

pptApplication.Quit();

PDF转换首先是判断文件是否为word文件,如果是,则调用Offic组件进行转换为PDF文件,核心代码是:

Word.Application wordApplication = new Word.Application();

wordApplication.Documents.Open(fileName);

Word.WdSaveFormat format = Word.WdSaveFormat.wdFormatPDF;

wordApplication.ActiveDocument.SaveAs2(pathpdf, format);

PDF转换为图片的过程是调用Adobe Acrobat组件进行转换的,核心代码为:

Acrobat.CAcroPDPage pdfPage;

Acrobat.CAcroRect pdfRect;

Acrobat.CAcroPoint pdfPoint;

int pageCount = pdfDoc.GetNumPages();

for (int i = 0; i < pageCount; i++){

      pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(i);

      pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();

      pdfRect = (Acrobat.CAcroRect) Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");

      pdfRect.Left = 0;

      pdfRect.right = pdfPoint.x;

      pdfRect.Top = 0;

      pdfRect.bottom = pdfPoint.y;

       pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);

        DataObject loClipboardData = Clipboard.GetDataObject();

        if (loClipboardData.GetDataPresent(DataFormats.Bitmap)) {

            Bitmap pdfBitmap = (Bitmap)loClipboardData.GetData(DataFormats.Bitmap);

            int loImgWidth = pdfPoint.x;

            int loImgHeight = pdfPoint.y;

            Bitmap loTemplateBitmap = new Bitmap(pdfPoint.x, pdfPoint.y);

            Image loPdfImage = pdfBitmap.GetThumbnailImage(loImgWidth, loImgHeight, null, IntPtr.Zero);

            Bitmap thumbnailBitmap = new Bitmap(loImgWidth + 7, loImgHeight + 7,                                                         System.Drawing.Imaging.PixelFormat.Format32bppArgb);                                  loTemplateBitmap.MakeTransparent();

            using (Graphics poGraphics = Graphics.FromImage(thumbnailBitmap)) {

                  poGraphics.DrawImage(loPdfImage, 2, 2, loImgWidth, loImgHeight);

                  poGraphics.DrawImage(loTemplateBitmap, 0, 0);

                  //保存图象文件

                  string lcSaveFileName = lcOutPutFile + "_" + i.ToString() + ".png";

                  thumbnailBitmap.Save(lcSaveFileName, System.Drawing.Imaging.ImageFormat.Png);

            }

            loTemplateBitmap.Dispose();

            loPdfImage.Dispose();

            thumbnailBitmap.Dispose();

   }

   Marshal.ReleaseComObject(pdfPage);

   Marshal.ReleaseComObject(pdfRect);

}

创建Windows 服务守护转换进程:

为保证PPT转视频应用程序(DocumentConvert)一直运行,原先设计是创建一个Windows服务来保护该进程,具体设计流程如下:

创建一个Windows Service, 在服务中添加定时器,在定时器事件处理中,查找名为“DocumentConvert”的进程,若此进程不在,则新建一个进程开启在该软件安装目录下的DocumentConvert.exe程序;若此程序有多个运行进程,则只保留一个进程,杀掉其他进程。

服务创建结果是,该服务可以正常安装,启动和关闭,卸载。并且调起的进程可以正常访问数据库,可以正常转换PDF文件,但是不能正常启动Office打开PPTWord,在使用其Open方法时抛出异常。

调研结果大概是,windows服务的窗口站不同于用户的窗口站。而ppt应用程序只能在用户窗口站打开。并且PowerPoint是一个用户应用程序,不应该在服务中被使用。设置该服务与用户界面交互是一个糟糕的选择,及时这样工作了也会带来其他更深层次的问题。 

参考微软Office组件使用特别说明:http://support.microsoft.com/default.aspx?scid=kb;en-us;257757

Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.

遇到同样问题的参考:http://stackoverflow.com/questions/729609/powerpoint-interop-fails-in-a-windows-service-but-works-fine-in-a-windows-form-a  

创建用户守护进程:

守护服务创建失败,我们转而求其次,创建一个用户守护进程,来保证DocumentConvert一直运行。具体过程如下:程序每隔一段时间(在配置文件中设置),查找名为“DocumentConvert”的进程,若此进程不在,则新建一个进程,开启在该软件安装目录下的DocumentConvert.exe程序;若此程序有多个运行进程,则只保留一个进程,杀掉其他进程。

主要代码为:


public bool OnTimedEvent() {

            bool result = true; 

            //判断进程是否正在进行

            Process[] pros = Process.GetProcessesByName(this.process_name); 

             try  { 

                       //如果该进程有多个副本在运行,则杀掉多个进程,只保留一个

                     if (pros.Length > 1)  {  

                        for (int i = 1; i < pros.Length; i++)  {

                            pros[i].Kill();

                        } 

                    }  else if (pros.Length < 1) {  //程序不在进行中,开启进程

                            Process process = new Process();

                            process.StartInfo.FileName = this.process_address;

                            process.Start();  

                    }

                } catch (Exception ex) { 

                     result = false;

                }

            return result;

}

你可能感兴趣的:(C#,Office,Office.Interop)