Introduction
This PDFConverter converts Microsoft Word documents (*.doc) into PDF-files on a Webserver. There is a simple Webform, where you can upload your Word-Document, which will be converted and sent back as a PDF-File.
Prerequisites
Background
There are a lot of people trying to do this Word => PDF conversion using Com Interop directly from their ASP.NET code. As Microsoft reports, Word or any other Office products are not recommended to be automated on a server. The Office products are optimized for running as client applications using a Desktop for interaction. This is why, if you want to use an Office-product in any kind on a server, there must be a User logged in. But then, there is the next problem: Using COM Interop directly from ASP.NET means, the call is made by the ASP.NET-User which is not allowed to interact with Word. Even if this setting is changed in the DCOM-configuration, there will still remain a lot of access rights-related problems with this solution. That's why I considered the following way to do it:
Explanation
The PDFConverter.exe is an executable containing RemotableObjects running all the time on the server. To do this, a User must be logged in. When starting the PDFConverter.exe, it will be checked if Word 2007 is available or not. I configured that Word should be Visible for this check, so you can see if Microsoft Word quickly opens and closes again, everything works fine.
Then there is the normal website with fileupload. Store the uploaded file somewhere (don't forget to give the appropriate rights to the ASP.NET and IIS User on this folder, in order to be able to save the uploaded file there).
When the file is saved, you call the
convert()
-method of the
PDFConverter.RemoteConverter
Instance which you get using Remoting (see code). The whole conversion thing is then called from the
PDFConverter.exe which runs on a "Desktop" with the appropriate rights to interact with Microsoft Word.
When the conversion is finished, you can do whatever you want with the pdf-file. In the example, it will be streamed back as filedownload to the client.
Using the Code
Remoting
Serverside PDFConverter.exe (app.config):
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown objecturi="RemoteConverter"
type="PDFConverter.RemoteConverter, RemoteConverter" mode="Singleton">
</wellknown>
<channels>
<channel port="8989" ref="http">
</channel>
</channels>
</service>
</application>
</system.runtime.remoting></configuration>
Serverside PDFConverter.exe (Form1.cs):
...
RemotingConfiguration.Configure("PDFConverter.exe.config",false);
RemotingConfiguration.RegisterWellKnownServiceType(new RemoteConverter().GetType(),
"RemoteConverter",WellKnownObjectMode.Singleton);
...
Serverside ASP.NET:
Add a Reference to the PDFConverter and then use this code to create instance: Default.aspx.cs:
...
converter=(PDFConverter.RemoteConverter)Activator.GetObject
(typeof(PDFConverter.RemoteConverter),"http://localhost:8989/RemoteConverter");
...
Don't forget to set your correct storefolder in the Default.aspx.cs.
Converting
Serverside PDFConverter.exe:
I copied the important part of code for the PDF-Conversion using Word 2007 from a MSDN-Article. See here: Saving Word 2007 Documents to PDF and XPS Formats.
Serverside ASP.NET:
...
FileUpload1.SaveAs(sourcefile);
converter.convert(sourcefile, outputfile);
if (System.IO.File.Exists(sourcefile))
System.IO.File.Delete(sourcefile);
System.IO.FileInfo downloadFile = new System.IO.FileInfo(outputfile);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.AddHeader("Content-Disposition",
string.Format("attachment; filename={0}",
downloadFile.Name));
HttpContext.Current.Response.AddHeader("Content-Length", downloadFile.Length.ToString());
HttpContext.Current.Response.WriteFile(downloadFile.FullName);
HttpContext.Current.Response.End();
HttpContext.Current.Response.Close();
...
Conclusion
As you see, it's not too much code. The whole conversion-code is copied from MSDN, so it's more just the idea doing this with Remoting. I am not a Remoting-expert, so there might be easier/nicer/better ways to do this, so please tell me if you have any considerations. Anyway, I think this solution is much better than trying to use Word directly from the ASP.NET-code.
History
- July 30th, 2009: Initial version