替换标题,OpenXML中的图像

问题描述 投票:0回答:1

我希望有人可以解决这个问题。我正在使用OpenXMl使用Open XML在Word文档的页眉,正文和页脚中搜索和替换文本。文本工作正常。但是图像并没有像我期望的那样被替换。图像(@“ C:\ temp \ pic \ Logo.gif”)在源中确实存在。但是永远不会正确显示在Word文档中。您可以在下面的区域中看到(#region“修改标题徽标”)有人可以协助吗?谢谢!

Word Error

       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;
    }
c# replace openxml
1个回答
0
投票

[首先,这是我手动插入Word文档中的图像(Picture.png)的标记。手动插入相同图像时,是否将代码创建的标记与Microsoft Word创建的标记进行了比较?这通常有助于发现标记中的错误(尽管并非总是如此,因为存在多种“通往罗马的道路”,并且同一事物通常可以多种方式表示)。例如,您可以使用Open XML生产率工具比较两个文档,并查看标记的差异以及创建正确标记所需的代码。

    <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循环。该循环接受w:t的所有w:hdr后代,但从不使用循环主体中的currentText

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

循环的主体就足够了。我只用FirstOrDefault并检查是否为null,除非您100%确定文本将出现在所有(!)标头中。

© www.soinside.com 2019 - 2024. All rights reserved.