简体   繁体   English

如何使用 OpenXml 2.0 将任何文件类型嵌入到 Microsoft Word 中

[英]How can I embed any file type into Microsoft Word using OpenXml 2.0

I spent a lot of time trying to figure out a good way to embed any file into Microsoft Word using OpenXml 2.0;我花了很多时间试图找出一种使用 OpenXml 2.0 将任何文件嵌入到 Microsoft Word 中的好方法; Office documents are fairly easy but what about other file types such as PDF, TXT, GIF, JPG, HTML, etc.... Office 文档相当简单,但其他文件类型如 PDF、TXT、GIF、JPG、HTML 等呢?...

What is a good way to get this to work for any file type, in C#?在 C# 中,让它适用于任何文件类型的好方法是什么?

Embedding Foreign Objects (PDF, TXT, GIF, etc…) into Microsoft Word using OpenXml 2.0 (Well, in collaboration with COM)使用 OpenXml 2.0(嗯,与 COM 合作)将外来对象(PDF、TXT、GIF 等)嵌入到 Microsoft Word 中

I got a lot from this site, so here I asked and answered my own question in order to give back a little on a topic in which I had difficulty finding answers on, hope it helps people.我从这个网站上得到了很多,所以在这里我提出并回答了我自己的问题,以便对我难以找到答案的主题有所回馈,希望它可以帮助人们。

There are several examples out there that show how to embed an Office Document into another Office Document using OpenXml 2.0, what's not out there and easily understandable is how to embed just about any file into and Office Document.有几个示例展示了如何使用 OpenXml 2.0 将 Office 文档嵌入到另一个 Office 文档中,但不存在且易于理解的是如何将几乎任何文件嵌入到 Office 文档中。

I have learned a lot from other people's code, so this is my attempt to contribute.我从其他人的代码中学到了很多东西,所以这是我的贡献。 Since I am already using OpenXml to generate documents, and I am in need of embedding other files into Word, I have decided use a collaboration of OpenXml and COM (Microsoft Office 2007 dll's) to achieve my goal.由于我已经在使用 OpenXml 生成文档,并且我需要将其他文件嵌入到 Word 中,因此我决定使用 OpenXml 和 COM(Microsoft Office 2007 dll)的协作来实现我的目标。 If you are like me, “invoking the OLE server application to create an IStorage” doesn't mean much to you.如果您像我一样,“调用 OLE 服务器应用程序来创建 IStorage”对您来说意义不大。

In this example I'd like to show how I use COM to PROGRMATICALLY get the OLE-binary data information of the attached file, and then how I used that information within my OpenXml document.在这个例子中,我想展示我如何使用 COM 以编程方式获取附件的 OLE 二进制数据信息,然后我如何在我的 OpenXml 文档中使用该信息。 Basically, I am programmatically looking at the OpenXml 2.0 Document Reflector to get the information I need.基本上,我以编程方式查看 OpenXml 2.0 文档反射器以获取我需要的信息。

My code below is broken down into several classes, but here is an outline of what I am doing:我下面的代码分为几个类,但这里是我在做什么的大纲:

  1. Create an OpenXml WordProcessingDocument, get the System.IO.FileInfo for the file you want to Embed创建一个 OpenXml WordProcessingDocument,获取要嵌入的文件的 System.IO.FileInfo
  2. Create a custom OpenXmlEmbeddedObject object (this is what holds all the binary data)创建一个自定义 OpenXmlEmbeddedObject 对象(这是保存所有二进制数据的内容)
  3. Use the binary data from the above step to create Data and Image Streams使用上述步骤中的二进制数据创建数据和图像流
  4. Use those Streams as the File Object and File Image for your OpenXml Document将这些流用作 OpenXml 文档的文件对象和文件图像

I know there is a lot of code, and not much explanation… Hopefully it is easy to follow and will help people out 我知道有很多代码,并没有太多解释......希望它很容易理解并且可以帮助人们 

Requirements: • DocumentFormat.OpenXml dll (OpenXml 2.0) • WindowsBase dll • Microsoft.Office.Interop.Word dll (Office 2007 – version 12)要求: • DocumentFormat.OpenXml dll (OpenXml 2.0) • WindowsBase dll • Microsoft.Office.Interop.Word dll(Office 2007 – 版本 12)

• This the main class that starts everything, opens a WordProcessingDocument and class to have the file attached • 这是启动一切的主类,打开 WordProcessingDocument 和类以附加文件

