Home > Programmieren > C# – Verzeichnis mit Office-Dokumenten in PDF konvertieren

C# – Verzeichnis mit Office-Dokumenten in PDF konvertieren

18. Februar 2010

Wie erstellt man für alle MS Office Dokumente in einem Verzeichnis eine Kopie als PDF? Diese Frage habe ich mir erst vor kurzer Zeit gestellt. Leider habe ich keine fertigen (kostenlosen) Programme gefunden, die diese Aufgabe erfüllen. Deshalb habe ich mir gedacht ich verwende einfach die Exportfunktion von MS Office 2007 selbst und automatisiere das Ganze mit .NET.

Ich stelle in diesem Artikel vor, wie man MS Office dazu über .NET ansteuert und biete für alle Tippfaulen analog dazu gleich ein fertiges Konsolenprogramm sammt Quelltext an.

Systemvoraussetzung

Auf dem Zielsystem folgende Software vorhanden sein:

  • Microsoft Office 2007
  • Microsoft Office 2007 Interop Assemblies 1
  • Microsoft Office 2007 PDF Export-Funktion 2
  • .NET Framework 3
Microsoft 2007 Interop Assemblies

Installation der Microsoft 2007 Interop Assemblies

Die Exportfunktion für PDF-Dateien sollte bereits Bestandteil der Installation von Microsoft Office 2007 sein. Die Interop Assemblies sind ebenfalls Bestandteil des Pakets und können bei der Installation für jedes Office-Programm extra ausgewählt werden.

Als Entwicklungsumgebung wurde Visual Studio 2008 und das .NET-Framework 3.5 SP1 verwendet. Die kostenlose Express-Version4 ist dafür völlig ausreichend.

Hinweis: In diesem Artikel wird zwar C# verwendet, aber im Grunde eignet sich dazu auch jede andere .NET-Sprache. Da die selben Schnittstellen auch über COM+ angeboten werden, können die MS Office Programme auch zB über VBS,.. angesteuert werden.

Das Konsolenprogramm

Das Programm soll der Einfachheit halber auf der Konsole ausgeführt werden und folgende Parameter unterstützen:

Office2PDF [-r] [-o] [-v] Pfad

Wobei der optionale Parameter -r dafür sorgt, dass nicht nur das angegebene Verzeichnis, sondern auch alle Unterverzeichnisse nach Office-Dokumenten durchsucht werden. Der Parameter -v soll dafür Sorgen, dass die Office-Programme nicht unsichtbar sind, sondern während der Bearbeitung angezeigt werden. -o soll zusätzlich festlegen, dass bereits existierende PDF-Dateien überschrieben werden sollen.

Es wären auch noch weitere Parameter denkbar, wie zB. ein Parameter, der unterdrückt, dass alle Office-Dateien gleich wieder geschlossen werden. Auch der Export in andere Dokumentformate wie ODF oder XPS wäre ohne Weiteres möglich. Das Programm soll aber vorerst nicht zu sehr mit Funktionen überladen.

Ob ein Parameter gesetzt ist lässt sich sehr leicht mit dieser Methode über LINQ abprüfen:

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.Linq;
using System.IO;
//...
  static int Main(string[] args) {
    //...
    //Checks if Parameter x is set
    Func<string [], string, bool> ParamIsSet = delegate(string[] arr, string param) {
      bool result;
      if (!(result = args.Contains(param, StringComparer.CurrentCultureIgnoreCase)))
      Console.WriteLine("Parameter {0} not found!", param);
      return result;
    }
    //...
    // If (ParamIsSet(args, "-r")) ...
    //...
    return 0;
  }
</string>

In der fertigen Implementierung für das Konsolenprogramm wurde allerdings auf diesen Code verzichtet, da dieser schwerer zu lesen ist und sich die Parameter auch über eine gewöhnliche Schleife ohne LINQ überprüfen lassen. Außerdem wird die Abhängigkeit zu LINQ gelöst und der Code liese sich so auch unter .NET 2.0 noch kompilieren.

