Creating PDFs from Word and Excel Documents on IIS. For Free.

pdf.pngConverting a Microsoft Word or Excel file to a PDF is usually an expensive task. Commercial Services exist, but there are no free options. As well, you may not be able to use a service as your documents may be confidential and can’t be sent over national borders.

There is a simple solution that is free, secure and easy. Really.

Note: You will need full control over your IIS server to use this toolset

Summary: How we do it

Your web site will save the Word or Excel file onto the server’s file system. A Windows Service will watch that folder then when a document appears will send it off to the open source Libre Office and have it create the PDF via a headless call. Your web site will then pick up the PDF from the same folder and send it along.

Let’s do it!

Step 1: IIS Server Setup. You’ll need total control of the server.

  1. Create a file folder on the server that your web site’s IIS Application pool has read-write access to. For example c:\FileDrop
  2. Install LibreOffice on the server. Default settings.

Step 2: Web Site

Your web site will need to deposit the Word or Excel file into c:\FileDrop. You’ll need to handle that code, but it’s fairly simple. If you need help, Google it.

Step 3: The Windows Service

Create a new Console App. This will be your Windows Service.

Change Program.cs to this:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.ServiceProcess;
namespace PdfService
    internal class Program : ServiceBase
        private static void Main(string[] args)
            ServiceBase.Run(new Program());
        public Program()
            this.ServiceName = "DataSystem PDF";
        private FileSystemWatcher _watch;
        protected override void OnStart(string[] args)
                var path = System.Configuration.ConfigurationManager.AppSettings["PdfPath"];
                Trace.WriteLine("PDF: Using Path=" + path);
                if (!Directory.Exists(path))
                    Trace.WriteLine("PDF: Creating " + path);
                _watch = new FileSystemWatcher(System.Configuration.ConfigurationManager.AppSettings["PdfPath"]);
                Trace.WriteLine("PDF: Started File Watcher");
                _watch.Created += watch_Created;
                _watch.EnableRaisingEvents = true;
            catch (Exception e)
                Trace.WriteLine("PDF: Error " + e.Message); 
        private void watch_Created(object sender, FileSystemEventArgs e)
            Trace.WriteLine("PDF: WATCH: " + e.FullPath);
            if (Path.GetExtension(e.FullPath) == ".xlsx" || Path.GetExtension(e.FullPath) == ".docx")
                Trace.WriteLine("PDF: Processing " + e.FullPath);
                string exePdf = System.Configuration.ConfigurationManager.AppSettings["PdfExe"];
                string param = System.Configuration.ConfigurationManager.AppSettings["PdfParameters"];
                var pdfProcess = new Process();
                pdfProcess.StartInfo.FileName = exePdf;
                pdfProcess.StartInfo.Arguments = param + \"" + e.FullPath + "\"";
                pdfProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(e.FullPath); //!!!!This is really important!!!!!
                if (!pdfProcess.HasExited)
        protected override void OnStop()
            _watch = null;

Add a new class called PDFServiceInstaller.cs and change the code to this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration.Install;
using System.ComponentModel;
using System.ServiceProcess;
namespace PdfService
  public class PDFServiceInstaller : Installer
      private ServiceInstaller serviceInstaller;
      public PDFServiceInstaller()
      var processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new ServiceInstaller();
      //set the privileges
      processInstaller.Account = ServiceAccount.LocalSystem;
      serviceInstaller.DisplayName = "DataSystem PDF";
      serviceInstaller.StartType = ServiceStartMode.Automatic;
      //must be the same as what was set in Program's constructor
      serviceInstaller.ServiceName = "DataSystem PDF";
      this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
      void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
          using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))

Edit the App.Config and change it to this. Make any changes to paths you need.

<?xml version="1.0" encoding="utf-8"?>
    <add key="PdfExe" value="C:\Program Files (x86)\LibreOffice 6\program\soffice.exe"/>
    <add key="PdfParameters" value=" -norestore -nofirststartwizard -nologo -headless -convert-to pdf "/>
    <add key="PdfPath" value="c:\FileDrop"/>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>

Step 4: Installing the Service

Compile the PdfService and place it on your IIS server, in our example c:\PdfService. Here’s how you install it.

  1. Run the command prompt as ADMIN
  2. cd to -> C:\Windows\Microsoft.NET\Framework64\v4.0.30319
  3. Run InstallUtil.exe C:\PdfService\PdfService.exe

To uninstall
InstallUtil.exe -u C:\PdfService\PDFService.exe

To watch DEBUG info, Run DebugViewer from Sys Internals and enable Global Win32 watching in DebugViewer

Step 5: Start the service via the management tool Services.msc. Simple right click “DataSystem PDF”


Now that the service is running, you can test it by just dropping a Word or Excel file into the folder. A PDF should appear in 10-20 seconds depending on size and your server’s power.




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s