using DocumentFormat.OpenXml.Packaging;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;

public class MyReport
{
    private MainDocumentPart _mainDocumentPart;

    public void CreateReport()
    {
        using (WordprocessingDocument wpDocument = WordprocessingDocument.Create(@"TempPath\MyReport.docx", WordprocessingDocumentType.Document))
        {
            _mainDocumentPart = wpDocument.AddMainDocumentPart();
            _mainDocumentPart.Document = new Document(new Body());

            AttachFile(@"MyFilePath\MyFile.pdf", true);
        }
    }

    private void AttachFile(string filePathAndName, bool displayAsIcon)
    {
        FileInfo fileInfo = new FileInfo(filePathAndName);

        OpenXmlHelper.AppendEmbeddedObject(_mainDocumentPart, fileInfo, displayAsIcon);
    }
}

• This class in an OpenXml helper class, holds all the logic to embed an object into your OpenXml File • OpenXml 助手类中的此类,包含将对象嵌入 OpenXml 文件的所有逻辑

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Validation;
using DocumentFormat.OpenXml.Wordprocessing;
using OVML = DocumentFormat.OpenXml.Vml.Office;
using V = DocumentFormat.OpenXml.Vml;

public class OpenXmlHelper
{
    /// <summary>
    /// Appends an Embedded Object into the specified Main Document
    /// </summary>
    /// <param name="mainDocumentPart">The MainDocument Part of your OpenXml Word Doc</param>
    /// <param name="fileInfo">The FileInfo object associated with the file being embedded</param>
    /// <param name="displayAsIcon">Whether or not to display the embedded file as an Icon (Otherwise it will display a snapshot of the file)</param>
    public static void AppendEmbeddedObject(MainDocumentPart mainDocumentPart, FileInfo fileInfo, bool displayAsIcon)
    {
        OpenXmlEmbeddedObject openXmlEmbeddedObject = new OpenXmlEmbeddedObject(fileInfo, displayAsIcon);

        if (!String.IsNullOrEmpty(openXmlEmbeddedObject.OleObjectBinaryData))
        {
            using (Stream dataStream = new MemoryStream(Convert.FromBase64String(openXmlEmbeddedObject.OleObjectBinaryData)))
            {
                if (!String.IsNullOrEmpty(openXmlEmbeddedObject.OleImageBinaryData))
                {
                    using (Stream emfStream = new MemoryStream(Convert.FromBase64String(openXmlEmbeddedObject.OleImageBinaryData)))
                    {
                        string imagePartId = GetUniqueXmlItemID();
                        ImagePart imagePart = mainDocumentPart.AddImagePart(ImagePartType.Emf, imagePartId);

                        if (emfStream != null)
                        {
                            imagePart.FeedData(emfStream);
                        }

                        string embeddedPackagePartId = GetUniqueXmlItemID();

                        if (dataStream != null)
                        {
                            if (openXmlEmbeddedObject.ObjectIsOfficeDocument)
                            {
                                EmbeddedPackagePart embeddedObjectPart = mainDocumentPart.AddNewPart<EmbeddedPackagePart>(
                                    openXmlEmbeddedObject.FileContentType, embeddedPackagePartId);
                                embeddedObjectPart.FeedData(dataStream);
                            }
                            else
                            {
                                EmbeddedObjectPart embeddedObjectPart = mainDocumentPart.AddNewPart<EmbeddedObjectPart>(
                                    openXmlEmbeddedObject.FileContentType, embeddedPackagePartId);
                                embeddedObjectPart.FeedData(dataStream);
                            }
                        }

                        if (!displayAsIcon && !openXmlEmbeddedObject.ObjectIsPicture)
                        {
                            Paragraph attachmentHeader = CreateParagraph(String.Format("Attachment: {0} (Double-Click to Open)", fileInfo.Name));
                            mainDocumentPart.Document.Body.Append(attachmentHeader);
                        }

                        Paragraph embeddedObjectParagraph = GetEmbeededObjectParagraph(openXmlEmbeddedObject.FileType,
                            imagePartId, openXmlEmbeddedObject.OleImageStyle, embeddedPackagePartId);

                        mainDocumentPart.Document.Body.Append(embeddedObjectParagraph);
                    }
                }
            }
        }
    }

