OpenXML 用实际图像替换图像占位符会替换所有占位符

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

我在尝试替换 Word 文档中的图像占位符时遇到一些奇怪的问题。如果我尝试用下面的代码替换占位符,它将替换所有这些代码。不仅仅是与 docproperties 中的名称匹配的那个。

经过进一步检查,我发现使用 OpenXML SDK Productivity Tool 查看 Word 文档时,我的占位符图片共享相同的嵌入 id。这是为什么?这似乎就是为什么我的所有占位符都被新图像替换的原因。

使用 OpenXML Productivity Tool 的部分文档:

 <pic:blipFill>
                <a:blip r:embed="rId6">
                  <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>

我的C#代码

public static void ReplacePlaceHolderWithPicture(this WordprocessingDocument doc, string nameOfImage, string imgFilePath)
{
    var drawings = doc.MainDocumentPart.Document.Descendants<Drawing>().ToList();
    var newImageBytes = File.ReadAllBytes(imgFilePath);

    foreach (var drawing in drawings)
    {
        var dpr = drawing.Descendants<DocProperties>().FirstOrDefault();
        if (dpr != null && dpr.Name == nameOfImage)
        {
            foreach (var b in drawing.Descendants<A.Blip>())
            {
                OpenXmlPart imagePart = doc.MainDocumentPart.GetPartById(b.Embed);

                using (var writer = new BinaryWriter(imagePart.GetStream()))
                {
                    writer.Write(newImageBytes);
                }
            }
        }
    }
}
c# image openxml placeholder cpu-word
1个回答
0
投票

重点是 EmbedID 将绘图链接到图像部分,图像部分又链接到图像文件。您将从要替换的绘图中获取图像部分 ID,并使用它用新图像填充图像部分。这样,链接到该图像部分的所有形状都将获得新图像。要仅替换具有指定名称的形状,您必须使用新文件创建一个新的图像部分,并将 id 放入您正在更新的绘图元素中。

这样您将只更新单个元素。

public static void ReplacePlaceHolderWithPicture(this WordprocessingDocument doc, string nameOfImage, string imgFilePath)
{
    var drawings = doc.MainDocumentPart.Document.Descendants<Drawing>().ToList();
    var newImageBytes = File.ReadAllBytes(imgFilePath);

    foreach (var drawing in drawings)
    {
        var dpr = drawing.Descendants<DocProperties>().FirstOrDefault();
        if (dpr != null && dpr.Name == nameOfImage)
        {

            //Instead of replacing the imagePart Data (and replacing all the images with the same embed id) add a new imagepart
            var imagePart = doc.MainDocumentPart.AddImagePart(ImagePartType.Jpeg); //Check if the image extensions specified is correct

            using (var stream = new MemoryStream(newImageBytes))
            {
                imagePart.FeedData(stream);
            }

            //Get the embed id of the image just added
            var relationshipId = doc.MainDocumentPart.GetIdOfPart(imagePart);

            foreach (var b in drawing.Descendants<Blip>())
            {
                //Set the ID of the new image into the blip of the aimed Drawing element
                b.Embed = relationshipId;
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.