如何使用Open XML SDK将Word文档(docx)中的书签替换为图像?

时间:2015-06-22 19:53:09

标签: c# image ms-word openxml-sdk

我需要使用带有一组书签的模板Word文档,并用图像替换它们(删除书签本身)。使用我已经看过的书签的例子令人困惑,我不确定它们是否适用于使用ImagePart,因为根据内容,情况似乎有所不同。

有人可以提供一个直截了当的例子吗?

2 个答案:

答案 0 :(得分:3)

您可以使用以下方法ReplaceBookmarksWithImage将所有书签替换为给定图像。单词模板文件路径和图像文件路径是参数。如果每个书签需要不同的图像,则可以扩展代码。

    private static void ReplaceBookmarksWithImage(string wordDocTempaltePath, string imageFilename)
    {
        WordprocessingDocument doc = WordprocessingDocument.Open(wordDocTempaltePath, true);

        // Read all bookmarks from the word doc
        foreach (BookmarkStart bookmarkStart in doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
        {
            // insert the image
            InsertImageIntoBookmark(doc, bookmarkStart, imageFilename);

            // remove the bookmark
            bookmarkStart.Remove();
        }

        doc.Close();
    }

    public static void InsertImageIntoBookmark(WordprocessingDocument doc, BookmarkStart bookmarkStart, string imageFilename)
    {
        // Remove anything present inside the bookmark
        OpenXmlElement elem = bookmarkStart.NextSibling();
        while (elem != null && !(elem is BookmarkEnd))
        {
            OpenXmlElement nextElem = elem.NextSibling();
            elem.Remove();
            elem = nextElem;
        }

        // Create an imagepart
        var imagePart = AddImagePart(doc.MainDocumentPart, imageFilename);

        // insert the image part after the bookmark start
        AddImageToBody(doc.MainDocumentPart.GetIdOfPart(imagePart), bookmarkStart);
    }

    public static ImagePart AddImagePart(MainDocumentPart mainPart, string imageFilename)
    {
        ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);

        using (FileStream stream = new FileStream(imageFilename, FileMode.Open))
        {
            imagePart.FeedData(stream);
        }

        return imagePart;
    }

    private static void AddImageToBody(string relationshipId, BookmarkStart bookmarkStart)
    {
        // Define the reference of the image.
        var element =
            new Drawing(
                new DW.Inline(
                    new DW.Extent()
                        {
                            Cx = 990000L,
                            Cy = 792000L
                        },
                    new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L },
                    new DW.DocProperties() { Id = (UInt32Value)1U, Name = "Picture 1" },
                    new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true }),
                    new A.Graphic(
                        new A.GraphicData(
                            new PIC.Picture(
                                new PIC.NonVisualPictureProperties(
                                    new PIC.NonVisualDrawingProperties()
                                        {
                                            Id = (UInt32Value)0U,
                                            Name = "New Bitmap Image.jpg"
                                        },
                                    new PIC.NonVisualPictureDrawingProperties()),
                                new PIC.BlipFill(
                                    new A.Blip(
                                        new A.BlipExtensionList(
                                            new A.BlipExtension()
                                                {
                                                    Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                                }))
                                        {
                                            Embed
                                                =
                                                relationshipId,
                                            CompressionState
                                                =
                                                A
                                                .BlipCompressionValues
                                                .Print
                                        },
                                    new A.Stretch(new A.FillRectangle())),
                                new PIC.ShapeProperties(
                                    new A.Transform2D(new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = 990000L, Cy = 792000L }),
                                    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"
                    });

        // add the image element to body, the element should be in a Run.
        bookmarkStart.Parent.InsertAfter<Run>(new Run(element), bookmarkStart);
    }

以下是使用声明

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml.Packaging;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using A = DocumentFormat.OpenXml.Drawing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;

答案 1 :(得分:0)

我正在尝试放入单词书签,即内存流中的图像而不是图像文件。在标记中,我得到一个带有“X”的图像。

public static ImagePart AddStreamPart(MainDocumentPart mainPart, Stream ImageSignature)
{
    ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
    imagePart.FeedData(ImageSignature);
    return imagePart;
}