. net uses the open source software Openoffice to realize the document (word ppt excel) to pdf service

preface

I did a project a few years ago. There is a need to browse word, PDF, PPT and other documents online.  

I think of it recently. I think it's a little interesting, so I'll record it.

Current scheme:

Because net, for example aspose.net , spire.doc for .net Wait, but these are all for a fee.

Microsoft's Office also provides com component to realize document transcoding service. The premise is that Office must be installed on Windows Server, but Office also needs a license

Considering the cost.

Therefore, open source is adopted in the end OpenOffice +openOffice SDK Deploy in a Windows server to meet this requirement

 

prerequisite:

In the windows server, because it was a project many years ago, it was used at that time net framework 4.6.1, Linux system has not tried.

OpenOffice software

The version of OpenOffice SDK must be consistent, otherwise there will be problems.

 

The following are two middleware services

The purpose of Windows Service} is to monitor the input folder. When there are files in the folder {InputFolder}, the transcoding operation will start.

When Windows Console App performs transcoding, it transcodes the files in the {InputFolder} folder and places them in the {OutputFolder} directory.

Then perform subsequent operations.

 

Windows Service uses the Process class to call the Console App application.

The following is the core code of Console App document transcoding.  

  1     public class OpenOfficeHelper : IOpenOffice
  2     {
  3         // For thread safety
  4         private Mutex _openOfficeLock;
  5 
  6         /// <summary>
  7         /// constructor
  8         /// </summary>
  9         public OpenOfficeHelper()
 10         {
 11             _openOfficeLock = new Mutex(false, "OpenOfficeMutexLock-MiloradCavic");
 12         }
 13 
 14         /// <summary>
 15         /// Converts document to PDF
 16         /// </summary>
 17         /// <param name="sourcePath">Path to document to convert(e.g: C:\test.doc)</param>
 18         /// <param name="destinationPath">Path on which to save PDF (e.g: C:\test.pdf)</param>
 19         /// <returns>Path to destination file if operation is successful, or Exception text if it is not</returns>
 20         public void ConvertDocToPDF(string sourcePath, string destinationPath)
 21         {
 22             bool obtained = _openOfficeLock.WaitOne(60 * 1000, false);
 23 
 24             XComponent xComponent = null;
 25             try
 26             {
 27                 if (!obtained)
 28                 {
 29                     throw new System.Exception(string.Format("Request for using OpenOffice wasn't served after {0} seconds. Aborting...", 30));
 30                 }
 31 
 32                 sourcePath = PathConverter(sourcePath);
 33                 destinationPath = PathConverter(destinationPath);
 34 
 35                 // Set the properties before loading the file to hide when the file is opened
 36                 PropertyValue[] loadDesc = new PropertyValue[1];
 37                 loadDesc[0] = new PropertyValue();
 38                 loadDesc[0].Name = "Hidden";
 39                 loadDesc[0].Value = new uno.Any(true);
 40 
 41                 //Get a ComponentContext
 42                 unoidl.com.sun.star.uno.XComponentContext xLocalContext = uno.util.Bootstrap.bootstrap();
 43 
 44                 //Get MultiServiceFactory
 45                 unoidl.com.sun.star.lang.XMultiServiceFactory xRemoteFactory = (unoidl.com.sun.star.lang.XMultiServiceFactory)xLocalContext.getServiceManager();
 46 
 47                 //Get a CompontLoader
 48                 XComponentLoader aLoader = (XComponentLoader)xRemoteFactory.createInstance("com.sun.star.frame.Desktop");
 49 
 50                 //Load the sourcefile
 51                 xComponent = aLoader.loadComponentFromURL(sourcePath, "_blank", 0, new unoidl.com.sun.star.beans.PropertyValue[0]);
 52 
 53                 //Wait for loading
 54                 while (xComponent == null)
 55                 {
 56                     Thread.Sleep(3000);
 57                 }
 58 
 59                 SaveDocument(xComponent, destinationPath);
 60 
 61                 xComponent.dispose();
 62 
 63             }
 64             catch (System.Exception ex)
 65             {
 66                 throw ex;
 67             }
 68             finally
 69             {
 70                 Process[] pt = Process.GetProcessesByName("soffice.bin");
 71                 if (pt != null && pt.Length > 0)
 72                 {
 73                     foreach (var item in pt)
 74                     {
 75                         item.Kill();
 76                     }
 77                 }
 78                 if (obtained)
 79                 {
 80                     _openOfficeLock.ReleaseMutex();
 81                 }
 82             }
 83         }
 84 
 85         /// <summary>
 86         /// Execute save
 87         /// </summary>
 88         /// <param name="xComponent">The x component.</param>
 89         /// <param name="filePath">Name of the file.</param>
 90         private void SaveDocument(XComponent xComponent, string filePath)
 91         {
 92             unoidl.com.sun.star.beans.PropertyValue[] propertyValue = new unoidl.com.sun.star.beans.PropertyValue[1];
 93 
 94             propertyValue[0] = new unoidl.com.sun.star.beans.PropertyValue();
 95             propertyValue[0].Name = "FilterName";
 96             propertyValue[0].Value = new uno.Any("writer_pdf_Export");
 97 
 98             ((XStorable)xComponent).storeToURL(filePath, propertyValue);
 99         }
100 
101         /// <summary>
102         /// Convert into OO file format
103         /// </summary>
104         /// <param name="file">The file.</param>
105         /// <returns>The converted file</returns>
106         private static string PathConverter(string file)
107         {
108             try
109             {
110                 file = file.Replace(@"\", "/");
111 
112                 return "file:///" + file;
113             }
114             catch (System.Exception ex)
115             {
116                 throw ex;
117             }
118         }
119 
120 
121     }

The principle of transcoding is to call OpenOffice software and save it as a PDF file.

The Windows Service code is not released. In fact, it is to start a Timer to regularly monitor whether there are files to be transcoded in the {InputFolder} folder. If there are, start a Process instance and execute the Console App application for transcoding.

 

Next is the pit

1. When the first transcoding operation is performed, the Console App will call OpenOffice software, the screen will call OpenOffice software, and a pop-up window waiting to fill in OpenOffice will pop up on the interface (this pop-up window will only pop up once and will not pop up). The pop-up window must fill in the basic name, otherwise OpenOffice will stay in this interface.

2. However, by default, our Windows Service runs under the Local System account, and the Console App is started by Windows Service. When we really use Window Service to run, we will find that transcoding cannot be performed.

3. Check the task manager and find that the OpenOffice software has been opened, and the running user is just OpenOffice, i.e. software Bin process.

There are two solutions:

1. Create a new windows user DocConverter, put the user under the administrator group, then log in to windows as the user, open OpenOffice, fill in the corresponding basic information after the first pop-up window, change the Windows Service startup user to DocConverter user, and then start the transcoding service. At this time, you will find that it can work normally.

 

2. Find a way to open OpenOffice as a Local System user, and then fill in the basic information of OpenOffice. How to open it? Here is the help PsTools Tool, open it in cmd command line mode.

 

Basically.

reference resources:

How to run the specified program as system?

OpenOffice

 

Keywords: C# .NET

Added by wolf on Fri, 21 Jan 2022 22:13:17 +0200