簡體   English   中英

替換標題中的圖像,OpenXML

[英]replace image in header, OpenXML

我希望有人可以協助解決這個問題。 我正在使用 OpenXMl 來搜索和替換使用 Open XML 的 Word 文檔的頁眉、正文和頁腳中的文本。 文本工作正常。 但是圖像並沒有像我期望的那樣被替換。 圖像 (@"C:\\temp\\pic\\Logo.gif") 確實存在於源中。 但永遠不會正確顯示在word文檔中。 您可以在下面的區域中看到(#region“Modify Header Logo”)有人可以提供幫助嗎? 謝謝!

字錯誤

       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;
    }

首先,這是我手動插入到 Word 文檔中的圖像 (Picture.png) 的標記。 手動插入同一圖像時,您是否對照 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循環。 該循環采用w:hdr所有w:t后代,但從currentText循環體中使用currentText

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

循環體就足夠了。 我只會使用FirstOrDefault並檢查是否為空,除非您 100% 確定文本將存在於所有 (!) 標題中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM