Saltar al contenido

Insertar imagen en DocX usando OpenXML y configurar el tamaño

Nuestro grupo de expertos luego de muchos días de trabajo y de recopilar de información, hallamos la respuesta, esperamos que te sea de gran utilidad en tu proyecto.

Solución:

Los tamaños, en EMU (unidades métricas inglesas; lea esto para obtener una buena explicación), se establecen en las extensiones (Cx y Cy). Para obtener una imagen en un DocX, generalmente lo hago así:

  1. Obtenga las dimensiones y la resolución de la imagen
  2. Calcule el ancho de la imagen en EMU: wEmu = imgWidthPixels / imgHorizontalDpi * emuPerInch
  3. Calcule la altura de la imagen en EMU: hEmu = imgHeightPixels / imgVerticalDpi * emuPerInch
  4. Calcule el ancho máximo de página en EMU (descubrí que si la imagen es demasiado ancha, no se mostrará)
  5. Si el ancho de la imagen en EMU es mayor que el ancho máximo de la página, escalo el ancho y el alto de la imagen para que el ancho de la imagen sea igual al de la página (cuando digo página, me refiero a la página “utilizable” , eso es menos los márgenes):

    var ratio = hEmu / wEmu;
    wEmu = maxPageWidthEmu;
    hEmu = wEmu * ratio;

  6. Luego uso el ancho como el valor de Cx y la altura como el valor de Cy, ambos en el DW.Extent y en el A.Extents (de El A.Transform2D de El PIC.ShapeProperties).

Tenga en cuenta que el valor de emuPerInch es 914400.
Tengo esto ejecutándose (en un servicio) pero no tengo el código conmigo en este momento.

ACTUALIZAR

Este es el código que utilizo:

var img = new BitmapImage(new Uri(fileName, UriKind.RelativeOrAbsolute));
var widthPx = img.PixelWidth;
var heightPx = img.PixelHeight;
var horzRezDpi = img.DpiX;
var vertRezDpi = img.DpiY;
const int emusPerInch = 914400;
const int emusPerCm = 360000;
var widthEmus = (long)(widthPx / horzRezDpi * emusPerInch);
var heightEmus = (long)(heightPx / vertRezDpi * emusPerInch);
var maxWidthEmus = (long)(maxWidthCm * emusPerCm);
if (widthEmus > maxWidthEmus) 
  var ratio = (heightEmus * 1.0m) / widthEmus;
  widthEmus = maxWidthEmus;
  heightEmus = (long)(widthEmus * ratio);

En mi caso, las medidas de mi página están en cm, de ahí el emusPerCm que ves arriba.

ACTUALIZACIÓN 2 (para responder @andw)

Para tener el archivo bloqueado durante el mínimo tiempo posible, ábralo con un FileStream y pasar la corriente resultante a la StreamSource propiedad de la BitmapImage:

var img = new BitmapImage();
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    img.BeginInit();
    img.StreamSource = fs;
    img.EndInit();

// The file is now unlocked
var widthPx = img.PixelWidth;
...

Puedes darle a la imagen su tamaño original de esta manera:

Primero obtienes el ancho y alto del archivo:

int iWidth = 0;
int iHeight = 0;
using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap("yourFilePath"))

     iWidth = bmp.Width;
     iHeight = bmp.Height;

Luego convertir los pixeles para EMU Por aquí:

iWidth = (int)Math.Round((decimal)iWidth * 9525);
iHeight = (int)Math.Round((decimal)iHeight * 9525);

Y finalmente dé los valores al abrir su archivo, me refiero en esta línea de su código:

new DW.Extent()  Cx = 990000L, Cy = 792000L ,

reemplazar Cx y Cy con sus valores calculados para que se vea así:

new DW.Extent()  Cx = iWidth, Cy = iHeight ,

Observe que hay dos líneas en su código donde debe dar los valores calculados.

Entonces tienes tu imagen en su tamaño original, espero que esto ayude a alguien.

Este código me funciona.

Fuente: http://msdn.microsoft.com/en-us/library/office/bb497430(v=office.15).aspx

    public static void Do()
    
        string filename = @"c:tempm.docx";
        byte[] reportData = GetWordReport();
       // File.WriteAllBytes(filename, reportData);
        //MessageBox.Show("File " + filename + " created");
    

    private static byte[] GetWordReport()
    
       // using (MemoryStream stream = new MemoryStream())
       // 
            //var template = GetTemplateData();
            //stream.Write(template, 0, template.Length);
            using (WordprocessingDocument docx = WordprocessingDocument.Open(@"c:tempm.docx", true))
            
                // Some changes on docx
                docx.MainDocumentPart.Document = GenerateMainDocumentPart(6,4);

                var imagePart = docx.MainDocumentPart.AddNewPart("image/jpeg", "rIdImagePart1");
                GenerateImagePart(imagePart);
            
          //  stream.Seek(0, SeekOrigin.Begin);
           // return stream.ToArray();
       // 
        return null;
    

    private static byte[] GetTemplateData()
    
        using (MemoryStream targetStream = new MemoryStream())
        using (BinaryReader sourceReader = new BinaryReader(File.Open(@"c:tempm_2.docx", FileMode.Open)))
        
            byte[] buffer = new byte[4096];

            int num = 0;
            do
            
                num = sourceReader.Read(buffer, 0, 4096);
                if (num > 0)
                    targetStream.Write(buffer, 0, num);
            
            while (num > 0);
            targetStream.Seek(0, SeekOrigin.Begin);
            return targetStream.ToArray();
        
    

    private static void GenerateImagePart(OpenXmlPart part)
    
        using (Stream imageStream = File.Open(@"c:tempimage002.jpg", FileMode.Open))
        
            part.FeedData(imageStream);
        
    

    private static Document GenerateMainDocumentPart(int cx,int cy)
    
        long LCX = cx*261257L;
        long LCY = cy*261257L;




        var element =
            new Document(
                new Body(
                    new Paragraph(
                        new Run(
                            new RunProperties(
                                new NoProof()),
                            new Drawing(
                                new wp.Inline(
                                    new wp.Extent()  Cx = LCX, Cy = LCY ,
                                    new wp.EffectExtent()  LeftEdge = 0L, TopEdge = 19050L, RightEdge = 0L, BottomEdge = 0L ,
                                    new wp.DocProperties()  Id = (UInt32Value)1U, Name = "Picture 0", Description = "Forest Flowers.jpg" ,
                                    new wp.NonVisualGraphicFrameDrawingProperties(
                                        new a.GraphicFrameLocks()  NoChangeAspect = true ),
                                    new a.Graphic(
                                        new a.GraphicData(
                                            new pic.Picture(
                                                new pic.NonVisualPictureProperties(
                                                    new pic.NonVisualDrawingProperties()  Id = (UInt32Value)0U, Name = "Forest Flowers.jpg" ,
                                                    new pic.NonVisualPictureDrawingProperties()),
                                                new pic.BlipFill(
                                                    new a.Blip()  Embed = "rIdImagePart1", CompressionState = a.BlipCompressionValues.Print ,
                                                    new a.Stretch(
                                                        new a.FillRectangle())),
                                                new pic.ShapeProperties(
                                                    new a.Transform2D(
                                                        new a.Offset()  X = 0L, Y = 0L ,
                                                        new a.Extents()  Cx = LCX, Cy = LCY ),
                                                    new a.PresetGeometry(
                                                        new a.AdjustValueList()
                                                    )  Preset = a.ShapeTypeValues.Rectangle ))
                                        )  Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" )
                                )  DistanceFromTop = (UInt32Value)0U, DistanceFromBottom = (UInt32Value)0U, DistanceFromLeft = (UInt32Value)0U, DistanceFromRight = (UInt32Value)0U ))
                    )  RsidParagraphAddition = "00A2180E", RsidRunAdditionDefault = "00EC4DA7" ,
                    new SectionProperties(
                        new PageSize()  Width = (UInt32Value)11906U, Height = (UInt32Value)16838U ,
                        new PageMargin()  Top = 1440, Right = (UInt32Value)1800U, Bottom = 1440, Left = (UInt32Value)1800U, Header = (UInt32Value)851U, Footer = (UInt32Value)992U, Gutter = (UInt32Value)0U ,
                        new Columns()  Space = ((UInt32Value)425U).ToString() ,
                        new DocGrid()  Type = DocGridValues.Lines, LinePitch = 312 
                    )  RsidR = "00A2180E", RsidSect = "00A2180E" ));
        return element;
    

Si guardas algún dificultad o disposición de acrecentar nuestro post eres capaz de escribir una referencia y con placer lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *