在PowerPoint中显示HTML

我的目标:想要在Slide中显示我动态注入主演示文稿的HTML。

到目前为止我所取得的成果:将 Html转换为OpenXML(或更具体的WordML)然后将一个word对象嵌入到PowerPoint中,然后通过OpenXML SDK Productivity Tool分析结构,它创建了包含文档的embeddings文件夹I’选择了,我打开演示文稿时看到的视图基本上是/ppt/media/image.emf中的图像。

现在我已经动态地替换了嵌入式docx的内容,但是如何生成其图像以便我也可以更新视图?

还是有一个无痛的解决方案?

注意:对于WINFORMS C#

好吧,我没有经历你在查询中写下的痛苦描述我相信你已经流下了很多汗水让它起作用,在这里我分享了无痛的解决方案(至少它对我有用)而且我相信它应该也适合你。

创建一个类如下:(我从其他一些SO部分采取此解决方案,抱歉不记得来源)

using System; using System.Text.RegularExpressions; using System.Windows.Forms; public class HtmlFragment { #region Read and decode from clipboard static public HtmlFragment FromClipboard() { string rawClipboardText = Clipboard.GetText(TextDataFormat.Html); HtmlFragment h = new HtmlFragment(rawClipboardText); return h; } ///  /// Create an HTML fragment decoder around raw HTML text from the clipboard. /// This text should have the header. ///  /// raw html text, with header. public HtmlFragment(string rawClipboardText) { // This decodes CF_HTML, which is an entirely text format using UTF-8. // Format of this header is described at: // http://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp // Note the counters are byte counts in the original string, which may be Ansi. So byte counts // may be the same as character counts (since sizeof(char) == 1). // But System.String is unicode, and so byte couns are no longer the same as character counts, // (since sizeof(wchar) == 2). int startHMTL = 0; int endHTML = 0; int startFragment = 0; int endFragment = 0; Regex r; Match m; r = new Regex("([a-zA-Z]+):(.+?)[\r\n]", RegexOptions.IgnoreCase | RegexOptions.Compiled); for (m = r.Match(rawClipboardText); m.Success; m = m.NextMatch()) { string key = m.Groups[1].Value.ToLower(); string val = m.Groups[2].Value; switch(key) { // Version number of the clipboard. Starting version is 0.9. case "version": m_version = val; break; // Byte count from the beginning of the clipboard to the start of the context, or -1 if no context case "starthtml": if (startHMTL != 0) throw new FormatException("StartHtml is already declared"); startHMTL = int.Parse(val); break; // Byte count from the beginning of the clipboard to the end of the context, or -1 if no context. case "endhtml": if (startHMTL == 0) throw new FormatException("StartHTML must be declared before endHTML"); endHTML = int.Parse(val); m_fullText = rawClipboardText.Substring(startHMTL, endHTML - startHMTL); break; // Byte count from the beginning of the clipboard to the start of the fragment. case "startfragment": if (startFragment != 0) throw new FormatException("StartFragment is already declared"); startFragment = int.Parse(val); break; // Byte count from the beginning of the clipboard to the end of the fragment. case "endfragment": if (startFragment == 0) throw new FormatException("StartFragment must be declared before EndFragment"); endFragment = int.Parse(val); m_fragment = rawClipboardText.Substring(startFragment, endFragment - startFragment); break; // Optional Source URL, used for resolving relative links. case "sourceurl": m_source = new System.Uri(val); break; } } // end for if (m_fullText == null && m_fragment == null) { throw new FormatException("No data specified"); } } // Data. See properties for descriptions. string m_version; string m_fullText; string m_fragment; System.Uri m_source; ///  /// Get the Version of the html. Usually something like "1.0". ///  public string Version { get { return m_version; } } ///  /// Get the full text (context) of the HTML fragment. This includes tags that the HTML is enclosed in. /// May be null if context is not specified. ///  public string Context { get { return m_fullText; } } ///  /// Get just the fragment of HTML text. ///  public string Fragment { get { return m_fragment; } } ///  /// Get the Source URL of the HTML. May be null if no SourceUrl is specified. This is useful for resolving relative urls. ///  public System.Uri SourceUrl { get { return m_source; } } #endregion // Read and decode from clipboard #region Write to Clipboard // Helper to convert an integer into an 8 digit string. // String must be 8 characters, because it will be used to replace an 8 character string within a larger string. static string To8DigitString(int x) { return String.Format("{0,8}", x); } ///  /// Clears clipboard and copy a HTML fragment to the clipboard. This generates the header. ///  /// A html fragment. ///  /// HtmlFragment.CopyToClipboard("Hello!"); ///  public static void CopyToClipboard(string htmlFragment) { CopyToClipboard(htmlFragment, null, null); } ///  /// Clears clipboard and copy a HTML fragment to the clipboard, providing additional meta-information. ///  /// a html fragment /// optional title of the HTML document (can be null) /// optional Source URL of the HTML document, for resolving relative links (can be null) public static void CopyToClipboard(string htmlFragment, string title, Uri sourceUrl) { if (title == null) title = "From Clipboard"; System.Text.StringBuilder sb = new System.Text.StringBuilder(); // Builds the CF_HTML header. See format specification here: // http://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp // The string contains index references to other spots in the string, so we need placeholders so we can compute the offsets. // The <<<<<<<_ strings are just placeholders. We'll backpatch them actual values afterwards. // The string layout (<<<) also ensures that it can't appear in the body of the html because the < // character must be escaped. string header = @"Format:HTML Format Version:1.0 StartHTML:<<<<<<<1 EndHTML:<<<<<<<2 StartFragment:<<<<<<<3 EndFragment:<<<<<<<4 StartSelection:<<<<<<<3 EndSelection:<<<<<<<3 "; string pre = @" " + title + @""; string post = @""; sb.Append(header); if (sourceUrl != null) { sb.AppendFormat("SourceURL:{0}", sourceUrl); } int startHTML = sb.Length; sb.Append(pre); int fragmentStart = sb.Length; sb.Append(htmlFragment); int fragmentEnd = sb.Length; sb.Append(post); int endHTML = sb.Length; // Backpatch offsets sb.Replace("<<<<<<<1", To8DigitString(startHTML)); sb.Replace("<<<<<<<2", To8DigitString(endHTML)); sb.Replace("<<<<<<<3", To8DigitString(fragmentStart)); sb.Replace("<<<<<<<4", To8DigitString(fragmentEnd)); // Finally copy to clipboard. string data = sb.ToString(); Clipboard.Clear(); Clipboard.SetText(data, TextDataFormat.Html); } #endregion // Write to Clipboard } 

用法说明如下:

使用PowerPoint = Microsoft.Office.Interop.PowerPoint;

 var oPowerPoint = new PowerPoint.Application(); oPowerPoint.Visible = Microsoft.Office.Core.MsoTriState.msoTrue; 

我需要将内容粘贴到活动幻灯片上,所以我使用了下面的代码,根据您的需要,您的逻辑可能会有所不同,您可以忽略下面的代码行

  var activeSlide = (PowerPoint.Slide)oPowerPoint.ActiveWindow.View.Slide; 

将HTML内容提供给以下方法

 HtmlFragment.CopyToClipboard(HTML CONTENT WILL COME HERE); 

下面的代码会将HTML粘贴到活动幻灯片中

 oPowerPoint.ActiveWindow.View.PasteSpecial(); 

我希望你能找到一些关于你的问题的东西。

有点晚了,但未来的人可能会来这里。

这适用于HTML – > PPT部分。

 PowerPoint.Presentation presentation; presentation = ppApp.Presentations.Open(configuration.PPTTExportedFile, MsoTriState.msoFalse, MsoTriState.msoTrue, MsoTriState.msoTrue); foreach (PowerPoint.Slide slide in presentation.Slides) { foreach (PowerPoint.Shape shape in slide.Shapes) { File.WriteAllText(temporaryFilePath, html); WebsiteToImage websiteToImage = new WebsiteToImage(temporaryFilePath, @"New picture path"); websiteToImage.Generate(); slide.Shapes.AddPicture(@"picture path", MsoTriState.msoTrue, MsoTriState.msoTrue, oldshapeleft, oldshapetop, oldshapewidth, oldshapeheight); fileToDelete.Add(temporaryFilePath); fileToDelete.Add(@""dont forget to remove tmp files"); } } 

将网页转换为ASP.NET中的图像

如果你想在Word / Excel / PowerPoint中进行任何对象操作,我建议使用

 Console.Write("AlternativeText: "); Console.WriteLine(shape.AlternativeText); 

因为如果在原始文件中保存对象中的AlternativeText,则可以快速访问它,甚至可以将PATH更改为简单变量。

如果你想要例如导出一个HTML表格,从中做一个图像并更改AlternativeText以便以后更容易访问它,同时给它一个你可以用第三个软件工具访问的适当名称,因为PowerPoint没有支持HTML标签

接下来做:

 File.Copy(WordTemplateFile, WordExportedFile, true); 

你为什么要改变原作? 只需制作副本,并将其保存为模板,您可以随时更改该模板,同时从中创建新的更改版本。(适用于报告)

如果您打算使用AlternativeText非常有用。

如需更换,可能需要使用NetOffice / Microsoft Office库。

 foreach (NetOffice.WordApi.InlineShape s in docWord.InlineShapes) { if (s.Type==NetOffice.WordApi.Enums.WdInlineShapeType.wdInlineShapePicture && s.AlternativeText.Contains("any pattern you are looking for")) {  s.Range.InsertFile(); } } 

循环遍历所有文件并检查是否符合您的模式。

祝好运。