2

我的目标:想在幻灯片中显示 HTML,我将其动态注入到主演示文稿中。

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

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

或者有没有无痛的解决方案?

4

2 回答 2

1

注意:对于 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;

    }


    /// <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–&gt;";


        string post = @"<!–EndFragment–&gt;</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();
于 2016-11-17T10:52:41.817 回答
0

我希望您设法找到有关您的问题的一些信息。

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

这是针对 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"))
    {
        <Do your manipulation with image change it>
        s.Range.InsertFile(<insert your new picture for example>);
    }
 }

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

祝你好运。

于 2013-03-25T12:22:25.477 回答