Das fertige Listing inklusive der Suche nach MS Office Dateien sieht dementsprechend wie folgt aus:

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.Linq;
using System.IO;
namespace Office2PDF
{
  public class Program
  {
    static int Main(string[] args)
    {
      const StringComparison scmp = StringComparison.CurrentCultureIgnoreCase;
      SearchOption depth = SearchOption.TopDirectoryOnly;
      bool showApps = false;
      bool error = args.Length < 2;
      bool overwriteFiles = false;
      int i = 0;
 
      //Check optional Parameters
      for (; !error && i < args.Length - 1; i++)
      {
        //Recursive
        if (/*!error &&*/ args[i].Equals("-r", scmp))
        {
          depth = SearchOption.AllDirectories;
          continue;
        }
        //Overwrite existing Files
        if (/*!error &&*/ args[i].Equals("-o", scmp))
        {
          overwriteFiles = true;
          continue;
        }
        //Show Apps
        if (/*!error &&*/ args[i].Equals("-v", scmp))
        {
          showApps = true;
          continue;
        }
 
        //...
 
        //Unknown Parameter
        error = true;
        Console.WriteLine("Parameter {0} is unkown.", args[i]);
      }
      //Check if Path exists
      error = error || !Directory.Exists(args[i]);
      //Execute
      if (!error) ProcessFolder(args[i], depth, showApps, overwriteFiles);
      return error ? -1 : 0;
    }
 
    public static void ProcessFolder(string path, SearchOption depth, bool showApps, bool overwriteFiles)
    {
      ExcelInstance excelApp = new ExcelInstance(showApps);
      string[] excelExts = { ".xls", ".xlsx" };
      WordInstance wordApp = new WordInstance(showApps);
      string[] wordExts = { ".doc", ".docx" };
      VisioInstance visioApp = new VisioInstance(showApps);
      string[] visioExts = { ".vsd", ".dwg", ".svg" };
      PowerPointInstance ppApp = new PowerPointInstance(showApps);
      string[] ppExts = { ".ppt", ".pptx" };
      PublisherInstance publisherApp = new PublisherInstance(showApps);
      string[] publisherExts = { ".pub" };
 
      foreach (string file in Directory.GetFiles(path, "*", depth))
      {
        try
        {
          Console.Write(file + "...");
          //Is Excel-File?
          foreach (string ext in excelExts)
            if (file.EndsWith(ext)) excelApp.ConvertFile(file, file + ".pdf", overwriteFiles);
          //Is Word-File?
          foreach (string ext in wordExts)
            if (file.EndsWith(ext)) wordApp.ConvertFile(file, file + ".pdf", overwriteFiles);
          //Is Visio-File?
          foreach (string ext in visioExts)
            if (file.EndsWith(ext)) visioApp.ConvertFile(file, file + ".pdf", overwriteFiles);
          //PowerPoint
          foreach (string ext in ppExts)
            if (file.EndsWith(ext)) ppApp.ConvertFile(file, file + ".pdf", overwriteFiles);
          //Publisher
          foreach (string ext in publisherExts)
            if (file.EndsWith(ext)) publisherApp.ConvertFile(file, file + ".pdf", overwriteFiles);
          Console.WriteLine("done");
        }
        catch (Exception e)
        {
          Console.WriteLine(e.Message);
        }
      } //foreach
 
      excelApp.Close();
      wordApp.Close();
      visioApp.Close();
      ppApp.Close();
      publisherApp.Close();
    }
  } //class
} //ns

Die Main()-Methode wertet hierzu die Parameter aus. Falls kein Fehler aufgetreten ist und das übergebende Verzeichnis existiert, wird die ProcessFolder()-Methode aufgerufen. Diese ermittelt alle Dateien innerhalb des Verzeichnisses und ggf. der Unterverzeichnisse, über die Methode System.IO.Directory.GetFiles(). Diese Dateiliste wird dann durchlaufen und die von MS Office unterstützen Dateiformate werden herausgepickt und den entsprechenden Instanzen der MS Office Programme zur Konvertierung übergeben.

Die Klassen WordInstance, ExcelInstance,… sollen hierbei einfach eine Instanz der jeweiligen MS Office Anwendung kapseln. In dieser Implementierung leiten sich beide Klassen zusätzlich von dieser abstrakten Basisklasse ab:

using System;
namespace Office2PDF
{
  public abstract class OfficeInstance
  {
    protected object _noParam = Type.Missing;
    abstract public void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles);
    abstract public void Close();
  }
}

