Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Drawing.Image插入WordprocessingDocument正文_C#_.net_Openxml_System.drawing_Memorystream - Fatal编程技术网

C# 将Drawing.Image插入WordprocessingDocument正文

C# 将Drawing.Image插入WordprocessingDocument正文,c#,.net,openxml,system.drawing,memorystream,C#,.net,Openxml,System.drawing,Memorystream,我有一个代码,当我用System.IO读取字节数组格式的docx文档时。 稍后,我创建一个docx字节数组流,并使用WordprocessingDocument编辑docx流 我编辑/替换docx流文本中使用硬括号和自定义插入文本的标记 最后,我将编辑好的docx流转换成一个新的字节数组,稍后我会将它用于其他东西(比如使用字节数组创建PDF),但之后发生的事情现在并不重要 现在的问题是,就像我在文本中替换某些标记一样,我可以插入图像吗?最好使用Drawing.Image,因为这就是我现在的图像格

我有一个代码,当我用System.IO读取字节数组格式的docx文档时。 稍后,我创建一个docx字节数组流,并使用WordprocessingDocument编辑docx流

我编辑/替换docx流文本中使用硬括号和自定义插入文本的标记

最后,我将编辑好的docx流转换成一个新的字节数组,稍后我会将它用于其他东西(比如使用字节数组创建PDF),但之后发生的事情现在并不重要

现在的问题是,就像我在文本中替换某些标记一样,我可以插入图像吗?最好使用Drawing.Image,因为这就是我现在的图像格式

要明确一些观点:

我知道我可以使用Drawing.image.save()保存图像,然后用
编辑[image]标记,这是一个非常简单的解决方案

但是。如果我能避免保存不必要的文件和依赖链接(这不是图像消失时最稳定的链接),我会更愿意这样做

但为了避免追击,以下是我目前使用的代码:

Image image = myImage;
byte[] byteArray = System.IO.File.ReadAllBytes(fullFileNamePath); //Get our docx document as Byte Array
byte[] byteArrayAfterReading;
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length); //Create a stream of the docx byte array document
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
    {
       Body body = wordDoc.MainDocumentPart.Document.Body;
       foreach (var text in body.Descendants<Text>())
       {
           if (text.Text.Contains("[TEST]"))
           {
               text.Text = text.Text.Replace("[TEST]", "Test text here!");
           }
           if (text.Text.Contains("[IMAGE]"))
           {
               text.Text = text.Text.Replace("[IMAGE]", "Image here!"); 
               //Here I should somehowly insert my Drawing.Image
               //I could do this here but would prefer to not 
               //text.Text = text.Text.Replace("[IMAGE]", "<img href='imgurl.png'>"); 
           }
       }
    }
byteArrayAfterReading = stream.ToArray();
}
//After here I do my convert byte array to PDF and save it
Image=myImage;
byte[]byteArray=System.IO.File.ReadAllBytes(fullFileNamePath)//以字节数组的形式获取docx文档
字节[]ByteArrayReading后;
使用(MemoryStream stream=new MemoryStream())
{
Write(byteArray,0,(int)byteArray.Length);//创建docx字节数组文档的流
使用(WordprocessingDocument wordDoc=WordprocessingDocument.Open(stream,true))
{
Body Body=wordDoc.MainDocumentPart.Document.Body;
foreach(body.subjects()中的var text)
{
if(text.text.Contains(“[TEST]”)
{
text.text=text.text.Replace(“[测试]”,“在此处测试文本!”);
}
if(text.text.Contains(“[IMAGE]”)
{
text.text=text.text.Replace(“[IMAGE]”,“[IMAGE here!”);
//我应该在这里插入我的画
//我可以在这里做这件事,但我不愿意
//text.text=text.text.Replace(“[图像]”,”);
}
}
}
byteArrayAfterReading=stream.ToArray();
}
//在此之后,我将字节数组转换为PDF并保存它
所有这些都非常有效。我只是想想出一个好办法,把我的图像插入其中

tl;博士

我有一个Drawing.Image,我想在我的wordprocessingDocument.Document.Body中插入一个特定字符串,我更愿意这样做,而不使用指向url的html img链接

要更新此信息:

比尔回答,这基本上是一个MSDN链接显示如何插入一个图像,这是伟大的作品。但是,它遗漏了一些部分,如:

  • 如何将图像放置在某个位置,在本例中是我的[image]标记?(最重要)

  • 我希望不必在本地保存我的绘图.Image,以便使用
    'FileStream(fileName,FileMode.Open))
    ,也就是说,有没有一种方法可以让我直接使用绘图.Image而不用先保存它?(不重要,但希望如此)

  • 在MSDN示例中,我的图像分辨率和纵横比发生了变化,原因是什么?(目前不太重要,但将来可能会如此)


  • word文档只不过是一堆放在一起的XML文件。获取一个现有的.docx文件,将其重命名为.zip,然后查看其中的内容。您将看到图像是如何存储的、主文档、定义的样式以及其他各种好东西。要添加图像,您需要找到文档中要添加图像的“部分”。一旦找到,就很容易将图像“part”添加到父“part”中

    以下是MSDN的快速操作指南:

    AddImageToBody如下所示:

    private static void AddImageToBody(WordprocessingDocument wordDoc, string relationshipId)
    {
        // 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" });
    
       // Append the reference to body, the element should be in a Run.
       wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph(new Run(element)));
    }
    

    这里的关键部分是知道如何找到要插入图像的父“部件”的ID

    您是否考虑过使用图片内容控件而不是
    [IMAGE]
    文本?您可以在Word文件中将其放置在任何位置,给它一个“标记”来标识它,然后在代码中访问它的
    SdtContent
    ,并根据需要对其进行操作

    您仍然需要使用以下方法将新的替换图像添加到Word文档中:

    MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
    ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
    using (FileStream stream = new FileStream(fileName, FileMode.Open))
    {
        imagePart.FeedData(stream);
    }
    

    就像比尔的回答一样,但是你不需要经历创建一个绘图的麻烦。只需将现有的
    Blip
    Embed
    属性替换为新添加的图像id。

    应该有一种方法。让我来看看图像是如何存储在文档中的,我没有下载图像,只是一个绘图。图像,这如何替换标记?如果我使用下载的图像和提供的代码,它会破坏图像的高度/宽度和纵横比。将图像转换为内存流,并将其输入到示例中的.FeedData方法中。
    MainDocumentPart mainPart = wordprocessingDocument.MainDocumentPart;
    ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
    using (FileStream stream = new FileStream(fileName, FileMode.Open))
    {
        imagePart.FeedData(stream);
    }