4

Version 4.3

In C# I am trying to use the headless option to convert a XLSX to a PDF but nothing happens when I run this from ASP.NET or a simple Command prompt.

            var pdfProcess = new Process();
            pdfProcess.StartInfo.FileName = exe;
            pdfProcess.StartInfo.Arguments = param + " \"" + fullDocPath +"\"";
            pdfProcess.Start();

Where the exe and params are:

C:\Program Files (x86)\LibreOffice 4\program\soffice.exe

  -norestore -nofirststartwizard -nologo -headless -convert-to pdf  "c:\UDS_Docs\temp\Teller Roster National.xlsx"

I used the GUI to test that LibreOffice can convert the file and it worked fine.

tereško
  • 58,060
  • 25
  • 98
  • 150
Ian Vink
  • 66,960
  • 104
  • 341
  • 555

3 Answers3

11

Here is how to convert Excel, Word etc to PDF on an ASP.NET MVC web site at no cost:

Install LibreOffice, free

Set the current directory to the same folder as the existing XLS. This seems to be the missing piece.

Run this:

"C:\Program Files (x86)\LibreOffice 4\program\soffice.exe"  -norestore -nofirststartwizard -headless -convert-to pdf  "TheFile.xlsx"

In C#:

var pdfProcess = new Process();
pdfProcess.StartInfo.FileName = exePdf;
pdfProcess.StartInfo.Arguments = "-norestore -nofirststartwizard -headless -convert-to pdf  \"TheFile.xlsx\"";
pdfProcess.StartInfo.WorkingDirectory = docPath; //This is really important
pdfProcess.Start();

Make sure your WorkerProcess has access to the exe, by default it does not.

Kamil Budziewski
  • 22,699
  • 14
  • 85
  • 105
Ian Vink
  • 66,960
  • 104
  • 341
  • 555
  • thank you very much for your answer. Workingdirectory is most importent thing in this i finally come to know after wasting half of the day ;) – monikapatelIT Sep 01 '16 at 04:05
  • 2
    Just to add to this because I've been crawling up the wall trying to figure it all out. Basically in your application pool you want to have Load User Profile to true - I think it's default but mine was false and that caused no end of trouble. – Richard Housham Oct 06 '17 at 13:57
  • Does pdfProcess end on its own? or does it require pdfProcess.Stop() at the end? I am worried about memory leaks. – Irish Redneck May 02 '22 at 14:47
2

Turns out that the exe I am trying to run needs a lot of access (It's LibreOffice, used to make the PDFs from Excel).

So the easiest solution was to just make a super simple WindowsService, install it and have that run. The Web site drops a load of data into a place the service watches, then does the work and the web site picks it up later. That way I can run the web site in minimum permissions and still have a major service running.

Ian Vink
  • 66,960
  • 104
  • 341
  • 555
  • Thank you for your insights, but can you please point me to what permissions would the website need and to what directories. I have granted IIS_IUSRS users all the permissions for the LibreOffice directory and all the permissions for the output directory and input file, but still nothing happens. What may be I missing? – gyosifov Sep 13 '17 at 14:38
  • 1
    You don't. Create a Windows Service and have that monitor a drop folder that the web site drops the file into. The web server does not run LibreOffice, the WindowsService does. You need to write a Windows Service. – Ian Vink Sep 14 '17 at 16:23
2

Base on @BahaiResearch.com 's GREAT answer, I add some function to the convert code:

        string fileName = Path.GetFileName(excelFilePath);
        string fileDir = Path.GetDirectoryName(excelFilePath);

        var pdfProcess = new Process();
        pdfProcess.StartInfo.FileName = @"C:\Program Files\LibreOffice\program\soffice.exe";
        pdfProcess.StartInfo.Arguments =
            String.Format("--norestore --nofirststartwizard --headless --convert-to pdf  \"{0}\""
                                  , fileName);
        pdfProcess.StartInfo.WorkingDirectory = fileDir; 
        pdfProcess.StartInfo.RedirectStandardOutput = true;
        pdfProcess.StartInfo.RedirectStandardError = true;
        pdfProcess.StartInfo.UseShellExecute = false;
        pdfProcess.Start();

        string output = pdfProcess.StandardOutput.ReadToEnd();
        string error = pdfProcess.StandardError.ReadToEnd();

Some reference: StandardOutput UseShellExecute

yu yang Jian
  • 6,680
  • 7
  • 55
  • 80