    /// <summary>
    /// Gets Paragraph that includes the embedded object
    /// </summary>
    private static Paragraph GetEmbeededObjectParagraph(string fileType, string imageID, string imageStyle, string embeddedPackageID)
    {
        EmbeddedObject embeddedObject = new EmbeddedObject();

        string shapeID = GetUniqueXmlItemID();
        V.Shape shape = new V.Shape() { Id = shapeID, Style = imageStyle };
        V.ImageData imageData = new V.ImageData() { Title = "", RelationshipId = imageID };

        shape.Append(imageData);
        OVML.OleObject oleObject = new OVML.OleObject()
        {
            Type = OVML.OleValues.Embed,
            ProgId = fileType,
            ShapeId = shapeID,
            DrawAspect = OVML.OleDrawAspectValues.Icon,
            ObjectId = GetUniqueXmlItemID(),
            Id = embeddedPackageID
        };

        embeddedObject.Append(shape);
        embeddedObject.Append(oleObject);

        Paragraph paragraphImage = new Paragraph();

        Run runImage = new Run(embeddedObject);
        paragraphImage.Append(runImage);

        return paragraphImage;
    }

    /// <summary>
    /// Gets a Unique ID for an XML Item, for reference purposes
    /// </summary>
    /// <returns>A GUID string with removed dashes</returns>
    public static string GetUniqueXmlItemID()
    {
        return "r" + System.Guid.NewGuid().ToString().Replace("-", "");
    }

    private static Paragraph CreateParagraph(string paragraphText)
    {
        Paragraph paragraph = new Paragraph();
        ParagraphProperties paragraphProperties = new ParagraphProperties();

        paragraphProperties.Append(new Justification()
        {
            Val = JustificationValues.Left
        });

        paragraphProperties.Append(new SpacingBetweenLines()
        {
            After = Convert.ToString(100),
            Line = Convert.ToString(100),
            LineRule = LineSpacingRuleValues.AtLeast
        });

        Run run = new Run();
        RunProperties runProperties = new RunProperties();

        Text text = new Text();

        if (!String.IsNullOrEmpty(paragraphText))
        {
            text.Text = paragraphText;
        }

        run.Append(runProperties);
        run.Append(text);

        paragraph.Append(paragraphProperties);
        paragraph.Append(run);

        return paragraph;
    }

}

• This is the most important part of this process, it is using Microsoft's internal OLE Server, creates the Binary DATA and Binary EMF information for a file. • 这是此过程中最重要的部分,它使用 Microsoft 的内部 OLE 服务器,为文件创建二进制数据和二进制 EMF 信息。 All you have to here is call the OpenXmlEmbeddedObject constructor and all get's taken care of.您所要做的就是调用 OpenXmlEmbeddedObject 构造函数,一切都将得到处理。 It will mimic the process that goes on when you manually drag any file into Word;它将模仿您手动将任何文件拖入 Word 时的过程; there is some kind of conversion that goes on when you do that, turning the file into an OLE object, so that Microsoft can recognize the file.执行此操作时会进行某种转换,将文件转换为 OLE 对象,以便 Microsoft 可以识别该文件。 o The most imporant parts of this class are the OleObjectBinaryData and OleImageBinaryData properties; o 这个类中最重要的部分是 OleObjectBinaryData 和 OleImageBinaryData 属性; they contain the 64Bit string binary info for the file data and '.emf' image.它们包含文件数据和“.emf”图像的 64 位字符串二进制信息。 o If you choose to not display the file as an icon, then the '.emf' image data will create a snapshot of the file, like the first page of the pdf file for example, in which you can still double-click to open o If you are embedding an image and choose not to display it as an Icon, then the OleObjectBinaryData and OleImageBinaryData properties will be the same o 如果您选择不将文件显示为图标,则 '.emf' 图像数据将创建文件的快照,例如 pdf 文件的第一页,您仍然可以在其中双击打开o 如果您要嵌入图像并选择不将其显示为图标,则 OleObjectBinaryData 和 OleImageBinaryData 属性将相同

using System.Runtime.InteropServices;
using System.Xml;
using System.Diagnostics;
using System.IO;
using System.Drawing;
using Microsoft.Office.Interop.Word;

public class OpenXmlEmbeddedObject
{
    #region Constants

    private const string _defaultOleContentType = "application/vnd.openxmlformats-officedocument.oleObject";
    private const string _oleObjectDataTag = "application/vnd";
    private const string _oleImageDataTag = "image/x-emf";

    #endregion Constants

    #region Member Variables

