Partager via


Modifier l’orientation d’impression d’un document de traitement de texte

Cette rubrique montre comment utiliser les classes du Kit de développement logiciel (SDK) Open XML pour Office afin de définir par programmation l’orientation d’impression d’un document Microsoft Word 2010 ou Microsoft Word 2013. Il contient un exemple de méthode SetPrintOrientation pour illustrer cette tâche.


SetPrintOrientation, méthode

Vous pouvez utiliser la méthode SetPrintOrientation pour modifier l’orientation d’impression d’un document de traitement de texte. La méthode accepte deux paramètres qui indiquent le nom du document à modifier (chaîne) et la nouvelle orientation d’impression (PageOrientationValues).

Le code suivant montre la méthode SetPrintOrientation .

    public static void SetPrintOrientation(
      string fileName, PageOrientationValues newOrientation)

Pour chaque section du document, si la nouvelle orientation diffère de l’orientation d’impression actuelle de la section, le code modifie l’orientation d’impression de la section. En outre, le code doit mettre à jour manuellement la largeur, la hauteur et les marges de chaque section.


Appel de l’exemple de méthode SetPrintOrientation

Pour appeler l’exemple de méthode SetPrintOrientation , transmettez une chaîne qui contient le nom du fichier à convertir. Le code suivant montre un exemple d’appel de méthode.

    SetPrintOrientation(@"C:\Users\Public\Documents\ChangePrintOrientation.docx", 
        PageOrientationValues.Landscape);

Fonctionnement du code

Le code suivant ouvre d’abord le document à l’aide de la méthode Open et définit le paramètre isEditable sur true pour indiquer que le document doit être en lecture/écriture. Le code conserve une variable booléenne qui détermine si le document a changé (afin qu’il puisse enregistrer le document ultérieurement, si le document a changé). Le code récupère une référence au composant de document main, puis utilise cette référence pour récupérer une collection de tous les descendants de type SectionProperties dans le contenu du document. Le code ultérieur utilisera cette collection pour définir l’orientation de chaque section tour à tour.

    using (var document = 
        WordprocessingDocument.Open(fileName, true))
    {
        bool documentChanged = false;

        var docPart = document.MainDocumentPart;
        var sections = docPart.Document.Descendants<SectionProperties>();
        // Code removed here...
    }

Itération dans toutes les sections

Le bloc de code suivant itère toutes les sections de la collection d’éléments SectionProperties . Pour chaque section, le code initialise une variable qui détermine si l’orientation de la page de la section a été modifiée afin que le code puisse mettre à jour la taille et les marges de la page. (Si la nouvelle orientation correspond à l’orientation d’origine, le code ne met pas à jour la page.) Le code continue en récupérant une référence au premier descendant PageSize de l’élément SectionProperties . Si la référence n’est pas null, le code met à jour l’orientation en fonction des besoins.

    foreach (SectionProperties sectPr in sections)
    {
        bool pageOrientationChanged = false;

        PageSize pgSz = sectPr.Descendants<PageSize>().FirstOrDefault();
        if (pgSz != null)
        {
            // Code removed here...
        }
    }

Définition de l’orientation pour la section

Le bloc de code suivant vérifie d’abord si la propriété Orient de l’élément PageSize existe. Comme pour de nombreuses propriétés d’éléments Open XML, la propriété ou l’attribut n’existe peut-être pas encore. Dans ce cas, la récupération de la propriété retourne une référence null. Par défaut, si la propriété n’existe pas et que la nouvelle orientation est Portrait, le code ne met pas à jour la page. Si la propriété Orient existe déjà et que sa valeur diffère de la nouvelle valeur d’orientation fournie en tant que paramètre à la méthode, le code définit la propriété Value de la propriété Orient et définit les indicateurs pageOrientationChanged et documentChanged . (Le code utilise l’indicateur pageOrientationChanged pour déterminer s’il doit mettre à jour la taille et les marges de la page. Il utilise l’indicateur documentChanged pour déterminer s’il doit enregistrer le document à la fin.)

Remarque

Si le code doit créer la propriété Orient, il doit également créer la valeur à stocker dans la propriété, en tant que nouvelle instance EnumValue<T>, en fournissant la nouvelle orientation dans le constructeur EnumValue.

    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;
        }
    }

Mise à jour de la taille de page

À ce stade du code, l’orientation de la page a peut-être changé. Si c’est le cas, le code doit effectuer deux autres tâches. Il doit mettre à jour la taille de la page et mettre à jour les marges de page pour la section. La première tâche est simple : le code suivant change simplement la hauteur et la largeur de la page, en stockant les valeurs dans l’élément PageSize .

    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...
    }

Mise à jour des marges

L’étape suivante de l’exemple de procédure gère les marges de la section . Si l’orientation de la page a changé, le code doit faire pivoter les marges pour qu’elles correspondent. Pour ce faire, le code récupère une référence à l’élément PageMargin pour la section. Si l’élément existe, le code fait pivoter les marges. Notez que le code fait pivoter les marges de 90 degrés : certaines imprimantes font pivoter les marges de 270 degrés à la place et vous pouvez modifier le code pour en tenir compte. Sachez également que les propriétés Top et Bottom de l’objet PageMargin sont des valeurs signées, et que les propriétés Left et Right sont des valeurs non signées. Le code doit effectuer une conversion entre les deux types de valeurs à mesure qu’il fait pivoter les paramètres de marge, comme indiqué dans le code suivant.

    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));
    }

Enregistrement du document

Après toutes les modifications, le code détermine si le document a changé. Si le document a changé, le code l’enregistre.

    if (documentChanged)
    {
        docPart.Document.Save();
    }

Exemple de code

Voici l’exemple de code Complet SetPrintOrientation en C# et 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();
        }
    }
}

Voir aussi