Hinweis: MS Office Anwendungen erwarten bei vielen Methoden unzählige Parameter, viele davon sind optional. C# unterstützt allerdings erst in der kommenden Version 4.0 optionale bzw. benannte Parameter. Für die ausgelassenen Parameter muss hier die Konstante System.Type.Missing als object übergeben werden damit jeweils der Default-Wert verwendet wird. Da oft auch Referenzen erwartet werden, wurde die geschützte Variable _noParam als globaler Platzhalter verwendet.

Visual Basic.NET unterstützt dagegen schon lange optionale Parameter. Ein Umweg über diese Konstante ist hier nicht notwendig und die Aufrufe sind entsprechend kürzer.

Da fast sämtliche MS Office Programme eine uneinheitliche und inkompatible Schnittstelle bereitstellen ist die abstrakte Klasse, die die Gemeinsamkeiten bündeln soll, entsprechend kurz ausgefallen. Hier hätte Microsoft bei der Umstellung auf Office 2007 eindeutig einiges gegen über dem alten Office 2003-Modell verbessern können. Bei der Entwicklung dieser Schnittstelle fand offenbar keinerlei Koordination/Planung durch die Teams statt. Viele Klassen weisen Namensunterschiede auf und die meisten Methoden erwarten bei jedem Programm fast die selben Parameter, aber in anderer Reihenfolge. Auch werden die selben Parameter ohne erkennbare Logik einmal Call-By-Value und andermal über Call-By-Reference erwartet. Von gemeinsamen Basisklassen für die Kompatibilität ganz zu schweigen.

Einrichten der Referenzen

MS Office Interop References

Benötigte MS Office Interop Assemblies

Die Referenzen zu den entsprechenden Interop Assemblies sind schnell über den Solution Explorer in Visual Studio 2008 eingerichtet. Dazu reicht ein Rechtsklick auf den Eintrag References und die Wahl des Menüpunktes Add References. Im darauf erscheinenden Dialog lassen sich die entsprechenden .NET-Assemblies auswählen. Zu jeder MS Office-Anwendung existiert hierbei eine entsprechende Komponente mit dem Namen Microsoft.Office.Interop.*. Zusätzlich wird für einige Programme wie zB. PowerPoint das Assembly mit dem Namen Office benötigt, welches einige Kernkomponenten und Datentypen wie zB MsoTriState enthält.

Natürlich muss für die Ansteuerung des Programms auch die Anwendung selbst auf dem System vorhanden sein. Die Referenz alleine dient nur als Schnittstelle und ist selbst nicht ausreichend. Sollte eines der hier in diesem Artikel beschriebenen Programme nicht installiert sein, sollte der entsprechende Code auskommentiert, oder eine Überpüfung auf vorhandene Programme eingebaut werden.

Word 2007

Die zuvor erwähnte Klasse WordInstance soll eine Instanz von Word kapseln. In dieser Implementierung erfolgt die Instanzierung direkt beim Aufruf des Konstruktors. Alternativ wäre eine zusätzliche Methode Start() denkbar. Beim Schließen von Word sollte außerdem darauf geachtet werden, dass danach auf den Garbage Collector gewartet werden sollte um sicher zu gehen, dass Word aus dem Speicher entladen wurde. (Immerhin wird auch als unsafe definierter Code ausgeführt.)

Die Implementierung zu dieser Klasse enthält dabei folgenden Code:

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.IO;
using Word = Microsoft.Office.Interop.Word;
 
namespace Office2PDF
{
  public class WordInstance : OfficeInstance
  {
    private Word._Application _instance;
 
    public WordInstance(bool visible)
    {
      _instance = new Word.ApplicationClass();
      if (_instance == null) throw new Exception("Couldn't create an Word Instance.");
      _instance.Visible = visible;
    }
 
