[英]Showing HTML in PowerPoint
我的目標:想要在幻燈片中顯示HTML,並將其動態注入到主演示中。
到目前為止,我已經完成了什么:將 HTML轉換為OpenXML(或更具體地講是WordML),然后將一個Word對象嵌入PowerPoint中,然后通過OpenXML SDK生產率工具分析結構,它創建了embeddings文件夾,其中包含我的文檔選中,打開演示文稿時看到的視圖基本上是/ppt/media/image.emf中的圖像。
現在,我已經動態替換了嵌入式docx的內容,但是如何生成其圖像,以便也可以更新視圖?
還是有無痛的解決方案?
注意:對於WINFORMS C#
好的,我沒有遍歷您在查詢中寫的疼痛描述,我相信您已經付出了很多汗水才能使它起作用,在這里,我分享了無痛解決方案(至少對我有用),我相信應該也為您工作。
創建一個如下所示的類:(我從其他方法中獲得了部分解決方案,對不起,我不記得源代碼了)
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;
}
/// <summary>
/// Create an HTML fragment decoder around raw HTML text from the clipboard.
/// This text should have the header.
/// </summary>
/// <param name="rawClipboardText">raw html text, with header.</param>
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;
/// <summary>
/// Get the Version of the html. Usually something like "1.0".
/// </summary>
public string Version
{
get { return m_version; }
}
/// <summary>
/// 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.
/// </summary>
public string Context
{
get { return m_fullText; }
}
/// <summary>
/// Get just the fragment of HTML text.
/// </summary>
public string Fragment
{
get { return m_fragment; }
}
/// <summary>
/// Get the Source URL of the HTML. May be null if no SourceUrl is specified. This is useful for resolving relative urls.
/// </summary>
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);
}
/// <summary>
/// Clears clipboard and copy a HTML fragment to the clipboard. This generates the header.
/// </summary>
/// <param name="htmlFragment">A html fragment.</param>
/// <example>
/// HtmlFragment.CopyToClipboard("<b>Hello!</b>");
/// </example>
public static void CopyToClipboard(string htmlFragment)
{
CopyToClipboard(htmlFragment, null, null);
}
/// <summary>
/// Clears clipboard and copy a HTML fragment to the clipboard, providing additional meta-information.
/// </summary>
/// <param name="htmlFragment">a html fragment</param>
/// <param name="title">optional title of the HTML document (can be null)</param>
/// <param name="sourceUrl">optional Source URL of the HTML document, for resolving relative links (can be null)</param>
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 =
@"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">
<HTML><HEAD><TITLE>" + title + @"</TITLE></HEAD><BODY><!–StartFragment–>";
string post = @"<!–EndFragment–></BODY></HTML>";
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");
}
}
如果要在Word / Excel / PowerPoint中進行任何對象操作,建議使用
Console.Write("AlternativeText: ");
Console.WriteLine(shape.AlternativeText);
因為如果將原始文本中的AlternativeText保存在對象中,則可以快速訪問它,甚至可以將PATH更改為簡單變量。
並且,例如,如果您要導出HTML表,則可以從中進行圖像處理並更改AlternativeText,以便以后可以更輕松地訪問它,同時為其指定一個適當的名稱,您可以使用第3個軟件工具來訪問它,因為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"))
{
<Do your manipulation with image change it>
s.Range.InsertFile(<insert your new picture for example>);
}
}
您遍歷所有文件,並檢查是否適合您的模式。
祝好運。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.