Создание ImagePart не сохраняет отношения в OpenXML

- Обновлен, чтобы предоставить полный пример рабочего класса, с 2 примерами документов -

www.sklinar.co.uk/wp-content/uploads/mydoc.docx - Оригинальный документ с инструкцией INCLUDETEXT для объединения в Footer.Docx

www.sklinar.co.uk/wp-content/uploads/footer.docx

Я добавилImagePart к моему документу, а также с помощьюFeedData() обеспечить его потоковым контентом.

Но все, что я могу увидеть в своем документе, это красная рамка.

Мой исходный код СоздаетRun сDrawing как это ребенок

- В этом примере я использовал жестко закодированный FileStream, чтобы отсеять нечеткие изображения.

Просто чтобы заставить это работать, я использую один и тот же нижний колонтитул каждый раз, и в настоящее время он жестко задан с правильным нижним колонтитулом:

runToAmend.InsertAfterSelf(CreateImageRun(sourceDocument,run,target.MainDocumentPart.FooterParts.ElementAt(2)));

runToAmend берется из прогона в текущем документе, который содержит поле, которое затем удаляется, а изображение (и другой текст, взятый из другого документа) помещается на его место.

    public Run CreateImageRun(WordprocessingDocument sourceDoc,  Run sourceRunFromOriginalDocument, FooterPart footerPart)
    {
        ImageData shape = sourceRun.Descendants<ImageData>().FirstOrDefault();

        ImagePart p = sourceDoc.MainDocumentPart.GetPartById(shape.RelationshipId) as ImagePart;

        ImagePart newPart = footerPart.AddImagePart(ImagePartType.Jpeg);

        using (Stream stream = new FileStream(@"C:\Users\SAS\Desktop\IMG_20130803_104521.jpg",FileMode.Open,FileAccess.Read))
        {
            stream.Position = 0;
            newPart.FeedData(stream);
        }

        string partId = footerPart.GetIdOfPart(newPart);

        Drawing newImage = CreateImage(partId);
        return new Run(newImage);
    }

Code to Create Drawing

private Drawing CreateImage(string relationshipId)
    {
        // Define the reference of the image.
        return new Drawing(
                 new DW.Inline(
                     new DW.Extent() { Cx = 990000L, Cy = 792000L },
                     new DW.EffectExtent()
                     {
                         LeftEdge = 0L,
                         TopEdge = 0L,
                         RightEdge = 0L,
                         BottomEdge = 0L
                     },
                     new DW.DocProperties()
                     {
                         Id = (UInt32Value)1U,
                         Name = "Picture 1"
                     },
                     new DW.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 = "New Bitmap Image.jpg"
                                     },
                                     new PIC.NonVisualPictureDrawingProperties()),
                                 new PIC.BlipFill(
                                     new A.Blip(
                                         new A.BlipExtensionList(
                                             new A.BlipExtension()
                                             {
                                                 Uri =
                                                   "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                             })
                                     )
                                     {
                                         Embed = relationshipId,
                                         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 = 990000L, Cy = 792000L }),
                                     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,
                     EditId = "50D07946"
                 });
    }

Созданный XML-файл выглядит правильно, и изображение добавляется в/Media/ папка.

<w:r>
  <w:drawing>
    <wp:inline distT="0" distB="0" distL="0" distR="0" wp14:editId="50D07946">
      <wp:extent cx="990000" cy="792000" />
      <wp:effectExtent l="0" t="0" r="0" b="0" />
      <wp:docPr id="1" name="Picture 1" />
      <wp:cNvGraphicFramePr>
        <a:graphicFrameLocks noChangeAspect="1" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
      </wp:cNvGraphicFramePr>
      <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
        <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
          <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
            <pic:nvPicPr>
              <pic:cNvPr id="0" name="New Bitmap Image.jpg" />
              <pic:cNvPicPr />
            </pic:nvPicPr>
            <pic:blipFill>
              <a:blip r:embed="Raae77c5adb2e48f3" cstate="print">
                <a:extLst>
                  <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}" />
                </a:extLst>
              </a:blip>
              <a:stretch>
                <a:fillRect />
              </a:stretch>
            </pic:blipFill>
            <pic:spPr>
              <a:xfrm>
                <a:off x="0" y="0" />
                <a:ext cx="990000" cy="792000" />
              </a:xfrm>
              <a:prstGeom prst="rect">
                <a:avLst />
              </a:prstGeom>
            </pic:spPr>
          </pic:pic>
        </a:graphicData>
      </a:graphic>
    </wp:inline>
  </w:drawing>
