Ändern der Druckausrichtung von einem Textverarbeitungsdokument
In diesem Thema wird gezeigt, wie Sie die Klassen im Open XML SDK für Office verwenden, um die Druckausrichtung eines Microsoft Word 2010- oder Microsoft Word 2013 Dokuments programmgesteuert festzulegen. Sie enthält ein Beispiel für eine SetPrintOrientation-Methode , um diese Aufgabe zu veranschaulichen.
SetPrintOrientation-Methode
Sie können die SetPrintOrientation-Methode verwenden, um die Druckausrichtung eines Textverarbeitungsdokuments zu ändern. Die -Methode akzeptiert zwei Parameter, die den Namen des zu ändernden Dokuments (Zeichenfolge) und die neue Druckausrichtung (PageOrientationValues) angeben.
Der folgende Code zeigt die SetPrintOrientation-Methode .
public static void SetPrintOrientation(
string fileName, PageOrientationValues newOrientation)
Wenn sich die neue Ausrichtung für jeden Abschnitt im Dokument von der aktuellen Druckausrichtung des Abschnitts unterscheidet, ändert der Code die Druckausrichtung für den Abschnitt. Darüber hinaus muss der Code die Breite, Höhe und Ränder für jeden Abschnitt manuell aktualisieren.
Aufrufen der SetPrintOrientation-Beispielmethode
Um die SetPrintOrientation-Beispielmethode aufzurufen, übergeben Sie eine Zeichenfolge, die den Namen der zu konvertierenden Datei enthält. Der folgende Code zeigt ein Beispiel für einen Methodenaufruf.
SetPrintOrientation(@"C:\Users\Public\Documents\ChangePrintOrientation.docx",
PageOrientationValues.Landscape);
Funktionsweise des Codes
Der folgende Code öffnet zunächst das Dokument mithilfe der Open-Methode und legt den isEditable-Parameter auf true fest, um anzugeben, dass das Dokument lese-/schreibfähig sein soll. Der Code verwaltet eine boolesche Variable, die nachverfolgt, ob das Dokument geändert wurde (sodass es das Dokument später speichern kann, wenn das Dokument geändert wurde). Der Code ruft einen Verweis auf den Standard Dokumentteil ab und verwendet dann diesen Verweis, um eine Auflistung aller Nachfolger vom Typ SectionProperties innerhalb des Inhalts des Dokuments abzurufen. Im späteren Code wird diese Auflistung verwendet, um die Ausrichtung für jeden Abschnitt nacheinander festzulegen.
using (var document =
WordprocessingDocument.Open(fileName, true))
{
bool documentChanged = false;
var docPart = document.MainDocumentPart;
var sections = docPart.Document.Descendants<SectionProperties>();
// Code removed here...
}
Durchlaufen aller Abschnitte
Der nächste Codeblock durchläuft alle Abschnitte in der Auflistung der SectionProperties-Elemente . Für jeden Abschnitt initialisiert der Code eine Variable, die nachverfolgt, ob die Seitenausrichtung für den Abschnitt geändert wurde, damit der Code die Seitengröße und die Seitenränder aktualisieren kann. (Wenn die neue Ausrichtung mit der ursprünglichen Ausrichtung übereinstimmt, aktualisiert der Code die Seite nicht.) Der Code ruft einen Verweis auf den ersten PageSize-Nachfolger des SectionProperties-Elements ab. Wenn der Verweis nicht NULL ist, aktualisiert der Code die Ausrichtung nach Bedarf.
foreach (SectionProperties sectPr in sections)
{
bool pageOrientationChanged = false;
PageSize pgSz = sectPr.Descendants<PageSize>().FirstOrDefault();
if (pgSz != null)
{
// Code removed here...
}
}
Festlegen der Ausrichtung für den Abschnitt
Der nächste Codeblock überprüft zunächst, ob die Orient-Eigenschaft des PageSize-Elements vorhanden ist. Wie bei vielen Eigenschaften von Open XML-Elementen ist die Eigenschaft oder das Attribut möglicherweise noch nicht vorhanden. In diesem Fall wird beim Abrufen der -Eigenschaft ein NULL-Verweis zurückgegeben. Wenn die Eigenschaft nicht vorhanden ist und die neue Ausrichtung hochformatiert ist, wird die Seite vom Code standardmäßig nicht aktualisiert. Wenn die Orient-Eigenschaft bereits vorhanden ist und ihr Wert sich von dem neuen Ausrichtungswert unterscheidet, der als Parameter für die Methode bereitgestellt wird, legt der Code die Value-Eigenschaft der Orient-Eigenschaft fest und legt sowohl die flags pageOrientationChanged als auch die documentChanged-Flags fest. (Der Code verwendet das pageOrientationChanged-Flag , um zu bestimmen, ob die Seitengröße und die Seitenränder aktualisiert werden müssen. Es verwendet das documentChanged-Flag , um zu bestimmen, ob das Dokument am Ende gespeichert werden muss.)
Hinweis
Wenn der Code die Orient-Eigenschaft erstellen muss, muss er auch den Wert erstellen, der in der Eigenschaft als neuer EnumValue<T-instance> gespeichert werden soll, wobei die neue Ausrichtung im EnumValue-Konstruktor bereitgestellt wird.
if (pgSz.Orient == null)
{
if (newOrientation != PageOrientationValues.Portrait)
{
pageOrientationChanged = true;
documentChanged = true;
pgSz.Orient =
new EnumValue<PageOrientationValues>(newOrientation);
}
}
else
{
if (pgSz.Orient.Value != newOrientation)
{
pgSz.Orient.Value = newOrientation;
pageOrientationChanged = true;
documentChanged = true;
}
}
Aktualisieren der Seitengröße
An diesem Punkt im Code kann sich die Seitenausrichtung geändert haben. Wenn ja, muss der Code zwei weitere Aufgaben ausführen. Es muss die Seitengröße und die Seitenränder für den Abschnitt aktualisiert werden. Die erste Aufgabe ist einfach– der folgende Code tauscht lediglich die Seitenhöhe und -breite aus, wobei die Werte im PageSize-Element gespeichert werden.
if (pageOrientationChanged)
{
// Changing the orientation is not enough. You must also
// change the page size.
var width = pgSz.Width;
var height = pgSz.Height;
pgSz.Width = height;
pgSz.Height = width;
// Code removed here...
}
Aktualisieren der Ränder
Im nächsten Schritt der Beispielprozedur werden Ränder für den Abschnitt behandelt. Wenn sich die Seitenausrichtung geändert hat, muss der Code die Ränder entsprechend drehen. Dazu ruft der Code einen Verweis auf das PageMargin-Element für den Abschnitt ab. Wenn das Element vorhanden ist, rotiert der Code die Ränder. Beachten Sie, dass der Code die Ränder um 90 Grad dreht– einige Drucker drehen die Ränder stattdessen um 270 Grad, und Sie können den Code ändern, um dies zu berücksichtigen. Beachten Sie außerdem, dass die Eigenschaften Top und Bottom des PageMargin-Objekts signierte Werte und die Eigenschaften Left und Right werte ohne Vorzeichen sind. Der Code muss zwischen den beiden Typen von Werten konvertiert werden, während er die Randeinstellungen rotiert, wie im folgenden Code gezeigt.
PageMargin pgMar =
sectPr.Descendants<PageMargin>().FirstOrDefault();
if (pgMar != null)
{
var top = pgMar.Top.Value;
var bottom = pgMar.Bottom.Value;
var left = pgMar.Left.Value;
var right = pgMar.Right.Value;
pgMar.Top = new Int32Value((int)left);
pgMar.Bottom = new Int32Value((int)right);
pgMar.Left =
new UInt32Value((uint)System.Math.Max(0, bottom));
pgMar.Right =
new UInt32Value((uint)System.Math.Max(0, top));
}
Speichern des Dokuments
Nach allen Änderungen bestimmt der Code, ob sich das Dokument geändert hat. Wenn das Dokument geändert wurde, wird es vom Code gespeichert.
if (documentChanged)
{
docPart.Document.Save();
}
Beispielcode
Im Folgenden finden Sie das vollständige SetPrintOrientation-Codebeispiel in C# und Visual Basic.
#nullable enable
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Linq;
SetPrintOrientation(args[0], args[1]);
// Given a document name, set the print orientation for
// all the sections of the document.
static void SetPrintOrientation(string fileName, string no)
{
PageOrientationValues newOrientation = no.ToLower() switch
{
"landscape" => PageOrientationValues.Landscape,
"portrait" => PageOrientationValues.Portrait,
_ => throw new System.ArgumentException("Invalid argument: " + no)
};
using (var document =
WordprocessingDocument.Open(fileName, true))
{
bool documentChanged = false;
if (document.MainDocumentPart is null)
{
throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
}
var docPart = document.MainDocumentPart;
var sections = docPart.Document.Descendants<SectionProperties>();
foreach (SectionProperties sectPr in sections)
{
bool pageOrientationChanged = false;
PageSize pgSz = sectPr.Descendants<PageSize>().First();
// No Orient property? Create it now. Otherwise, just
// set its value. Assume that the default orientation
// is Portrait.
if (pgSz.Orient is null)
{
// Need to create the attribute. You do not need to
// create the Orient property if the property does not
// already exist, and you are setting it to Portrait.
// That is the default value.
if (newOrientation != PageOrientationValues.Portrait)
{
pageOrientationChanged = true;
documentChanged = true;
pgSz.Orient =
new EnumValue<PageOrientationValues>(newOrientation);
}
}
else
{
// The Orient property exists, but its value
// is different than the new value.
if (pgSz.Orient.Value != newOrientation)
{
pgSz.Orient.Value = newOrientation;
pageOrientationChanged = true;
documentChanged = true;
}
if (pageOrientationChanged)
{
// Changing the orientation is not enough. You must also
// change the page size.
var width = pgSz.Width;
var height = pgSz.Height;
pgSz.Width = height;
pgSz.Height = width;
PageMargin pgMar = (sectPr.Descendants<PageMargin>().FirstOrDefault()) ?? throw new ArgumentNullException("There are no PageMargin elements in the section.");
if (pgMar is not null)
{
// Rotate margins. Printer settings control how far you
// rotate when switching to landscape mode. Not having those
// settings, this code rotates 90 degrees. You could easily
// modify this behavior, or make it a parameter for the
// procedure.
if (pgMar.Top is null || pgMar.Bottom is null || pgMar.Left is null || pgMar.Right is null)
{
throw new ArgumentNullException("One or more of the PageMargin elements is null.");
}
var top = pgMar.Top.Value;
var bottom = pgMar.Bottom.Value;
var left = pgMar.Left.Value;
var right = pgMar.Right.Value;
pgMar.Top = new Int32Value((int)left);
pgMar.Bottom = new Int32Value((int)right);
pgMar.Left =
new UInt32Value((uint)System.Math.Max(0, bottom));
pgMar.Right =
new UInt32Value((uint)System.Math.Max(0, top));
}
}
}
}
if (documentChanged)
{
docPart.Document.Save();
}
}
}