    public override void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles)
    {
      if (!overwriteFiles && File.Exists(targetFile)) throw new Exception("PDF-File already exists");
      object sourceFileObj = sourceFile;
      Word._Document doc = null;
 
      try
      {
        //Open File
        doc = _instance.Documents.Open(
          ref sourceFileObj, ref _noParam, ref _noParam, ref _noParam, ref _noParam, ref _noParam,
          ref _noParam, ref _noParam, ref _noParam, ref _noParam, ref _noParam, ref _noParam,
          ref _noParam, ref _noParam, ref _noParam, ref _noParam
          );
        doc.Activate();
 
        //Convert File to PDF
        doc.ExportAsFixedFormat(
          targetFile, Word.WdExportFormat.wdExportFormatPDF, false, Word.WdExportOptimizeFor.wdExportOptimizeForPrint,
          Word.WdExportRange.wdExportAllDocument, 0, 0, Word.WdExportItem.wdExportDocumentContent, true, false,
          Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks, true, true, false, ref _noParam
          );
      }
      finally
      {
        //Close File
        if (doc != null) doc.Close(ref _noParam, ref _noParam, ref _noParam);
      }
    }
 
    public override void Close()
    {
      //Quit Word
      _instance.Quit(ref _noParam, ref _noParam, ref _noParam);
      _instance = null;
      //Wait for Garbage Collector
      GC.Collect();
      GC.WaitForPendingFinalizers();
    }
  } //class
} //ns

Die Methode ConvertFile()

Wie man bei der Implementierung der Methode ConvertFile() erkennen kann, wird über die Variable _instance auf Word und damit auf alle geöffneten Dokumente über Documents zugegriffen. Documents erlaubt außerdem das Öffnen von weiteren Dokumenten über dessen Methode Open(). Diese gibt gleichzeitig ein Objekt vom Typ Document zurück, über die auf das geöffnete Dokument direkt zugegriffen werden kann. Sie besitzt wiederum eine Methode mit dem Namen ExportAsFixedFormat, welche den Export als PDF- bzw. XPS-Datei erlaubt.

ConvertFile() führt also zusammengefasst folgende Schritte durch:

  1. Öffnen des originalen Word-Dokuments.
  2. Erstellung einer Kopie als PDF-Datei in das selbe Verzeichnis mit dem selben Dateinamen.
  3. Schließen des Dokuments.
Application Klasse

Hinweis:Für die MS Office Anwendungen existieren jeweils mehrere Klassen und Schnittstellen. Als Datentyp für eine Instanz eignet sich das Interface _Application am Besten, während die Klasse Application als konkreter Datentyp verwendet werden sollte. Grund dafür ist zB der Umstand, dass sowohl die Klasse als auch das Interface Application für ein paar Methoden keine eindeutige Referenz bieten. Der C#-Compiler gibt bei Ihrer Verwendung aber eine entsprechende Warnung aus.

Excel 2007

Die Klasse ExcelInstance soll analog zu der bereits oben vorgestellten Klasse für Word 2007 erstellt werden. Das Vorgehen ist hier im Grunde gleich, allerdings gibt es ein paar Unterschiede gegenüber Word:

  • Dateien werden in Workbooks anstatt in Dokumente verwaltet.
  • Die Parameter der zuvor verwendeten Methoden sind meist gleich, aber in anderer Reihenfolge.
  • Parameter sind meist Call-By-Value anstatt Call-By-Reference wie bei Word.
  • Für den PDF-Export stehen weniger Einstellungsmöglichkeiten zur Verfügung.

Die Implementierung enthält dabei folgenden Code:

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
 
namespace Office2PDF
{
  public class ExcelInstance : OfficeInstance
  {
    private Excel._Application _instance;
 
    public ExcelInstance(bool visible)
    {
      _instance = new Excel.ApplicationClass();
      if (_instance == null) throw new Exception("Couldn't create an Excel Instance.");
      _instance.Visible = visible;
    }
 
    public override void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles)
    {
      if (!overwriteFiles && File.Exists(targetFile)) throw new Exception("PDF-File already exists");
      Excel._Workbook wb = null;
      try
      {
        //Open File
        wb = _instance.Workbooks.Open(
          sourceFile, 3, true, _noParam, _noParam, _noParam, true, _noParam, _noParam,
          _noParam, false, _noParam, _noParam, _noParam, _noParam
          );
        wb.Activate();
        //Convert File to PDF
        wb.ExportAsFixedFormat(
          Excel.XlFixedFormatType.xlTypePDF, targetFile, Excel.XlFixedFormatQuality.xlQualityStandard,
          true, true, _noParam, _noParam, false, _noParam
          );
      }
      finally
      {
        //Close File
        if (wb != null) wb.Close(_noParam, _noParam, _noParam);
      }
    }
 
