利用Office Save as PDF or XPS 实现Office批传PDF

      由于加班要转换Office文档及CAD为PDF,为了省事因此临时写个批量转换PDF工具。CAD已经有现成的一个叫Convert的工具,那就剩下Office这边的Word,Excel,PowerPoint的转换了。微软在Office 2007已经提供了一个叫save as pdf or xps的插件,但插件只能单个转换。因此网上搜了一下这方面的转换代码,搜来搜去很杂,itext,icreator等等,文档也不是很详细,于是想想微软应该提供了这方面的接口,查阅了一下MSDN,微软确实提供了.NET 调用Office com接口转换PDF的代码,以下简直封装的代码。

准备条件:

Office 12 dll  Microsoft.Office.Interop.Word,Microsoft.Office.Interop.Excel.....

save as pdf插件

代码部分:

Word代码

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;
using System.Threading;

namespace ConvertToPDF.BaseClass
{
public class WordToPDF:OfficeToPDF
{
#region 初始化参数
ApplicationClass wordApplication
= null ;
Document wordDocument
= null ;

object paramMissing;
WdExportFormat paramExportFormat;
bool paramOpenAfterExport;
WdExportOptimizeFor paramExportOptimizeFor;
WdExportRange paramExportRange;
int paramStartPage = 0 ;
int paramEndPage = 0 ;
WdExportItem paramExportItem;
bool paramIncludeDocProps;
bool paramKeepIRM;
WdExportCreateBookmarks paramCreateBookmarks;
bool paramDocStructureTags;
bool paramBitmapMissingFonts;
bool paramUseISO19005_1;
object paramReadOnly;
#endregion


public WordToPDF()
{
paramMissing
= Type.Missing;
paramExportFormat
= WdExportFormat.wdExportFormatPDF;
paramOpenAfterExport
= false ;
paramExportOptimizeFor
= WdExportOptimizeFor.wdExportOptimizeForPrint;
paramExportRange
= WdExportRange.wdExportAllDocument;
paramStartPage
= 0 ;
paramEndPage
= 0 ;
paramExportItem
= WdExportItem.wdExportDocumentContent;
paramIncludeDocProps
= true ;
paramKeepIRM
= true ;
paramCreateBookmarks
= WdExportCreateBookmarks.wdExportCreateWordBookmarks;
paramDocStructureTags
= true ;
paramBitmapMissingFonts
= true ;
paramUseISO19005_1
= false ;
paramReadOnly
= true ;

}

public override void SaveAsPDF( string paramSourceFilePath, string paramExportFilePath)
{
try
{
object paramSourceDocPath = ( object )paramSourceFilePath;
// Open the source document.
wordDocument = wordApplication.Documents.Open(
ref paramSourceDocPath, ref paramMissing, ref paramReadOnly,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing, ref paramMissing, ref paramMissing,
ref paramMissing);

// Export it in the specified format.
if (wordDocument != null )
wordDocument.ExportAsFixedFormat(paramExportFilePath,
paramExportFormat, paramOpenAfterExport,
paramExportOptimizeFor, paramExportRange, paramStartPage,
paramEndPage, paramExportItem, paramIncludeDocProps,
paramKeepIRM, paramCreateBookmarks, paramDocStructureTags,
paramBitmapMissingFonts, paramUseISO19005_1,
ref paramMissing);

// 通知成功
OnFinish(paramSourceFilePath, paramExportFilePath);
Thread.Sleep(
1000 );
}
catch (Exception ex)
{
OnError(ex, paramSourceFilePath, paramExportFilePath);
try
{
// Close and release the Document object.
if (wordDocument != null )
{
wordDocument.Close(
ref paramMissing, ref paramMissing,
ref paramMissing);
wordDocument
= null ;
}
}
catch (Exception e)
{
if (wordDocument != null )
wordDocument
= null ;
}
}
}

public override void Open()
{
wordApplication
= new ApplicationClass();
}

public override void Close()
{
try
{
// Close and release the Document object.
if (wordDocument != null )
{
wordDocument.Close(
ref paramMissing, ref paramMissing,
ref paramMissing);
wordDocument
= null ;
}
}
catch (Exception ex)
{
wordDocument
= null ;
}

try
{
if (wordApplication != null )
{
wordApplication.Quit(
ref paramMissing, ref paramMissing,
ref paramMissing);
wordApplication
= null ;
}
}
catch (Exception ex)
{
wordApplication
= null ;
ProcessManager.KillWordProcess();
}

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}

}
}

Excel代码

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Core;
using System.Threading;

