Alterar a orientação de impressão de um documento de processamento de texto
Este tópico mostra como usar as classes no SDK Open XML para Office para definir programaticamente a orientação de impressão de um documento Microsoft Word 2010 ou Microsoft Word 2013. Ele contém um método SetPrintOrientation de exemplo para ilustrar essa tarefa.
Método SetPrintOrientation
Você pode usar o método SetPrintOrientation para alterar a orientação de impressão de um documento de processamento de palavras. O método aceita dois parâmetros que indicam o nome do documento para modificar (cadeia de caracteres) e a nova orientação de impressão (PageOrientationValues).
O código a seguir mostra o método SetPrintOrientation .
public static void SetPrintOrientation(
string fileName, PageOrientationValues newOrientation)
Para cada seção no documento, se a nova orientação for diferente da orientação de impressão atual da seção, o código modificará a orientação de impressão da seção. Além disso, o código deve atualizar manualmente a largura, a altura e as margens para cada seção.
Chamando o método SetPrintOrientation de exemplo
Para chamar o método SetPrintOrientation de exemplo, passe uma cadeia de caracteres que contém o nome do arquivo a ser convertido. O código a seguir mostra uma chamada de método de exemplo.
SetPrintOrientation(@"C:\Users\Public\Documents\ChangePrintOrientation.docx",
PageOrientationValues.Landscape);
Como o código funciona
O código a seguir primeiro abre o documento usando o método Open e define o parâmetro isEditablecomo true para indicar que o documento deve ser leitura/gravação. O código mantém uma variável booliana que rastreia se o documento foi alterado (para que ele possa salvar o documento posteriormente, se o documento tiver sido alterado). O código recupera uma referência à parte do documento main e usa essa referência para recuperar uma coleção de todos os descendentes do tipo SectionProperties no conteúdo do documento. O código posterior usará essa coleção para definir a orientação para cada seção por sua vez.
using (var document =
WordprocessingDocument.Open(fileName, true))
{
bool documentChanged = false;
var docPart = document.MainDocumentPart;
var sections = docPart.Document.Descendants<SectionProperties>();
// Code removed here...
}
Iterando por todas as seções
O próximo bloco de código itera em todas as seções da coleção de elementos SectionProperties . Para cada seção, o código inicializa uma variável que rastreia se a orientação da página para a seção foi alterada para que o código possa atualizar o tamanho e as margens da página. (Se a nova orientação corresponder à orientação original, o código não atualizará a página.) O código continua recuperando uma referência ao primeiro descendente pageSize do elemento SectionProperties . Se a referência não for nula, o código atualizará a orientação conforme necessário.
foreach (SectionProperties sectPr in sections)
{
bool pageOrientationChanged = false;
PageSize pgSz = sectPr.Descendants<PageSize>().FirstOrDefault();
if (pgSz != null)
{
// Code removed here...
}
}
Definindo a Orientação para a Seção
O próximo bloco de código verifica primeiro se a propriedade Orient do elemento PageSize existe. Como acontece com muitas propriedades de elementos Open XML, a propriedade ou atributo pode não existir ainda. Nesse caso, recuperar a propriedade retorna uma referência nula. Por padrão, se a propriedade não existir e a nova orientação for Retrato, o código não atualizará a página. Se a propriedade Orient já existir, e seu valor for diferente do novo valor de orientação fornecido como um parâmetro para o método, o código definirá a propriedade Value da propriedade Orient e definirá a pageOrientationChanged e os sinalizadores documentChanged . (O código usa o sinalizador pageOrientationChanged para determinar se ele deve atualizar o tamanho e as margens da página. Ele usa o sinalizador documentChanged para determinar se ele deve salvar o documento no final.)
Observação
Se o código precisar criar a propriedade Orient , ele também deverá criar o valor a ser armazenado na propriedade, como uma nova instância EnumValue<T> , fornecendo a nova orientação no construtor 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;
}
}
Atualizando o tamanho da página
Neste ponto do código, a orientação da página pode ter sido alterada. Nesse caso, o código deve concluir mais duas tarefas. Ele deve atualizar o tamanho da página e atualizar as margens da página para a seção. A primeira tarefa é fácil: o código a seguir apenas troca a altura e a largura da página, armazenando os valores no elemento 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...
}
Atualizando as margens
A próxima etapa do procedimento de exemplo manipula as margens da seção. Se a orientação da página tiver sido alterada, o código deverá girar as margens para corresponder. Para fazer isso, o código recupera uma referência ao elemento PageMargin para a seção. Se o elemento existir, o código girará as margens. Observe que o código gira as margens em 90 graus— algumas impressoras giram as margens em 270 graus e você pode modificar o código para levar isso em conta. Também esteja ciente de que as propriedades Superior e Inferior do objeto PageMargin são valores assinados e as propriedades esquerda e direita são valores não assinados. O código deve ser convertido entre os dois tipos de valores à medida que gira as configurações de margem, conforme mostrado no código a seguir.
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));
}
Salvar o Documento
Após todas as modificações, o código determina se o documento foi alterado. Se o documento tiver sido alterado, o código o salvará.
if (documentChanged)
{
docPart.Document.Save();
}
Código de exemplo
A seguir está o exemplo completo de código SetPrintOrientation em C# e 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();
}
}
}