【问题标题】:copying openXML image from one document to another将 openXML 图像从一个文档复制到另一个文档
【发布时间】:2018-11-16 22:51:41
【问题描述】:

我们有条件页脚,INCLUDETEXT 基于客户端:

IF $CLIENT = "CLIENT1" "{INCLUDETEXT "CLIENT1HEADER.DOCX"}" ""

根据我们的文档,IF/ELSE 的数量可能会有所不同,这些都可以正常工作以将正确的文件合并到正确的位置。

但是,其中一些文档可能包含客户特定的图像/品牌,也需要从 INCLUDETEXT 文件中复制。

下面是调用的方法,用于替换从源文档复制到目标文档的IEnumerable<Run> 中存在的任何Picture 元素。

图像复制得很好,但它似乎没有更新我的Picture 中的 RID 或将记录添加到 .XML.Rels 文件中。 (我什至尝试添加ForEach 以添加到所有页眉和页脚,看看这是否有什么不同。

    private void InsertImagesFromOldDocToNewDoc(WordprocessingDocument source, WordprocessingDocument target, IEnumerable<Picture> pics)
    {
        IEnumerable<Picture> imageElements = source.MainDocumentPart.Document.Descendants<Run>().Where(x => x.Descendants<Picture>().FirstOrDefault() != null).Select(x => x.Descendants<Picture>().FirstOrDefault());

        foreach (Picture pic in pics) //the new pics
        {
            Picture oldPic = imageElements.Where(x => x.Equals(pic)).FirstOrDefault();

            if (oldPic != null)
            {
                string imageId = "";

                ImageData shape = oldPic.Descendants<ImageData>().FirstOrDefault();

                ImagePart p = source.MainDocumentPart.GetPartById(shape.RelationshipId) as ImagePart;

                ImagePart newPart = target.MainDocumentPart.AddPart<ImagePart>(p);

                newPart.FeedData(p.GetStream());

                shape.RelId = target.MainDocumentPart.GetIdOfPart(newPart);
                string relPart = target.MainDocumentPart.CreateRelationshipToPart(newPart);
            }
        }
    }

以前有人遇到过这个问题吗?

OpenXML SDK 文档似乎“有点”稀疏...

【问题讨论】:

  • 你解决过这个问题吗?

标签: c# openxml openxml-sdk mailmerge


【解决方案1】:

反应迟了,但这个帖子帮了我很多,让它发挥作用。这是我复制带有图像的文档的解决方案

private static void CopyDocumentWithImages(string path)
{
    if (!Path.GetFileName(path).StartsWith("~$"))
    {
        using (var source = WordprocessingDocument.Open(path, false))
        {
            using (var newDoc = source.CreateNew(path.Replace(".docx", "-images.docx")))
            {
                foreach (var e in source.MainDocumentPart.Document.Body.Elements())
                {
                    var clonedElement = e.CloneNode(true);
                    clonedElement.Descendants<DocumentFormat.OpenXml.Drawing.Blip>()
                        .ToList().ForEach(blip =>
                        {
                            var newRelation = newDoc.CopyImage(blip.Embed, source);
                            blip.Embed = newRelation;
                        });
                    clonedElement.Descendants<DocumentFormat.OpenXml.Vml.ImageData>().ToList().ForEach(imageData =>
                    {
                        var newRelation = newDoc.CopyImage(imageData.RelationshipId, source);
                        imageData.RelationshipId = newRelation;
                    });
                    newDoc.MainDocumentPart.Document.Body.AppendChild(clonedElement);
                }
                newDoc.Save();
            }
        }
    }
}

复制图片:

public static string CopyImage(this WordprocessingDocument newDoc, string relId, WordprocessingDocument org)
{
    var p = org.MainDocumentPart.GetPartById(relId) as ImagePart;
    var newPart = newDoc.MainDocumentPart.AddPart(p);
    newPart.FeedData(p.GetStream());
    return newDoc.MainDocumentPart.GetIdOfPart(newPart);
}

新建:

public static WordprocessingDocument CreateNew(this WordprocessingDocument org, string name)
{
    var doc = WordprocessingDocument.Create(name, WordprocessingDocumentType.Document);
    doc.AddMainDocumentPart();
    doc.MainDocumentPart.Document = new Document(new Body());
    using (var streamReader = new StreamReader(org.MainDocumentPart.ThemePart.GetStream()))
    using (var streamWriter = new StreamWriter(doc.MainDocumentPart.AddNewPart<ThemePart>().GetStream(FileMode.Create)))
    {
        streamWriter.Write(streamReader.ReadToEnd());
    }
    using (var streamReader = new StreamReader(org.MainDocumentPart.StyleDefinitionsPart.GetStream()))
    using (var streamWriter = new StreamWriter(doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>().GetStream(FileMode.Create)))
    {
        streamWriter.Write(streamReader.ReadToEnd());
    }
    return doc;
}

【讨论】:

  • 我会挖掘出原始来源并查看;)谢谢
  • 这对我有用,非常感谢。我希望有一种方法可以从 OpenXmlElement 克隆图像,而无需参考父文档。
  • 完美!为我省了很多力气!
  • @Marcel Hoekstra 当您将 word 文档的片段复制到另一个 word 文档中时,这是唯一的问题吗?主题、电子表格、样式...必须以相同的复杂方式复制它们才能在结果文档中正确查看?
  • 以这种方式复制图像后,我从 Word 中收到错误消息:Word 在“document.docx”中发现不可读的内容。是否要恢复此文档的内容?如果您信任文档的来源,请单击“是”。
【解决方案2】:

斯图尔特,

我在尝试将编号样式从一个文档复制到另一个文档时遇到了同样的问题。

我认为 Word 在内部所做的是,每当一个对象从一个文档复制到另一个文档时,该对象的 ID 不会复制到新文档,而是为其分配一个新 ID。

您必须在复制图像后获取 ID,然后在使用您的图像的任何地方替换它。

我希望这会有所帮助,这就是我使用的副本编号样式。

干杯

【讨论】:

  • 谢谢,但这就是我已经在做的事情 - 使用 FeedData(Stream) 然后获取零件 ID。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2014-09-22
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多