    private static FileInfo _fileInfo;
    private static string _filePathAndName;
    private static bool _displayAsIcon;
    private static bool _objectIsPicture;

    private object _objectMissing = System.Reflection.Missing.Value;
    private object _objectFalse = false;
    private object _objectTrue = true;

    #endregion Member Variables

    #region Properties

    /// <summary>
    /// The File Type, as stored in Registry (Ex: a GIF Image = 'giffile')
    /// </summary>
    public string FileType
    {
        get
        {
            if (String.IsNullOrEmpty(_fileType) && _fileInfo != null)
            {
                _fileType = GetFileType(_fileInfo, false);
            }

            return _fileType;
        }
    }
    private string _fileType;

    /// <summary>
    /// The File Context Type, as storered in Registry (Ex: a GIF Image = 'image/gif')
    /// * Is converted into the 'Default Office Context Type' for non-office files
    /// </summary>
    public string FileContentType
    {
        get
        {
            if (String.IsNullOrEmpty(_fileContentType) && _fileInfo != null)
            {
                _fileContentType = GetFileContentType(_fileInfo);

                if (!_fileContentType.Contains("officedocument"))
                {
                    _fileContentType = _defaultOleContentType;
                }
            }

            return _fileContentType;
        }
    }
    private string _fileContentType;

    /// <summary>
    /// Gets the ContentType Text for the file
    /// </summary>
    public static string GetFileContentType(FileInfo fileInfo)
    {
        if (fileInfo == null)
        {
            throw new ArgumentNullException("fileInfo");
        }

        string mime = "application/octetstream";

        string ext = System.IO.Path.GetExtension(fileInfo.Name).ToLower(); 

        Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);

        if (rk != null && rk.GetValue("Content Type") != null)
        {
            mime = rk.GetValue("Content Type").ToString();
        }