namespace ConvertToPDF.BaseClass
{
public class ExcelToPDF:OfficeToPDF
{
#region 参数定义
Microsoft.Office.Interop.Excel.ApplicationClass excelApplication
= null ;
Workbook excelWorkBook
= null ;

object paramMissing = Type.Missing;
XlFixedFormatType paramExportFormat
= XlFixedFormatType.xlTypePDF;
XlFixedFormatQuality paramExportQuality
= XlFixedFormatQuality.xlQualityStandard;

bool paramOpenAfterPublish;
bool paramIncludeDocProps;
bool paramIgnorePrintAreas;
object paramFromPage;
object paramToPage;
#endregion


public ExcelToPDF()
{
paramMissing
= Type.Missing;
paramExportFormat
= XlFixedFormatType.xlTypePDF;
paramExportQuality
= XlFixedFormatQuality.xlQualityStandard;

paramOpenAfterPublish
= false ;
paramIncludeDocProps
= true ;
paramIgnorePrintAreas
= true ;
paramFromPage
= Type.Missing;
paramToPage
= Type.Missing;
}

public override void Open()
{
excelApplication
= new Microsoft.Office.Interop.Excel.ApplicationClass();
}

public override void Close()
{
try
{
// Close the workbook object.
if (excelWorkBook != null )
{
excelWorkBook.Close(
false , paramMissing, paramMissing);
excelWorkBook
= null ;
}
}
catch (Exception ex)
{
excelWorkBook
= null ;
}

try
{
// Quit Excel and release the ApplicationClass object.
if (excelApplication != null )
{
excelApplication.Quit();
excelApplication
= null ;
}
}
catch (Exception ex)
{
excelApplication
= null ;
ProcessManager.KillExcelProcess();
}

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
}

public override void SaveAsPDF( string paramSourceFilePath, string paramExportFilePath)
{
try
{
// Open the source workbook.
excelWorkBook = excelApplication.Workbooks.Open(paramSourceFilePath,
paramMissing, paramMissing, paramMissing, paramMissing,
paramMissing, paramMissing, paramMissing, paramMissing,
paramMissing, paramMissing, paramMissing, paramMissing,
paramMissing, paramMissing);

// Save it in the target format.
if (excelWorkBook != null )
excelWorkBook.ExportAsFixedFormat(paramExportFormat,
paramExportFilePath, paramExportQuality,
paramIncludeDocProps, paramIgnorePrintAreas, paramFromPage,
paramToPage, paramOpenAfterPublish,
paramMissing);

// 完成通知
OnFinish(paramSourceFilePath,paramExportFilePath);
Thread.Sleep(
1000 );
}
catch (Exception ex)
{
// Respond to the error.
OnError(ex,paramSourceFilePath,paramExportFilePath);
try
{
// Close the workbook object.
if (excelWorkBook != null )
{
excelWorkBook.Close(
false , paramMissing, paramMissing);
excelWorkBook
= null ;
}
}
catch (Exception e)
{
// Close the workbook object.
if (excelWorkBook != null )
excelWorkBook
= null ;
}
}
}
}
}

open打开一个Office进程(Word为Word.exe,Excel为Excel.exe进程,Close关闭此进程)。在转换Word中总会碰到一些意外(有时候是RPC不响应),当进程未正常关闭时则杀死此进程。

另外注意一点,在转换Word过程使用的是只读模式,否进出现意外后会弹出此Word文档副本操作,很麻烦。基类OfficeToPDF提供了事件通知机制,接口IOfficeToPDF提供了事件注册及公用的接口方法SaveAsPDF。事件主要用来控制异常和查看进度。

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConvertToPDF.BaseClass
{
public class PDFConvertEventArgs : EventArgs
{
public PDFConvertEventArgs()
{ }

public Exception Exception { set ; get ; }

public string SourceFilePath { set ; get ; }

public string ExportFilePath { set ; get ; }
}

public interface IOfficeToPDF
{
void SaveAsPDF( string paramSourceFilePath, string paramExportFilePath);
event EventHandler < PDFConvertEventArgs > Error;
event EventHandler < PDFConvertEventArgs > Finish;
void Open();
void Close();

}

public abstract class OfficeToPDF : IOfficeToPDF
{
#region IOfficeToPDF 成员

public virtual void SaveAsPDF( string paramSourceFilePath, string paramExportFilePath)
{
throw new NotImplementedException();
}

public event EventHandler < PDFConvertEventArgs > Error;

public event EventHandler < PDFConvertEventArgs > Finish;

protected void OnError(Exception ex)
{
if (Error != null )
{
PDFConvertEventArgs args
= new PDFConvertEventArgs();
args.Exception
= ex;

Error(
this , args);
}
}

protected void OnError(Exception ex, string paramSourceFilePath, string paramExportFilePath)
{
if (Error != null )
{
PDFConvertEventArgs args
= new PDFConvertEventArgs();
args.Exception
= ex;
args.SourceFilePath
= paramSourceFilePath;
args.ExportFilePath
= paramExportFilePath;
Error(
this , args);
}
}

protected void OnFinish()
{
if (Finish != null )
{
PDFConvertEventArgs args
= new PDFConvertEventArgs();
Finish(
this , args);
}
}

protected void OnFinish( string paramSourceFilePath, string paramExportFilePath)
{
if (Finish != null )
{
PDFConvertEventArgs args
= new PDFConvertEventArgs();
args.SourceFilePath
= paramSourceFilePath;
args.ExportFilePath
= paramExportFilePath;
Finish(
this , args);
}
}

public virtual void Open()
{
throw new NotImplementedException();
}

public virtual void Close()
{
throw new NotImplementedException();
}

#endregion
}
}

转Word总会出现一些莫名其妙的问题,没办法只增加了一个杀死进程的类

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;

namespace ConvertToPDF.BaseClass
{
class ProcessManager
{
// 获取程序集
// private static Assembly _reflect = Assembly.Load("ExcelConvert");

[DllImport(
" kernel32.dll " )]
private static extern IntPtr _lopen( string lpPathName, int iReadWrite);

[DllImport(
" kernel32.dll " )]
private static extern bool CloseHandle(IntPtr hObject);

private static int OF_READWRITE = 2 ;
private static int OF_SHARE_DENY_NONE = 0x40 ;
private static readonly IntPtr HFILE_ERROR = new IntPtr( - 1 );

/// <summary>
/// 判断文是否被占用
/// </summary>
///
///
///
/// <param name="filePath"></param>
/// <returns></returns>
public static bool FileIsUsing( string filePath)
{
bool result = false ;
IntPtr vHandle
= _lopen(filePath, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
result
= true ;
}
CloseHandle(vHandle);
return result;
}

/// <summary>
/// 杀死EXCEL进程
/// </summary>
public static void KillExcelProcess()
{
KillProcess(
" Excel " );
}

/// <summary>
/// 杀死EXCEL进程
/// </summary>
public static void KillWordProcess()
{
KillProcess(
" Word " );
}

/// <summary>
/// 杀死进程
/// </summary>
public static void KillProcess( string processName)
{
System.Diagnostics.Process[] excelProcess
= System.Diagnostics.Process.GetProcessesByName(processName);
foreach (System.Diagnostics.Process process in excelProcess)
{
if (process != null )
{
process.Kill();
}
}
}

/// <summary>
/// 杀死进程
/// </summary>
public static bool ProcessIsRun( string processName)
{
bool isRun = false ;
System.Diagnostics.Process[] excelProcess
= System.Diagnostics.Process.GetProcessesByName(processName);
foreach (System.Diagnostics.Process process in excelProcess)
{
if (process != null )
isRun
= true ;
}
return isRun;
}

}
}

看一下简单调用的方式

View Code
IOfficeToPDF word = new WordToPDF();
word.Error
+= new EventHandler < PDFConvertEventArgs > (office_Error);
word.Finish
+= new EventHandler < PDFConvertEventArgs > (office_Finish);
word.Open();
IOfficeToPDF excel
= new ExcelToPDF();
excel.Error
+= new EventHandler < PDFConvertEventArgs > (office_Error);
excel.Finish
+= new EventHandler < PDFConvertEventArgs > (office_Finish);
excel.Open();

word.SaveAsPDF(sourceFilePath, exportFilePath);

excel.SaveAsPDF(sourceFilePath, exportFilePath);

excel.Close();
word.Close();

代码很简单,忽忙写的,所以就不注释了。另外程序在运行的尽量不要直接关闭(所以我屏掉了关闭等按钮),否则像wordDocumnet这个没正常关闭,下次再转换的时候会引起一些不必要的麻烦。(基本是RPC不响应,估计频率调COM接口的问题,还有就是WORD不停弹只读副本的原因等等)

看下程序的运行效果:

时间关系简单封装后,做了100份批传测试没啥大问题。

现将源码发布出来,WordDocument关闭异常问题还没解决,有知道原因的可以指点或修正回发我一份。

Office批传PDF工具

转载于:https://www.cnblogs.com/mecity/archive/2011/06/23/2087973.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值