заменить изображение в заголовке OpenXML - PullRequest
0 голосов
/ 24 марта 2020

Я надеюсь, что кто-то может помочь с этим вопросом. Я использую Open XMl для поиска и замены текста в верхнем и нижнем колонтитулах текстового документа, используя Open XML. Текст работает нормально. Но изображение не заменяет, как я ожидал. Изображение (@ "C: \ temp \ pic \ Lo go .gif") существует в источнике. Но никогда не отображается в документе слово правильно. Вы можете увидеть в регионе ниже (#region "Изменить заголовок Lo go") Кто-нибудь может помочь? Спасибо!

Ошибка в слове

       public void SearchAndReplace(string templateFileNameTemplate, string targetFileName, ProjectModel project)
    {

        //copy template file
        if (File.Exists(targetFileName) == true)
        {
            File.Delete(targetFileName);
        }

        File.Copy(templateFileNameTemplate, targetFileName);

        string searchText = "", replaceText = "", headerLogo = "", headerText = "";
        bool replace = false;

        //open file
        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(targetFileName, true))
        {

            //Gets all the headers
            foreach (var headerPart in wordDoc.MainDocumentPart.HeaderParts)
            {
                //Gets the text in headers
                foreach (var currentText in headerPart.RootElement.Descendants<Text>())
                {
                    replace = false;

                    switch (currentText.Text)
                    {
                        case "<COMPANY NAME>":
                            replace = true;
                            replaceText = project.ClientName;
                            searchText = currentText.Text;
                            break;
                        **case "<INSERT YOUR LOGO HERE>":
                            headerLogo = @"C:\temp\pic\Logo.gif";//project.ClientLogo;**
                            headerText = currentText.Text;
                            break;
                        case "<ISSUE DATE>":
                            replace = true;
                            replaceText = project.AssignedDate.ToShortDateString();
                            searchText = currentText.Text;
                            break;
                        case "<REVIEW DATE>":
                            replace = true;
                            replaceText = project.ClientDueDate.ToShortDateString();
                            searchText = currentText.Text;
                            break;
                        default:
                            break;
                    }
                    if(searchText.Length>0 && replace==true)
                        currentText.Text = currentText.Text.Replace(searchText, replaceText);
                }
            }
            //Gets all the footers
            foreach (var footerPart in wordDoc.MainDocumentPart.FooterParts)
            {
                //Gets the text in headers
                foreach (var currentText in footerPart.RootElement.Descendants<Text>())
                {
                    replace = false;
                    switch (currentText.Text)
                    {
                        case "<COMPANY NAME>":
                            replace = true;
                            replaceText = project.ClientName;
                            searchText = currentText.Text;
                            break;
                        default:
                            break;
                    }

                    if (searchText.Length > 0 && replace == true)
                        currentText.Text = currentText.Text.Replace(searchText, replaceText);
                }
            }
            #region "Modify Header Logo"
            if(headerLogo != string.Empty)
            {
                ImagePart imagePart = wordDoc.MainDocumentPart.AddImagePart(ImagePartType.Png);
                using (FileStream stream = new FileStream(headerLogo, FileMode.Open))
                {
                    imagePart.FeedData(stream);
                }
                searchText = headerText;
                Text textPlaceHolder = null;
                // Insert image (the image created with your function) after text place holder.        
                // Search for text holder
                //Gets all the headers
                foreach (var headerPart in wordDoc.MainDocumentPart.HeaderParts)
                {
                    //Gets the text in headers
                    foreach (var currentText in headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>())
                    {
                        textPlaceHolder = headerPart.RootElement.Descendants<Text>()
                            .Where((x) => x.Text == searchText).First();
                    }
                }


                if (textPlaceHolder != null)
                {
                    var parent = textPlaceHolder.Parent;

                    if (parent is Run)  // Parent should be a run element.
                    {
                        //add image
                        Drawing imageElement = GetImageElement(
                            wordDoc.MainDocumentPart.GetIdOfPart(imagePart),
                            headerLogo,
                            "my image",
                            475,
                            245);
                        // Insert image (the image created with your function) after text place holder.        
                        textPlaceHolder.Parent.InsertAfter<Drawing>(imageElement, textPlaceHolder);
                        // Remove text place holder.
                        textPlaceHolder.Remove();
                    }
                }
            }

            #endregion
            string docText = null;
            using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
            {
                docText = sr.ReadToEnd();
            }

            Regex regexText = new Regex("&lt;COMPANY NAME&gt;");
            docText = regexText.Replace(docText, project.ClientName);

            //regexText = new Regex("&lt;COMPANY NAME&gt;");
            //docText = regexText.Replace(docText, project.ClientName);

            using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
            {
                sw.Write(docText);
            }

            //wordDoc.SaveAs(targetFileName).Close();
        }
    }

        private static Drawing GetImageElement(
        string imagePartId,
        string fileName,
        string pictureName,
        double width,
        double height)
    {
        double englishMetricUnitsPerInch = 914400;
        double pixelsPerInch = 96;

        //calculate size in emu
        double emuWidth = width * englishMetricUnitsPerInch / pixelsPerInch;
        double emuHeight = height * englishMetricUnitsPerInch / pixelsPerInch;

        var element = new Drawing(
            new A.Wordprocessing.Inline(
                new A.Wordprocessing.Extent { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight },
                new A.Wordprocessing.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
                new A.Wordprocessing.DocProperties { Id = (UInt32Value)1U, Name = pictureName },
                new A.Wordprocessing.NonVisualGraphicFrameDrawingProperties(
                new A.GraphicFrameLocks { NoChangeAspect = true }),
                new A.Graphic(
                    new A.GraphicData(
                        new A.Pictures.Picture(
                            new A.Pictures.NonVisualPictureProperties(
                                new A.Pictures.NonVisualDrawingProperties { Id = (UInt32Value)0U, Name = fileName },
                                new A.Pictures.NonVisualPictureDrawingProperties()),
                            new A.Pictures.BlipFill(
                                new A.Blip(
                                    new A.BlipExtensionList(
                                        new A.BlipExtension { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }))
                                {
                                    Embed = imagePartId,
                                    CompressionState = A.BlipCompressionValues.Print
                                },
                                        new A.Stretch(new A.FillRectangle())),
                            new A.Pictures.ShapeProperties(
                                new A.Transform2D(
                                    new A.Offset { X = 0L, Y = 0L },
                                    new A.Extents { Cx = (Int64Value)emuWidth, Cy = (Int64Value)emuHeight }),
                                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"
            });
        return element;
    }

1 Ответ

0 голосов
/ 25 марта 2020

Во-первых, вот разметка для изображения (Picture.png), которое я вручную вставил в документ Word. Вы проверяли разметку, созданную вашим кодом, на соответствие разметке, созданной Microsoft Word, при вставке того же изображения вручную? Это часто помогает обнаружить ошибки в разметке (однако не всегда, потому что существует несколько «путей в Рим», и одно и то же часто можно выразить несколькими способами). Вы можете использовать Open XML Productivity Tool, например, чтобы сравнить два документа и посмотреть на различия в разметке и код, необходимый для создания правильной разметки.

    <w:r>
      <w:rPr>
        <w:noProof/>
      </w:rPr>
      <w:drawing>
        <wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="787F9556" wp14:editId="6F9F029A">
          <wp:extent cx="4026107" cy="4019757"/>
          <wp:effectExtent l="0" t="0" r="0" b="0"/>
          <wp:docPr id="2" name="Picture 2" descr="A close up of a sign&#xA;&#xA;Description automatically generated"/>
          <wp:cNvGraphicFramePr>
            <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
          </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="2" name="Picture.png"/>
                  <pic:cNvPicPr/>
                </pic:nvPicPr>
                <pic:blipFill>
                  <a:blip r:embed="rId1">
                    <a:extLst>
                      <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                        <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
                      </a:ext>
                    </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="4026107" cy="4019757"/>
                  </a:xfrm>
                  <a:prstGeom prst="rect">
                    <a:avLst/>
                  </a:prstGeom>
                </pic:spPr>
              </pic:pic>
            </a:graphicData>
          </a:graphic>
        </wp:inline>
      </w:drawing>
    </w:r>

Во-вторых, следующий код не имеет большого смысла, потому что вам не нужно foreach l oop. То, что l oop принимает всех w:t потомков w:hdr, но никогда не использует currentText в теле l oop.

foreach (var currentText in headerPart.RootElement.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>())
{
    textPlaceHolder = headerPart.RootElement.Descendants<Text>()
       .Where((x) => x.Text == searchText).First();
}

Тела l oop достаточно , Я просто использовал бы FirstOrDefault и проверил бы на ноль, если вы не уверены на 100%, что текст будет присутствовать во всех (!) Заголовках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...