        return mime;
    }

    public bool ObjectIsOfficeDocument
    {
        get { return FileContentType != _defaultOleContentType; }
    }

    public bool ObjectIsPicture
    {
        get { return _objectIsPicture; }
    }

    public string OleObjectBinaryData
    {
        get { return _oleObjectBinaryData; }
        set { _oleObjectBinaryData = value; }
    }
    private string _oleObjectBinaryData;

    public string OleImageBinaryData
    {
        get { return _oleImageBinaryData; }
        set { _oleImageBinaryData = value; }
    }
    private string _oleImageBinaryData;

    /// <summary>
    /// The OpenXml information for the Word Application that is created (Make-Shoft Code Reflector)
    /// </summary>
    public string WordOpenXml
    {
        get { return _wordOpenXml; }
        set { _wordOpenXml = value; }
    }
    private String _wordOpenXml;

    /// <summary>
    /// The XmlDocument that is created based on the OpenXml Data from WordOpenXml
    /// </summary>
    public XmlDocument OpenXmlDocument
    {
        get
        {
            if (_openXmlDocument == null && !String.IsNullOrEmpty(WordOpenXml))
            {
                _openXmlDocument = new XmlDocument();
                _openXmlDocument.LoadXml(WordOpenXml);
            }

            return _openXmlDocument;
        }
    }
    private XmlDocument _openXmlDocument;

    /// <summary>
    /// The XmlNodeList, for all Nodes containing 'binaryData'
    /// </summary>
    public XmlNodeList BinaryDataXmlNodesList
    {
        get
        {
            if (_binaryDataXmlNodesList == null && OpenXmlDocument != null)
            {
                _binaryDataXmlNodesList = OpenXmlDocument.GetElementsByTagName("pkg:binaryData");
            }

            return _binaryDataXmlNodesList;
        }
    }
    private XmlNodeList _binaryDataXmlNodesList;

    /// <summary>
    /// Icon Object for the file
    /// </summary>
    public Icon ObjectIcon
    {
        get
        {
            if (_objectIcon == null)
            {
                _objectIcon = Enterprise.Windows.Win32.Win32.GetLargeIcon(_filePathAndName);
            }

            return _objectIcon;
        }
    }
    private Icon _objectIcon;

    /// <summary>
    /// File Name for the Icon being created
    /// </summary>
    public string ObjectIconFile
    {
        get
        {
            if (String.IsNullOrEmpty(_objectIconFile))
            {
                _objectIconFile = String.Format("{0}.ico", _filePathAndName.Replace(".", ""));
            }

            return _objectIconFile;
        }
    }
    private string _objectIconFile;

    /// <summary>
    /// Gets the original height and width of the emf file being created
    /// </summary>
    public string OleImageStyle
    {
        get
        {
            if (String.IsNullOrEmpty(_oleImageStyle) && !String.IsNullOrEmpty(WordOpenXml))
            {
                XmlNodeList xmlNodeList = OpenXmlDocument.GetElementsByTagName("v:shape");
                if (xmlNodeList != null && xmlNodeList.Count > 0)
                {
                    foreach (XmlAttribute attribute in xmlNodeList[0].Attributes)
                    {
                        if (attribute.Name == "style")
                        {
                            _oleImageStyle = attribute.Value;
                        }
                    }
                }
            }

            return _oleImageStyle;
        }

        set { _oleImageStyle = value; }
    }
    private string _oleImageStyle;

    #endregion Properties

    #region Constructor

    /// <summary>
    /// Generates binary information for the file being passed in
    /// </summary>
    /// <param name="fileInfo">The FileInfo object for the file to be embedded</param>
    /// <param name="displayAsIcon">Whether or not to display the file as an Icon (Otherwise it will show a snapshot view of the file)</param>
    public OpenXmlEmbeddedObject(FileInfo fileInfo, bool displayAsIcon)
    {
        _fileInfo = fileInfo;
        _filePathAndName = fileInfo.ToString();
        _displayAsIcon = displayAsIcon;

        SetupOleFileInformation();
    }

    #endregion Constructor

    #region Methods

    /// <summary>
    /// Creates a temporary Word App in order to add an OLE Object, get's the OpenXML data from the file (similar to the Code Reflector info)
    /// </summary>
    private void SetupOleFileInformation()
    {
        Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application();

        Microsoft.Office.Interop.Word.Document wordDocument = wordApplication.Documents.Add(ref _objectMissing, ref _objectMissing,
            ref _objectMissing, ref _objectMissing);

        object iconObjectFileName = _objectMissing;
        object objectClassType = FileType;
        object objectFilename = _fileInfo.ToString();

        Microsoft.Office.Interop.Word.InlineShape inlineShape = null;

        if (_displayAsIcon)
        {
            if (ObjectIcon != null)
            {
                using (FileStream iconStream = new FileStream(ObjectIconFile, FileMode.Create))
                {
                    ObjectIcon.Save(iconStream);
                    iconObjectFileName = ObjectIconFile;
                }
            }

            object objectIconLabel = _fileInfo.Name;

            inlineShape = wordDocument.InlineShapes.AddOLEObject(ref objectClassType,
                ref objectFilename, ref _objectFalse, ref _objectTrue, ref iconObjectFileName,
                ref _objectMissing, ref objectIconLabel, ref _objectMissing);
        }
        else
        {
            try
            {
                Image image = Image.FromFile(_fileInfo.ToString());
                _objectIsPicture = true;
                OleImageStyle = String.Format("height:{0}pt;width:{1}pt", image.Height, image.Width);

                wordDocument.InlineShapes.AddPicture(_fileInfo.ToString(), ref _objectMissing, ref _objectTrue, ref _objectMissing);
            }
            catch
            {
                inlineShape = wordDocument.InlineShapes.AddOLEObject(ref objectClassType,
                    ref objectFilename, ref _objectFalse, ref _objectFalse, ref _objectMissing, ref _objectMissing,
                    ref _objectMissing, ref _objectMissing);
            }
        }

        WordOpenXml = wordDocument.Range(ref _objectMissing, ref _objectMissing).WordOpenXML;

        if (_objectIsPicture)
        {
            OleObjectBinaryData = GetPictureBinaryData();
            OleImageBinaryData = GetPictureBinaryData();
        }
        else
        {
            OleObjectBinaryData = GetOleBinaryData(_oleObjectDataTag);
            OleImageBinaryData = GetOleBinaryData(_oleImageDataTag);
        }

        // Not sure why, but Excel seems to hang in the processes if you attach an Excel file…
        // This kills the excel process that has been started < 15 seconds ago (so not to kill the user's other Excel processes that may be open)
        if (FileType.StartsWith("Excel"))
        {
            Process[] processes = Process.GetProcessesByName("EXCEL");
            foreach (Process process in processes)
            {
                if (DateTime.Now.Subtract(process.StartTime).Seconds <= 15)
                {
                    process.Kill();
                    break;
                }
            }
        }

        wordDocument.Close(ref _objectFalse, ref _objectMissing, ref _objectMissing);
        wordApplication.Quit(ref _objectMissing, ref _objectMissing, ref _objectMissing);
    }

    /// <summary>
    /// Gets the binary data from the Xml File that is associated with the Tag passed in
    /// </summary>
    /// <param name="binaryDataXmlTag">the Tag to look for in the OpenXml</param>
    /// <returns></returns>
    private string GetOleBinaryData(string binaryDataXmlTag)
    {
        string binaryData = null;
        if (BinaryDataXmlNodesList != null)
        {
            foreach (XmlNode xmlNode in BinaryDataXmlNodesList)
            {
                if (xmlNode.ParentNode != null)
                {
                    foreach (XmlAttribute attr in xmlNode.ParentNode.Attributes)
                    {
                        if (String.IsNullOrEmpty(binaryData) && attr.Value.Contains(binaryDataXmlTag))
                        {
                            binaryData = xmlNode.InnerText;
                            break;
                        }
                    }
                }
            }
        }

        return binaryData;
    }

    /// <summary>
    /// Gets the image Binary data, if the file is an image
    /// </summary>
    /// <returns></returns>
    private string GetPictureBinaryData()
    {
        string binaryData = null;
        if (BinaryDataXmlNodesList != null)
        {
            foreach (XmlNode xmlNode in BinaryDataXmlNodesList)
            {
                binaryData = xmlNode.InnerText;
                break;
            }
        }

        return binaryData;
    }

    /// <summary>
    /// Gets the file type description ("Application", "Text Document", etc.) for the file.
    /// </summary>
    /// <param name="fileInfo">FileInfo containing extention</param>
    /// <returns>Type Description</returns>
    public static string GetFileType(FileInfo fileInfo, bool returnDescription)
    {
        if (fileInfo == null)
        {
            throw new ArgumentNullException("fileInfo");
        }

        string description = "File";
        if (string.IsNullOrEmpty(fileInfo.Extension))
        {
            return description;
        }
        description = string.Format("{0} File", fileInfo.Extension.Substring(1).ToUpper());
        RegistryKey typeKey = Registry.ClassesRoot.OpenSubKey(fileInfo.Extension);
        if (typeKey == null)
        {
            return description;
        }
        string type = Convert.ToString(typeKey.GetValue(string.Empty));
        RegistryKey key = Registry.ClassesRoot.OpenSubKey(type);
        if (key == null)
        {
            return description;
        }

        if (returnDescription)
        {
            description = Convert.ToString(key.GetValue(string.Empty));
            return description;
        }
        else
        {
            return type;
        }
    }

    #endregion Methods
}
 _objectIcon = Enterprise.Windows.Win32.Win32.GetLargeIcon(_filePathAndName); 

