利用OpenOffice将多种文档转换为PDF源码

一直在解决PDF文档转换的问题,今天无意中搜索到老外的一段代码,好象可以解决,先记下来.

好象注释还不是英文的,有明白的解释一下

 

代码
  1 using System;
  2 using System.Text;
  3 using System.Diagnostics;
  4 using System.Threading;
  5 using Tyma.ToPDF.Support;
  6 //
  7 using unoidl.com.sun.star.lang;
  8 using unoidl.com.sun.star.uno;
  9 using unoidl.com.sun.star.bridge;
 10 using unoidl.com.sun.star.frame;
 11 
 12 namespace Tyma.Support.OpenOffice
 13 {
 14     /*
 15      pri konverzi pres Open Office se skryva hlavni okno aplikace, zustava zobrazen jen splash screen,
 16      ktery lze vypnout v souboru program/soffice.ini nastavenim promene Logo=0
 17     */
 18 
 19     /// <summary>
 20     /// Predstavuje stav timeru.
 21     /// </summary>
 22     internal class TimerStateOO
 23     {
 24         private int count;
 25         private int endCount;
 26         private Timer timer = null;
 27 
 28         /// <summary>
 29         /// Urcuje kolikrat byla metoda timeru spustena
 30         /// </summary>
 31         internal int Count
 32         {
 33             get { return count; }
 34             set { count = value; }
 35         }
 36 
 37         /// <summary>
 38         /// Pocet kolikrat ma byt metoda timeru vykonana
 39         /// </summary>
 40         internal int EndCount
 41         {
 42             get { return endCount; }
 43             set { endCount = value; }
 44         }
 45 
 46         /// <summary>
 47         /// Odkaz na timer (bude mozne s nim manipulovat v timer metode)
 48         /// </summary>
 49         internal Timer Timer
 50         {
 51             get { return timer; }
 52             set { timer = value; }
 53         }
 54     }
 55 
 56     internal static class TimerForOpenOffice
 57     {
 58         private static GDebug log = null;
 59         private static Timer m_oTimer = null;
 60 
 61         public static void Init(GDebug dbg)
 62         {
 63             log = dbg;
 64         }
 65 
 66         /// <summary>
 67         /// Run timer
 68         /// </summary>
 69         /// <param name="EndCount">Pocet zavolani obsluzne funkce casovace v definovanem intervalu</param>
 70         /// <returns></returns>
 71         internal static void RunTimer()
 72         {
 73             int EndCount = 50, interval = 200;
 74             TimerStateOO lState = new TimerStateOO();
 75             lState.EndCount = EndCount;
 76             //
 77             m_oTimer = new Timer(new TimerCallback(DoTestWarningOODialog), lState, 0, interval);
 78             lState.Timer = m_oTimer;
 79 
 80             //dokud beh timeru ukoncen cekame
 81             while (lState.Timer != null)
 82             {
 83                 Thread.Sleep(100);
 84             }
 85             //
 86             log.WriteLn("- timer was terminated");
 87         }
 88 
 89         internal static void StopTimer()
 90         {
 91             m_oTimer.Dispose();
 92             m_oTimer = null;
 93             log.WriteLn("- timer was stopped.");
 94         }
 95 
 96         private static bool FindWarningWindow()
 97         {
 98             int l_nHandle = 0;
 99             l_nHandle = Win32.FindWindow("SALSUBFRAME""Chyby během exportu PDF");   // TODO: prelozit i pro anglickou 
100 
101 verzi windows
102 
103             log.WriteLn(String.Format("- handle: {0}", l_nHandle));
104 
105             if (l_nHandle == 0)
106             {
107                 log.WriteLn("- Window handle not found. [FALSE]");
108                 return false;
109             }
110 
111             //IntPtr hwndChild = Win32.FindWindowEx((IntPtr)l_nHandle, IntPtr.Zero, "Button", "&Tisk");
112 
113             if(Win32.SendMessage((int)l_nHandle, Win32.WM_CLOSE, 00== 0)
114                 log.WriteLn("- Warning dialog was closed [OK]");
115             else
116                 log.WriteLn("- Warning dialog wasn't closed  [FALSE]");
117             
118             return true;
119         }
120 
121         /// <summary>
122         /// event of timer
123         /// </summary>
124         /// <param name="state"></param>
125         private static void DoTestWarningOODialog(object state)
126         {
127             TimerStateOO lState = (TimerStateOO)state;
128             lState.Count++;
129             log.WriteLn(String.Format("Actual state timer is {0}: {1}", lState.EndCount, lState.Count));
130 
131             if (lState.Count == lState.EndCount || FindWarningWindow())
132             {
133                 log.WriteLn("- timer was stoped.");
134                 lState.Timer.Dispose();
135                 lState.Timer = null;
136             }
137         }
138     }
139 
140     /// <summary>
141     /// Converter to pdf with application OpenOffice
142     /// </summary>
143     sealed public class TOpenOffice : IGExternalConverter
144     {
145         private const string m_csOpenOffice = "OpenOffice";
146 
147         public TOpenOffice()
148         {
149             AppDomain.CurrentDomain.AssemblyResolve -= _searchAssembly; //cleans up previous events, may not be needed.
150             AppDomain.CurrentDomain.AssemblyResolve += _searchAssembly; //registered the event
151         }
152 
153         public static bool Is64bitOS
154         {
155             get { return (Environment.GetEnvironmentVariable("ProgramFiles(x86)"!= null); }
156         }
157 
158         private static System.Reflection.Assembly _searchAssembly(Object o, ResolveEventArgs e) 
159         {
160             // TODO: overit, odmaZat staticke reference potom!
161             GDebug l_oLog = new GDebug(m_csOpenOffice);
162             l_oLog.WriteLn("- class: GOpenOffice, method: _searchAssembly(Object o, ResolveEventArgs e)");
163 
164             string l_sName = e.Name.Split(',')[0+ ".dll";
165             if (l_sName.StartsWith("cli_"))
166                 return System.Reflection.Assembly.LoadFrom(GetDirfromRegistry() + @"ToPDF\" + l_sName);
167             else
168                 return null
169         }
170 
171         private static string GetDirfromRegistry()
172         {
173             try
174             {
175                 // TODO: 64bit udelat
176                 Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(Is64bitOS? 
177 
178 @"SOFTWARE\Wow6432Node\Tyma\SHARED\INSTALL32\":
179                                                     @"SOFTWARE\Tyma\SHARED\INSTALL32\");
180 
181                 return (rk != null? (rk.GetValue("ADRTOPDF", String.Empty) as string).Trim() + @"TOPDF\" : 
182 
183 String.Empty;
184             }
185             catch
186             {
187                 return String.Empty;
188             }
189         }
190 
191         private struct SUPPORTED_TYPE
192         {
193             public const string m_csSUPPORTED_TYPES = @".docx|.doc|.rtf|.txt|.xls|.xlsx|.odt|.sxw|" +
194             ".sdw|.vor|.out|.ods|.ots|.sxc|.stc|.xlt|.odp|.otp|.sxi|.sti|.ppt|.odg|.sxd|.std|.sda|" +
195             ".jpg|.jpeg|.tif|.tiff|.bmp|.png|.gif|.txt|.html|.htm";
196 
197 /*
198                 case ".odt":
199                 case ".sxw":
200                 case ".sdw":
201                 case ".vor":
202                 case ".out":
203                 case ".ods":
204                 case ".ots":
205                 case ".sxc":
206                 case ".stc":
207                 case ".xlt":
208                 case ".odp"://  open office kresba format
209                 case ".otp":
210                 case ".sxi":
211                 case ".sti":
212                 case ".ppt":
213                 case ".odg"://  open office prezentace format
214                 case ".otg":
215                 case ".sxd":
216                 case ".std":
217                 case ".sda":
218 */
219             public const string DOC = ".doc";
220             public const string DOCX = ".docx";
221             public const string RTF = ".rtf";
222             public const string TXT = ".txt";
223             public const string XLS = ".xls";
224             public const string XLSX = ".xlsx";
225         }
226 
227         #region Implements method interface IGExternalConverter
228         //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
229         public bool Initialise(out string ErrText, GDebug debug)
230         {
231             ErrText = String.Empty;
232             GDebug l_oLog = new GDebug(m_csOpenOffice);
233 
234             try
235             {
236                 lock (this)
237                 {
238                     GCommon.Init(l_oLog);
239                     l_oLog.WriteLn("------------------------------------------------------------------------------------
240 
241 -------");
242                     l_oLog.WriteLn("- Tyma.Support.PDFCreator.dll, class: GOpenOffice, method: 
243 
244 IGExternalConverter.Initialise");
245 
246                     if (GCommon.IsInstalledOO())
247                     {
248                         l_oLog.WriteLn("- OpenOffice is instaled [OK]");
249                         return true;
250                     }
251                     else
252                     {
253                         l_oLog.WriteLn("- is not instaled OpenOffice. [FALSE]");
254                         ErrText = "- is not instaled OpenOffice. [FALSE]";
255                         return false;
256                     }
257                 }// end lock
258             }
259             catch (System.Exception exp)
260             {
261                 ErrText = exp.Message;
262                 return false;
263             }
264         }
265 
266         public bool IsSupportedType(string extens)
267         {
268             return (SUPPORTED_TYPE.m_csSUPPORTED_TYPES.IndexOf(extens, StringComparison.OrdinalIgnoreCase) >= 0);
269         }
270 
271         public void ToPdf(byte[] sourcedata, string sourcefilename, out byte[] destdata, GDebug debug)
272         {
273             debug.WriteLn("- PDFCreator: this method is not supported. [FALSE]");
274             destdata = null;
275         }
276 
277         public void ToPdf(string sourcefile, string destinfile, GDebug debug)
278         {
279             debug.WriteLn("- PDFCreator: this method is not supported. [FALSE]");
280         }
281 
282         public bool ToPdf(string sourcefile, ref string destinfile, out string errortext)
283         {
284             return all2PDF(sourcefile, ref destinfile, out errortext);
285         }
286 
287         public void Done() { }
288         #endregion
289 
290 
291         /// <summary> 
292         /// Starts the open office.
293         /// </summary> 
294         /// <returns></returns> 
295         private bool StartOpenOffice(out string errortext)
296         {
297             errortext = String.Empty;
298             GDebug l_oLog = new GDebug(m_csOpenOffice);
299 
300             try
301             {
302                 ProcessStartInfo theProcess = new ProcessStartInfo("soffice.exe");
303                 theProcess.WindowStyle = ProcessWindowStyle.Hidden;
304                 Process.Start(theProcess);
305                 l_oLog.WriteLn("- OpenOffice proces is running.");
306 
307                 return true;
308             }
309             catch(System.Exception exp)
310             {
311                 l_oLog.WriteLn("- OpenOffice proces is not running. EXCEPTION:" + exp.Message);
312                 errortext = "- OpenOffice proces is not running. EXCEPTION:" + exp.Message;
313                 return false;
314             }
315         }
316 
317         /// <summary>
318         /// convert all support types
319         /// </summary>
320         /// <param name="sourcefile"></param>
321         /// <param name="destinationfile"></param>
322         /// <param name="errortext"></param>
323         /// <returns></returns>
324         public bool all2PDF(string sourcefile, ref string destinationfile, out string errortext)
325         {
326             GDebug l_oLog = new GDebug(m_csOpenOffice);
327             //-----------init log support:
328             GCommon.Init(l_oLog);
329             TimerForOpenOffice.Init(l_oLog);
330             //----------------------------
331 
332 
333             l_oLog.WriteLn("------------------------------");
334             l_oLog.WriteLn("- Converter2PDFWidthOO.all2pdf");
335             errortext = String.Empty;
336 
337             string l_sExtension = System.IO.Path.GetExtension(sourcefile);
338             l_oLog.WriteLn("- converting type file: " + l_sExtension);
339 
340             switch (l_sExtension.ToLower())
341             {
342                 case ".docx":
343                 case ".doc":
344                 case ".rtf":
345                 case ".odt":
346                 case ".sxw":
347                 case ".sdw":
348                 case ".vor":
349                 case ".html":
350                 case ".txt":
351                 case ".jpg":
352                 case ".tif":
353                 case ".bmp":
354                 case ".png":
355                 case ".gif":
356                 case ".xls":
357                 case ".ods":
358                 case ".ots":
359                 case ".sxc":
360                 case ".stc":
361                 case ".xlt":
362                 case ".odp"://  open office kresba
363                 case ".otp":
364                 case ".sxi":
365                 case ".sti":
366                 case ".ppt":
367                 case ".odg"://  open office prezentace
368                 case ".otg":
369                 case ".sxd":
370                 case ".std":
371                 case ".sda":
372 
373                     return file2pdf(sourcefile, ref destinationfile, out errortext);
374 
375                 default:
376                     errortext = "Daný typ souboru ke konverzi není podporován.";
377                     return false;
378             }
379         }
380 
381         private bool file2pdf(string sourcefilename, ref string destinationfile, out string errortext)
382         {
383             GDebug l_oLog = new GDebug(m_csOpenOffice);
384             l_oLog.WriteLn("- -----------------------------");
385             l_oLog.WriteLn("- GConverter2PDFWithOO.file2pdf");
386 
387             errortext = String.Empty;
388             
389             lock (this)
390             {
391                 try
392                 {
393                     StartOpenOffice(out errortext);
394 
395                     //Get a ComponentContext 
396                     unoidl.com.sun.star.uno.XComponentContext xLocalContext = uno.util.Bootstrap.bootstrap();
397                     //Get MultiServiceFactory 
398                     unoidl.com.sun.star.lang.XMultiServiceFactory xRemoteFactory = 
399 
400 (unoidl.com.sun.star.lang.XMultiServiceFactory)xLocalContext.getServiceManager();
401                     
402                     //Get a CompontLoader 
403                     XComponentLoader aLoader = (XComponentLoader)xRemoteFactory.createInstance
404 
405 ("com.sun.star.frame.Desktop");
406                     l_oLog.WriteLn("- init Loader. [OK]");
407 
408                     //Load the sourcefile
409                     XComponent xComponent = initDocument(aLoader, PathConverter(sourcefilename), "_blank");
410                     l_oLog.WriteLn("- init document. [OK]");
411 
412                     //Wait for loading 
413                     while (xComponent == null)
414                     {
415                         System.Threading.Thread.Sleep(500);
416                     }
417 
418                     destinationfile = System.IO.Path.GetDirectoryName(sourcefilename) + destinationfile + ".tmp";
419                     //sourcefilename
420 
421                     saveDocument(xComponent, PathConverter(destinationfile));
422                     //Wait for input 
423                     l_oLog.WriteLn("- conversation completed! [OK]");
424 
425                     // Close OpenOffice
426                     xComponent.dispose();
427                     xComponent = null;
428 
429                     XDesktop xDesk = (XDesktop)aLoader;
430                     xDesk.terminate();
431 
432                     GC.Collect();
433                     GC.WaitForPendingFinalizers();
434                     l_oLog.WriteLn("- application OO is closed. [OK]");
435                     
436                     return true;
437                 }
438 
439                 /*
440                 catch (unoidl.com.sun.star.uno.Exception exp)
441                 {
442                     throw exp;
443                 }
444                 */
445             
446                 catch (System.Exception exp)
447                 {
448                     l_oLog.WriteLn("- OpenOffice [FALSE] err: " + exp.Message);
449                     errortext = exp.Message;
450                     return false;
451                 }
452              
453             }// end lock
454         }
455 
456         /// <summary> 
457         /// Load a given file or create a new blank file 
458         /// </summary> 
459         /// <param name="aLoader">A ComponentLoader</param> 
460         /// <param name="file">The file</param> 
461         /// <param name="target">The target</param> 
462         /// <returns>Th Component</returns> 
463         private XComponent initDocument(XComponentLoader aLoader, string file, string target)
464         {
465             unoidl.com.sun.star.beans.PropertyValue[] Args = new unoidl.com.sun.star.beans.PropertyValue[1];
466             Args[0= new unoidl.com.sun.star.beans.PropertyValue();
467             Args[0].Name = "Hidden";
468             Args[0].Value.setValue(typeof(Boolean), true);
469 
470             XComponent xComponent = aLoader.loadComponentFromURL(file, target, 0, Args);
471             return xComponent;
472         }
473 
474         /// <summary> 
475         /// Convert into OO file format 
476         /// </summary> 
477         /// <param name="file">The file.</param> 
478         /// <returns>The converted file</returns> 
479         private string PathConverter(string file)
480         {
481             try
482             {
483                 GDebug l_oLog = new GDebug(m_csOpenOffice);
484                 l_oLog.WriteLn("- there is tmp file: " + file);
485                 file = file.Replace(@"\""/");
486 
487                 return "file:///" + file;
488             }
489             catch (System.Exception ex)
490             {
491                 throw ex;
492             }
493         }
494 
495         /// <summary> 
496         /// Saves the document. 
497         /// </summary> 
498         /// <param name="xComponent">The x component.</param> 
499         /// <param name="fileName">Name of the file.</param> 
500         private void saveDocument(XComponent xComponent, string fileName)
501         {
502             Thread l_oVlakno = null;
503             GDebug l_oLog = new GDebug(m_csOpenOffice);
504 
505             try
506             {
507                 unoidl.com.sun.star.beans.PropertyValue[] propertyValue = new unoidl.com.sun.star.beans.PropertyValue[1];
508 
509                 propertyValue[0= new unoidl.com.sun.star.beans.PropertyValue();
510                 propertyValue[0].Name = "FilterName";
511                 propertyValue[0].Value = new uno.Any("writer_pdf_Export");
512 
513 
514                 // timer zjistuje zda se neobjevi dialog s warovanim pri prevodu, pokud ano obsluha zajisti stisk 
515 
516 tlacitka OK
517                 l_oVlakno = new Thread(TimerForOpenOffice.RunTimer);
518                 l_oVlakno.Start();
519                 ((XStorable)xComponent).storeToURL(fileName, propertyValue);
520             }
521             catch (System.Exception exp)
522             {
523                 l_oLog.WriteLn(exp.Message);
524                 throw new System.Exception("Exception in saveDocument.");
525             }
526             finally
527             {
528                 TimerForOpenOffice.StopTimer();
529                 l_oVlakno.Abort();  // aby se vlakno dalo zastavit tak se musi zastavit v nem bezici timer
530             }
531         }
532     }
533 }
原文地址:https://www.cnblogs.com/wsxcy/p/1924021.html