    public override void Close()
    {
      //Quit Excel
      _instance.Quit();
      _instance = null;
      //Wait for Garbage Collector
      GC.Collect();
      GC.WaitForPendingFinalizers();
    }
  } //class
} //ns

PowerPoint 2007

PowerPoint unterscheidet sich gegenüber Word und Excel stark von den verlangten Parametern. Des Weiteren gibt es bei diesem Programm in der Klasse Application zwar auch die Eigenschaft Visible>, diese darf allerdings nicht verwendet werden, da das Verstecken des Hauptfensters bei PowerPoint nicht erlaubt ist. Das Hauptmenü wird deshalb einfach minimiert.

Eine weitere Stolperfalle hat Microsoft beim Laden von Dateien eingebaut. Anders als bei den anderen Anwendungen muss erst die Methode Activate() von PowerPoint aufgerufen werden, bevor eine Datei geladen wird. Andernfalls stürzt das Programm mit einer Fehlermeldung ab.

Zusätzlich muss beachtet werden, dass der letzte Parameter der Konvertierungsfunktion bei PowePoint für C# nicht den Typ System.Type.Missing sondern System.Reflection.Missing.Value erwartet.

Die Implementierung lautet deshalb wie folgt:

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.IO;
using System.Reflection;
using Microsoft.Office.Core;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
 
namespace Office2PDF
{
  public class PowerPointInstance : OfficeInstance
  {
    private PowerPoint._Application _instance;
    MsoTriState _showApp;
 
    public PowerPointInstance(bool visible)
    {
      _instance = new PowerPoint.ApplicationClass();
      if (_instance == null) throw new Exception("Couldn't create an PowerPoint Instance.");
 
      _instance.Activate(); //Important: PowerPoint needs to be acitvated, before loading Files!
 
      //Hidding the Window with Member "Visible" is not allowed!
      _showApp = visible ? MsoTriState.msoTrue : MsoTriState.msoFalse;
      if (!visible) _instance.WindowState = PowerPoint.PpWindowState.ppWindowMinimized;      
    }
 
    public override void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles)
    {
      if (!overwriteFiles && File.Exists(targetFile)) throw new Exception("PDF-File already exists");
      object sourceFileObj = sourceFile;
      PowerPoint._Presentation presentation = null;
 
      try
      {
        //Open File
        presentation = _instance.Presentations.Open(sourceFile, MsoTriState.msoFalse, MsoTriState.msoTrue, _showApp);
        if (_showApp == MsoTriState.msoTrue) _instance.Activate();
        //Convert File to PDF
        presentation.ExportAsFixedFormat(
          targetFile, PowerPoint.PpFixedFormatType.ppFixedFormatTypePDF, PowerPoint.PpFixedFormatIntent.ppFixedFormatIntentPrint,
          MsoTriState.msoFalse, PowerPoint.PpPrintHandoutOrder.ppPrintHandoutVerticalFirst,
          PowerPoint.PpPrintOutputType.ppPrintOutputOneSlideHandouts, MsoTriState.msoFalse, null,
          PowerPoint.PpPrintRangeType.ppPrintAll, null, true, true, true, true, false, Missing.Value
          );
      }
      finally
      {
        //Close File
        if (presentation != null) presentation.Close();
      }
    }
 
    public override void Close()
    {
      //Quit Word
      _instance.Quit();
      _instance = null;
      //Wait for Garbage Collector
      GC.Collect();
      GC.WaitForPendingFinalizers();
    }
  } //class
} //ns

Publisher 2007

Der Publisher unterstütztd as Ausblenden selbst, gar nicht. Das Fenster wird allerdings, anders als die anderen Programme unsichtbar geladen. Ansonsten noch zu beachten, dass die Konvertierungsfunktion einige Integer-Werte für die Farbekonvertierung erwartet. Hier ist es besser jeweils den Standardwert zu verwenden. Dieser ist allerdings anders als bei den anderen Anwendungen -1 anstatt 0. (Die MSDN selbst dokumentiert diese Werte leider gar nicht, sondern geht von der Verwendung von Visual Basic bzw. VBA aus.)

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.IO;
using Publisher = Microsoft.Office.Interop.Publisher;
 