seems to be broken, but好像坏了,但是

_objectIcon = System.Drawing.Icon.ExtractAssociatedIcon(_filePathAndName);

should also work.也应该工作。

在这里的回答将告诉您如何执行此操作,但不会展示SDK 或特定语言。

This is a great answer and it helped me a lot, but the potential bug that user bic mentioned also exists这是一个很好的答案,对我帮助很大,但用户 bic 提到的潜在错误也存在

in

OpenXmlEmbeddedObject(FileInfo fileInfo, bool displayAsIcon)

at line 242,在第 242 行,

_filePathAndName = fileInfo.ToString();

in

SetupOleFileInformation()

at line 264,在第 264 行,

 object objectFilename = _fileInfo.ToString();

line 289, and第 289 行,以及

Image image = Image.FromFile(_fileInfo.ToString());

line 293第 293 行

wordDocument.InlineShapes.AddPicture(_fileInfo.toString(), ref _objectMissing, ref _objectTrue, ref _objectMissing);

All of these need to be "FullName" instead of "ToString()" if the code should work with relative paths as well.如果代码也应该使用相对路径,所有这些都需要是“FullName”而不是“ToString()”。 Hope this helps anyone who wants to use D Lyonnais's code!希望这可以帮助任何想要使用 D Lyonnais 代码的人!

Make a copy of the document how you wanted to get through code and then use Open XML SDK Tool 2.5 for Microsoft Office for writing code.复制您希望如何通过代码获取文档,然后使用 Open XML SDK Tool 2.5 for Microsoft Office 编写代码。 This tool reflects code.这个工具反映了代码。 which you can simply copy paste.您可以简单地复制粘贴。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM