使用 OpenXML SDK 删除 header 中的图像
Removing images in header with OpenXML SDK
我使用了一些 OpenXML SDK,并制作了一个替换 Word 文档中 header 中的图像的 POC。但是,当我尝试使用要删除的图像调用 DeletePart 或 DeleteParts 时,它并没有按预期进行。
之后打开word doc时,之前有图片的地方现在有一个框架,上面有文字"This image cannot currently be displayed"和一个红叉。
通过一些谷歌搜索,似乎没有完全删除引用,但我找不到关于如何删除的任何帮助..
下面是我如何删除图像的示例。我只将其中一些添加到列表中,因为除了具有特定 uri 的那些之外,我需要删除所有内容..
//...
foreach(HeaderPart headerPart in document.MainDocumentPart.HeaderParts) {
List<ImagePart> list = new List<ImagePart>();
List<ImagePart> imgParts = new List<ImagePart> (headerPart.ImageParts);
foreach(ImagePart headerImagePart in imgParts) {
string newUri = headerImagePart.Uri.ToString();
if(newUri != uri) {
list.Add(headerImagePart);
}
}
headerPart.DeleteParts(list);
}
//...
图像在 OpenXml 中由两部分组成;您拥有实际图像本身,并且还拥有图像在文档中显示的 Picture
容器的详细信息。
如果您考虑在同一个文档中多次显示图像,这是有道理的;图像的细节可以存储一次,图像的位置可以根据需要存储多次。
以下代码将查找包含您要删除的 ImagePart
个对象的任何 Drawing
个对象。这是通过将 Blip
的 Embed
属性 与 ImagePart
.
的 ID 匹配来完成的
using (WordprocessingDocument document = WordprocessingDocument.Open(filename, true))
{
foreach (HeaderPart headerPart in document.MainDocumentPart.HeaderParts)
{
List<ImagePart> list = new List<ImagePart>();
List<ImagePart> imgParts = new List<ImagePart>(headerPart.ImageParts);
List<Drawing> drwdDeleteParts = new List<Drawing>();
List<Drawing> drwParts = new List<Drawing>(headerPart.RootElement.Descendants<Drawing>());
foreach (ImagePart headerImagePart in imgParts)
{
string newUri = headerImagePart.Uri.ToString();
if (newUri != uri)
{
list.Add(headerImagePart);
//you also need to find the Drawings the image was related to
IEnumerable<Drawing> drawings = drwParts.Where(d => d.Descendants<Pic.Picture>().Any(p => p.BlipFill.Blip.Embed == headerPart.GetIdOfPart(headerImagePart)));
foreach (var drawing in drawings)
{
if (drawing != null && !drwdDeleteParts.Contains(drawing))
drwdDeleteParts.Add(drawing);
}
}
}
foreach (var d in drwdDeleteParts)
{
d.Remove();
}
headerPart.DeleteParts(list);
}
}
正如您在评论中指出的,您需要添加一个 using 语句:
Pic = DocumentFormat.OpenXml.Drawing.Pictures;
我使用了一些 OpenXML SDK,并制作了一个替换 Word 文档中 header 中的图像的 POC。但是,当我尝试使用要删除的图像调用 DeletePart 或 DeleteParts 时,它并没有按预期进行。
之后打开word doc时,之前有图片的地方现在有一个框架,上面有文字"This image cannot currently be displayed"和一个红叉。
通过一些谷歌搜索,似乎没有完全删除引用,但我找不到关于如何删除的任何帮助..
下面是我如何删除图像的示例。我只将其中一些添加到列表中,因为除了具有特定 uri 的那些之外,我需要删除所有内容..
//...
foreach(HeaderPart headerPart in document.MainDocumentPart.HeaderParts) {
List<ImagePart> list = new List<ImagePart>();
List<ImagePart> imgParts = new List<ImagePart> (headerPart.ImageParts);
foreach(ImagePart headerImagePart in imgParts) {
string newUri = headerImagePart.Uri.ToString();
if(newUri != uri) {
list.Add(headerImagePart);
}
}
headerPart.DeleteParts(list);
}
//...
图像在 OpenXml 中由两部分组成;您拥有实际图像本身,并且还拥有图像在文档中显示的 Picture
容器的详细信息。
如果您考虑在同一个文档中多次显示图像,这是有道理的;图像的细节可以存储一次,图像的位置可以根据需要存储多次。
以下代码将查找包含您要删除的 ImagePart
个对象的任何 Drawing
个对象。这是通过将 Blip
的 Embed
属性 与 ImagePart
.
using (WordprocessingDocument document = WordprocessingDocument.Open(filename, true))
{
foreach (HeaderPart headerPart in document.MainDocumentPart.HeaderParts)
{
List<ImagePart> list = new List<ImagePart>();
List<ImagePart> imgParts = new List<ImagePart>(headerPart.ImageParts);
List<Drawing> drwdDeleteParts = new List<Drawing>();
List<Drawing> drwParts = new List<Drawing>(headerPart.RootElement.Descendants<Drawing>());
foreach (ImagePart headerImagePart in imgParts)
{
string newUri = headerImagePart.Uri.ToString();
if (newUri != uri)
{
list.Add(headerImagePart);
//you also need to find the Drawings the image was related to
IEnumerable<Drawing> drawings = drwParts.Where(d => d.Descendants<Pic.Picture>().Any(p => p.BlipFill.Blip.Embed == headerPart.GetIdOfPart(headerImagePart)));
foreach (var drawing in drawings)
{
if (drawing != null && !drwdDeleteParts.Contains(drawing))
drwdDeleteParts.Add(drawing);
}
}
}
foreach (var d in drwdDeleteParts)
{
d.Remove();
}
headerPart.DeleteParts(list);
}
}
正如您在评论中指出的,您需要添加一个 using 语句:
Pic = DocumentFormat.OpenXml.Drawing.Pictures;