</w:r>

Я потратил около 2 дней на поиски SO, плохих документов Google MS.

public class WordTest
    {
        using DocumentFormat.OpenXml;
        using DocumentFormat.OpenXml.Packaging;
        using DocumentFormat.OpenXml.Vml;
        using DocumentFormat.OpenXml.Wordprocessing;
        using System;
        using System.Collections.Generic;
        using System.Drawing;
        using System.IO;
        using System.Linq;
        using A = DocumentFormat.OpenXml.Drawing;
        using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
        using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
        public void MethodName()
        {
            WordprocessingDocument mainDoc = WordprocessingDocument.Open("mydoc.docx", true);

            foreach (var item in mainDoc.MainDocumentPart.FooterParts)
            {
                ProcessParaIncludeTextMerge(item, item.Footer.Descendants<Run>(), mainDoc);
                item.Footer.Save();
            }

            mainDoc.MainDocumentPart.Document.Save();

        }

        private void ProcessParaIncludeTextMerge(OpenXmlPart part, IEnumerable<Run> runs, WordprocessingDocument originalDocument)
        {
            List<Run> paraRuns = runs.ToList();

            int runCount = paraRuns.Count();

            for (int i = 0; i < runCount; i++)
            {
                Run r = paraRuns.ElementAt(i);

                // check if this is a simple Merge Field
                if (r.HasChildren && r.Descendants<FieldCode>().Any())
                {
                    FieldCode code = r.Descendants<FieldCode>().First();

                    // we check the first fieldcode is a merge field - but we can't *just* use that one, as for
                    // some stupid reason, the fieldcodes can be split across runs.... :/
                    if (code.Text.Trim().IndexOf("INCLUDETEXT", StringComparison.InvariantCultureIgnoreCase) > -1) //this is actually piss-poor, but as a merge field can go across n runs, we simply check for the M and let the other function figure it out..
                    {
                        MergeIncludeText(i, paraRuns, originalDocument);
                    }
                }
            }
        }

        public Run CreateImageRun(WordprocessingDocument sourceDoc, Run sourceRun, WordprocessingDocument target, FooterPart footerPart)
        {
             ImagePart newPart = footerPart.AddImagePart(ImagePartType.Png);

            ImageData shape = sourceRun.Descendants<ImageData>().FirstOrDefault();

            ImagePart p = sourceDoc.MainDocumentPart.GetPartById(shape.RelationshipId) as ImagePart;

            Bitmap image = new Bitmap(p.GetStream()); 

            using (Stream s = p.GetStream())
            {
                s.Position = 0;
                newPart.FeedData(s);
            }

            string partId = footerPart.GetIdOfPart(newPart);

            Drawing newImage = CreateImage(partId);

            return new Run(newImage);
        }

        private Drawing CreateImage(string relationshipId)
        {
            // Define the reference of the image.
            return new Drawing(
                     new DW.Inline(
                         new DW.Extent() { Cx = 990000L, Cy = 792000L },
                         new DW.EffectExtent()
                         {
                             LeftEdge = 0L,
                             TopEdge = 0L,
                             RightEdge = 0L,
                             BottomEdge = 0L
                         },
                         new DW.DocProperties()
                         {
                             Id = (UInt32Value)1U,
                             Name = "Picture 1"
                         },
                         new DW.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 = "New Bitmap Image.jpg"
                                         },
                                         new PIC.NonVisualPictureDrawingProperties()),
                                     new PIC.BlipFill(
                                         new A.Blip(
                                             new A.BlipExtensionList(
                                                 new A.BlipExtension()
                                                 {
                                                     Uri =
                                                       "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                 })
                                         )
                                         {
                                             Embed = relationshipId,
                                             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 = 990000L, Cy = 792000L }),
                                         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,
                         EditId = "50D07946"
                     });
        }

        private void ReplaceRunsWithRuns(IEnumerable<Run> fieldRuns, IEnumerable<Run> value, WordprocessingDocument source, WordprocessingDocument target)
        {
            FooterPart f = target.MainDocumentPart.FooterParts.ElementAt(1);

            f.Footer.RemoveAllChildren();

            Paragraph p = new Paragraph();
            //the run has no value to merge into, remove the field.
            if (value != null)
            {
                foreach (var item in value)
                {
                    if (!item.Descendants<Picture>().Any()) //pictures are processed differently - they're an absolute s**t storm to code...
                    {
                        p.Append(item.CloneNode(true));
                    }
                    else
                    {
                        p.Append(CreateImageRun(source, item, target, f));
                    }
                }
            }
            else
            {
            }
            f.Footer.Append(p);
        }

        private void MergeIncludeText(int curRunIdx, List<Run> runs, WordprocessingDocument originalDoc)
        {
            int startRun = GetBeginRun(runs, curRunIdx);

            if (startRun == -1)
            {
                return;
            }

            int endRun = GetEndRun(runs, startRun);

            if (endRun == -1)
            {
                return;
            }

            IEnumerable<Run> fieldRuns = WordMLHelpers.GetRunsBetweenTwoPoints(runs, startRun, endRun);

            IEnumerable<FieldCode> fieldCodes = fieldRuns.SelectMany(x => x.Descendants<FieldCode>());

            string mergeField = string.Concat(fieldCodes.Select(x => x.Text));

            string field = GetIncludeTextFilePath(mergeField);

            MemoryStream ms = LoadDocumentStream(field);

            WordprocessingDocument includeDoc = LoadDocumentFromStream(ms);

            IEnumerable<Run> includedRuns = includeDoc.MainDocumentPart.Document.Descendants<Run>();

            ReplaceRunsWithRuns(fieldRuns, includedRuns, includeDoc, originalDoc);
        }

        private string GetIncludeTextFilePath(string mergeFieldText)
        {
            int quoteStart = mergeFieldText.IndexOf('"') + 1;

            int quoteEnd = mergeFieldText.IndexOf('"', quoteStart);

            return mergeFieldText.Substring(quoteStart, quoteEnd - quoteStart);
        }

        private WordprocessingDocument LoadDocumentFromStream(Stream stream)
        {
            return WordprocessingDocument.Open(stream, true);
        }

#region helpers
        public static int GetBeginRun(IEnumerable<Run> runs, int curIdx)
        {
            for (int i = curIdx; i < runs.Count(); i--)
            {
                if (i == -1)
                {
                    return -1;
                }
                Run run = runs.ElementAt(i);

                if (run.HasChildren && run.ChildElements.OfType<FieldChar>().Count() > 0
                      && (run.ChildElements.OfType<FieldChar>().First().FieldCharType == FieldCharValues.Begin))
                {
                    return i;
                }
            }

            throw new Exception("Begin not found");
        }

        /// <summary>
        /// Get the first End Run in a <see cref="List"/>(<see cref="Run"/>)
        /// </summary>
        /// <param name="runs">The runs.</param>
        /// <param name="curIdx">The cur idx.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">End not found</exception>
        public static int GetEndRun(IEnumerable<Run> runs, int curIdx)
        {
            //runs.FirstOrDefault(x => x.HasChildren && x.Descendants<FieldChar>().Count > 0 && (x.Descendants<FieldChar>().First().FieldCharType & FieldCharValues.End) == FieldCharValues.End);

            for (int i = curIdx; i < runs.Count(); i++)
            {
                if (i == -1)
                {
                    return -1;
                }
                Run run = runs.ElementAt(i);

                if (run.HasChildren && run.Descendants<FieldChar>().Any()
                       && (run.Descendants<FieldChar>().First().FieldCharType == FieldCharValues.End))
                {
                    return i;
                }
            }

            return -1;
        }

        public static MemoryStream LoadDocumentStream(string template)
        {
            using (FileStream fs = File.Open(template, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // first read document in as stream
                MemoryStream ms = new MemoryStream();

                fs.CopyTo(ms);
                ms.Seek(0, SeekOrigin.Begin);
                return ms;
            }
        }
#endregion


    }

Ответы на вопрос(1)

Ваш ответ на вопрос