实现word转pdf
项目中需要在线实现word转pdf,网上很多方法都是不支持IIS的或者只是WINFORM的。自己整理了个可用的方法如下。
主要要调用的com组件有Acrobat Distiller[PDF公司出品]与WORD。这两个组件需要机器安装Adobe Acrobat Professional 7.0及以上版本,由于此软件为付费软件故需方法破解。而word组件需要机器安装microsoft office word 2003软件。
在实际部署到IIS上去时,由于IIS的NetWork Service[针对IIS6.0]用户没有调用本地COM组件的权限,代码在IIS时,就是转换不成功,花了点时间,发现原因是两个的用户不同,COM组件是管理员用户,而IIS是network Service。想通过更改设置COM组件权限来解决问题,改了不少,效果是从一个错误,变成了另一个错误。而且有组件并未经过注册即根本无法给其赋权限。
解决方法是在web.config中使用身份模拟,在<system.web>节中加入 <identity impersonate="true" userName="你的用户名" password="密码"/>,这样IIS在调用com组件的时候就有权限了。
以上仅仅是理论上解决问题,实际测试中还是有各种问题,譬如word转换完毕的关闭问题以及中间文档的删除问题。总结实现方法如下:
1:在web.config中使用身份模拟,在<system.web>节中加入 <identity impersonate="true" userName="你的用户名" password="密码"/>
2:安装Adobe Acrobat Professional 7.0及其其破解(未破解版本只能试用30天)。
3:安装虚拟打印机:进入WINDOWS的控制面板,进入打印机,点击"打印机和传真"图标,在安装对话框上"下一步",注意留意去掉自动检测并安装即插即用打印机,出现选择打印机时,在制造商一栏中选择"Generic",在打印机一栏中,选择"MS Publisher Color Printer",然后一路按下一步,知道安装结束。以下代码并没有提供当前的打印机,而是使用系统默认的,即设置的"MS Publisher Color Printer"。
4:必须添加引用Interop.ACRODISTXLib.dll与Microsoft.Office.Interop.Word.dll,可以从COM组件中添加。由于这两个组件已经提取出来,直接拷贝到BIN目录下即可。
主要实现代码:
using oWord = Microsoft.Office.Interop.Word;
using System.Diagnostics;
private void wordConvert(string wordname,string wordPath,string pdfPath)
{
oWord._Document m_Document = null;
oWord._Application m_wordApplication = null;
object oMissing = Type.Missing;
oWord.ApplicationClass word = new Microsoft.Office.Interop.Word.ApplicationClass();
object obj = System.Reflection.BindingFlags.InvokeMethod;
Type wordType = word.GetType();
oWord.Documents docs = word.Documents;
Type docsType = docs.GetType();
object objDocName = wordPath;
oWord.Document doc = (oWord.Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, docs, new Object[] { objDocName, true, true });
//打印输出到指定文件
Type docType = doc.GetType();
object printFileName = @"c:\test.ps";
docType.InvokeMember("PrintOut", System.Reflection.BindingFlags.InvokeMethod, null, doc, new object[] { false, false, oWord.WdPrintOutRange.wdPrintAllDocument, printFileName });
object savechanges = Microsoft.Office.Interop.Word.WdSaveOptions.wdSaveChanges;
object saveasPath = Server.MapPath("../") + "docsave\\000temp" + wordname + ".doc";
//必须另存为!
doc.SaveAs(ref saveasPath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
//必须关闭
doc.Close(ref savechanges, ref oMissing, ref oMissing);
wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null,word, null);
//删除另存为文件
try
{
System.IO.File.Delete(Server.MapPath("../") + "docsave\\000temp" + wordname + ".doc");
}
catch
{
}
string o1 = "c:\\test.ps";//与生产的PS文件同步
string o2 = pdfPath;
string o3 = "";
//引用将PS转换成PDF的对象
try
{
ACRODISTXLib.PdfDistillerClass pdf = new ACRODISTXLib.PdfDistillerClass();
Type pdfType = pdf.GetType();
pdfType.InvokeMember("FileToPDF", System.Reflection.BindingFlags.InvokeMethod, null, pdf, new object[] { o1, o2, o3 });
pdf = null;
System.IO.File.Delete(Server.MapPath("../") + "PDF\\" + wordname + ".log");//清除转换日志文件
}
catch { throw new Exception("PS转PDF处出错!"); }
//为防止本方法调用多次时发生错误,必须停止acrodist.exe进程
foreach (Process proc in System.Diagnostics.Process.GetProcesses())
{
int begpos;
int endpos;
string sProcName = proc.ToString();
begpos = sProcName.IndexOf("(") + 1;
endpos = sProcName.IndexOf(")");
sProcName = sProcName.Substring(begpos, endpos - begpos);
if (sProcName.ToLower().CompareTo("acrodist") == 0)
{
try
{
proc.Kill();
}
catch { }
break;
}
}
}