namespace Office2PDF
{
  public class PublisherInstance : OfficeInstance
  {
    private Publisher._Application _instance;
 
    public PublisherInstance(bool visible)
    {
      _instance = new Publisher.ApplicationClass();
      if (_instance == null) throw new Exception("Couldn't create an Publisher Instance.");
    }
 
    public override void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles)
    {
      if (!overwriteFiles && File.Exists(targetFile)) throw new Exception("PDF-File already exists");
      Publisher._Document pub = null;
      try
      {
        //Open File
        pub = _instance.Open(sourceFile, true, false, Publisher.PbSaveOptions.pbDoNotSaveChanges);
        //Convert File to PDF
        pub.ExportAsFixedFormat(
          Publisher.PbFixedFormatType.pbFixedFormatTypePDF, targetFile, Publisher.PbFixedFormatIntent.pbIntentPrinting,
          true, -1, -1, -1, -1, -1, -1, 1, true, Publisher.PbPrintStyle.pbPrintStyleDefault,
          true, true, false, _noParam
          );
      }
      finally
      {
        //Close File
        if (pub != null) pub.Close();
      }
    }
 
    public override void Close()
    {
      //Quit Word
      _instance.Quit();
      _instance = null;
      //Wait for Garbage Collector
      GC.Collect();
      GC.WaitForPendingFinalizers();
    }
  } //class
} //ns

Visio 2007

Ähnlich wie bei PowerPoint darf bei Visio das Hauptfenster nicht versteckt werden. Anders als bei PowerPoint stürtzt das Programm allerdings nicht beim Versuch das Fenster zu verstecken ab, ignoriert die Anweisung jedoch. Deshalb wird es im folgenden Code genau wie PowePoint einfach minimiert dargestellt.

/*This Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. 
<http ://www.gnu.org/licenses/>.*/
using System;
using System.IO;
using Visio = Microsoft.Office.Interop.Visio;
 
namespace Office2PDF
{
  public class VisioInstance : OfficeInstance
  {
    private Visio.Application _instance;
    private bool _showApp;
 
    public VisioInstance(bool visible)
    {
      _instance = new Visio.ApplicationClass();
      if (_instance == null) throw new Exception("Couldn't create an Visio Instance.");
 
      //Hidding the Window is not allowed!
      _instance.Visible = _showApp = visible;
      if (!_showApp) _instance.Window.WindowState = (int)Visio.VisWindowStates.visWSMinimized;
    }
 
    public override void ConvertFile(string sourceFile, string targetFile, bool overwriteFiles)
    {
      if (!overwriteFiles && File.Exists(targetFile)) throw new Exception("PDF-File already exists");
      Visio.Document doc = null;
      try
      {
        //Open File
        doc = _instance.Documents.Open(sourceFile);
        if (_showApp) _instance.Window.Activate();
        //Convert File to PDF
        doc.ExportAsFixedFormat(
          Visio.VisFixedFormatTypes.visFixedFormatPDF, targetFile, Visio.VisDocExIntent.visDocExIntentPrint,
          Visio.VisPrintOutRange.visPrintAll, 0, 0, false, true, true, true, true, _noParam
          );
      }
      finally
      {
        //Close File
        if (doc != null) doc.Close();
      }
    }
 
    public override void Close()
    {
      //Quit Visio
      _instance.Quit();
      _instance = null;
      //Wait for Garbage Collector
      GC.Collect();
      GC.WaitForPendingFinalizers();
    }
  } //class
} //ns

Der fertige Prototyp für Word, Excel, PowerPoint, Visio und den Publisher

Der hier gelistete Quellcode kann auch als vollständiges Visual Studio Projekt und bereits ausführbares Programm heruntergeladen werden. 5

Der Quelltext soll nur eine mögliche Implementierung als Konsolenprogramm aufzeigen. Der Prototyp enthält noch keine Identifizierung ob die genannten Programme überhaupt auf dem System installiert sind, sondern versucht diese blind auszuführen.

  1. Bisher keine Kommentare
Kommentare sind geschlossen