使用 openXML 与 c# 和 ASP.net 在 powerpoint 中创建动态表

2024-03-19

我已经使用了这些链接并获得了一个工作代码,我可以在其中使用模板报告(包含占位符)并使用从数据库获取的数据生成新的 PPTX 报告。我还有 4 个占位符,需要在其中填充 4 个不同的数据表。目前,我正在使用该模板创建新幻灯片并替换文本的占位符,但对于我无法弄清楚的表格。我可以使用下面的代码生成表格,但不能在占位符的位置生成表格。表格始终出现在屏幕中央。

使用的链接:https://blogs.msdn.microsoft.com/brian_jones/2008/11/18/creating-a-presentation-report-based-on-data/ https://blogs.msdn.microsoft.com/brian_jones/2008/11/18/creating-a-presentation-report-based-on-data/

https://code.msdn.microsoft.com/office/How-to-add-a-table-with-03578dde https://code.msdn.microsoft.com/office/How-to-add-a-table-with-03578dde

从某个按钮单击事件中调用此方法:

 using (PresentationDocument presentationDocument = PresentationDocument.Open(slideName, true))
            {
                //Get the first slide from presentation
                SlidePart intitalSlide = presentationDocument.PresentationPart.SlideParts.First();
                AddNewSlide(presentationDocument, intitalSlide, 1045);
            }

 private void AddNewSlide(PresentationDocument presentationDocument, SlidePart _slideTemplate, int projectID)
    {
        PresentationPart parent = presentationDocument.PresentationPart;

        System.Data.DataTable dt = GetValueForPPTReport(projectID);

        var newSlidePart = parent.AddNewPart<SlidePart>("newSlide1");

        //copy the contents of the template slide to the new slide and attach the appropriate layout
        newSlidePart.FeedData(_slideTemplate.GetStream(FileMode.Open));
        newSlidePart.AddPart(_slideTemplate.SlideLayoutPart, _slideTemplate.GetIdOfPart(_slideTemplate.SlideLayoutPart));

        //Alter the placeholder text in new slide
        SetPlaceholder(newSlidePart, "txtProjectIDName", dt.Rows[0]["projName"].ToString());
        SetPlaceholder(newSlidePart, "txtProjType", dt.Rows[0]["proj_type"].ToString());
        SetPlaceholder(newSlidePart, "txtProbSt", dt.Rows[0]["proj_problem_state"].ToString());
        SetPlaceholder(newSlidePart, "txtGoal", dt.Rows[0]["proj_goal_obj"].ToString());
        SetPlaceholder(newSlidePart, "txtInScope", dt.Rows[0]["proj_in_scope"].ToString());
        SetPlaceholder(newSlidePart, "txtOutOfScope", dt.Rows[0]["proj_out_scope"].ToString());
        SetPlaceholder(newSlidePart, "txtCustomer", dt.Rows[0]["proj_who_customer"].ToString());
        SetPlaceholder(newSlidePart, "txtCTQ", dt.Rows[0]["proj_critical_to_qlty"].ToString());
        SetPlaceholder(newSlidePart, "txtDefect", dt.Rows[0]["proj_what_defect"].ToString());
        SetPlaceholder(newSlidePart, "txtDate", System.DateTime.Now.ToString("MM/dd/yyyy HH:mm"));

        //Add Tables here
        //tblXBenefit
        System.Data.DataTable dtXb = GetValueForPPTReportBenefit(1045);
        string placeholder = "tblXBenefit";
        List<D.Text> textListExif1 = newSlidePart.Slide.Descendants<D.Text>().Where(t => t.Text.Equals(placeholder)).ToList();
        if (textListExif1.Count == 1)
        {

        }

        List<OpenXmlElement> elements = new List<OpenXmlElement>();
        elements.Add(new P.NonVisualGraphicFrameProperties
            (new P.NonVisualDrawingProperties() { Id = 1, Name = "xyz" }, new P.NonVisualGraphicFrameDrawingProperties(), new ApplicationNonVisualDrawingProperties()));

        // Declare and instantiate the graphic Frame of the new slide 
        P.GraphicFrame graphicFrame = newSlidePart.Slide.CommonSlideData.ShapeTree.AppendChild(new P.GraphicFrame());

        // Specify the required Frame properties of the graphicFrame 
        ApplicationNonVisualDrawingPropertiesExtension applicationNonVisualDrawingPropertiesExtension = new ApplicationNonVisualDrawingPropertiesExtension() { Uri = "{D42A27DB-BD31-4B8C-83A1-F6EECF244321}" };
        P14.ModificationId modificationId1 = new P14.ModificationId() { Val = 3229994563U };
        modificationId1.AddNamespaceDeclaration("p14", "http://schemas.microsoft.com/office/powerpoint/2010/main");
        applicationNonVisualDrawingPropertiesExtension.Append(modificationId1);
        graphicFrame.NonVisualGraphicFrameProperties = new P.NonVisualGraphicFrameProperties
        (new D.NonVisualDrawingProperties() { Id = 5, Name = "table 1" },
        new D.NonVisualGraphicFrameDrawingProperties(new D.GraphicFrameLocks() { NoGrouping = true }),
        new ApplicationNonVisualDrawingProperties(new ApplicationNonVisualDrawingPropertiesExtensionList(applicationNonVisualDrawingPropertiesExtension)));


        graphicFrame.Transform = new Transform(new D.Offset() { X = 1650609L, Y = 4343400L }, new D.Extents() { Cx = 6096000L, Cy = 741680L });

        // Specify the Griaphic of the graphic Frame 
        graphicFrame.Graphic = new D.Graphic(new D.GraphicData(GenerateTable()) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/table" });

        //save the changes to the slide
        newSlidePart.Slide.Save();

        //need to assign an id to the new slide and add it to the slideIdList
        //first figure out the largest existing id
        DocumentFormat.OpenXml.Presentation.SlideIdList slideIdList = parent.Presentation.SlideIdList;
        uint maxSlideId = 1;

        foreach (DocumentFormat.OpenXml.Presentation.SlideId slideId in slideIdList.ChildElements)
        {
            if (slideId.Id > maxSlideId) maxSlideId = slideId.Id;
        }

        //assign an id and add the new slide at the end of the list
        DocumentFormat.OpenXml.Presentation.SlideId newSlideId = new DocumentFormat.OpenXml.Presentation.SlideId { Id = ++maxSlideId, RelationshipId = parent.GetIdOfPart(newSlidePart) };
        slideIdList.Append(newSlideId);

        //Delete first template slide 
        SlideId tempSlideId = slideIdList.ChildElements[0] as SlideId;
        slideIdList.RemoveChild(tempSlideId);
    }
    private void SetPlaceholder(SlidePart slidePart, string placeholder, string value)
    {
        List<D.Text> textListExif1 = slidePart.Slide.Descendants<D.Text>().Where(t => t.Text.Equals(placeholder)).ToList();
        foreach (D.Text text in textListExif1)
        {
            text.Text = value;
        }
    }

    #region tables


    /// <summary> 
    /// Generate Table as below order: 
    /// a:tbl(Table) ->a:tr(TableRow)->a:tc(TableCell) 
    /// We can return TableCell object with CreateTextCell method 
    /// and Append the TableCell object to TableRow  
    /// </summary> 
    /// <returns>Table Object</returns> 
    private static D.Table GenerateTable()
    {
        string[,] tableSources = new string[,] { { "name", "age" }, { "Tom", "25" } };

        // Declare and instantiate table  
        D.Table table = new D.Table();


        // Specify the required table properties for the table 
        D.TableProperties tableProperties = new D.TableProperties() { FirstRow = true, BandRow = true };
        D.TableStyleId tableStyleId = new D.TableStyleId();
        tableStyleId.Text = "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}";


        tableProperties.Append(tableStyleId);


        // Declare and instantiate tablegrid and colums 
        D.TableGrid tableGrid1 = new D.TableGrid();
        D.GridColumn gridColumn1 = new D.GridColumn() { Width = 3048000L };
        D.GridColumn gridColumn2 = new D.GridColumn() { Width = 3048000L };


        tableGrid1.Append(gridColumn1);
        tableGrid1.Append(gridColumn2);
        table.Append(tableProperties);
        table.Append(tableGrid1);
        for (int row = 0; row < tableSources.GetLength(0); row++)
        {
            // Instantiate the table row 
            D.TableRow tableRow = new D.TableRow() { Height = 370840L };
            for (int column = 0; column < tableSources.GetLength(1); column++)
            {
                tableRow.Append(CreateTextCell(tableSources.GetValue(row, column).ToString()));
            }


            table.Append(tableRow);
        }
        return table;
    }


    /// <summary> 
    /// Create table cell with the below order: 
    /// a:tc(TableCell)->a:txbody(TextBody)->a:p(Paragraph)->a:r(Run)->a:t(Text) 
    /// </summary> 
    /// <param name="text">Inserted Text in Cell</param> 
    /// <returns>Return TableCell object</returns> 
    private static D.TableCell CreateTextCell(string text)
    {
        if (string.IsNullOrEmpty(text))
        {
            text = string.Empty;
        }

        // Declare and instantiate the table cell  
        // Create table cell with the below order: 
        // a:tc(TableCell)->a:txbody(TextBody)->a:p(Paragraph)->a:r(Run)->a:t(Text) 
        D.TableCell tableCell = new D.TableCell();


        //  Declare and instantiate the text body 
        D.TextBody textBody = new D.TextBody();
        D.BodyProperties bodyProperties = new D.BodyProperties();
        D.ListStyle listStyle = new D.ListStyle();


        D.Paragraph paragraph = new D.Paragraph();
        D.Run run = new D.Run();
        D.RunProperties runProperties = new D.RunProperties() { Language = "en-US", Dirty = false };
        D.Text text2 = new D.Text();
        text2.Text = text;
        run.Append(runProperties);
        run.Append(text2);
        D.EndParagraphRunProperties endParagraphRunProperties = new D.EndParagraphRunProperties() { Language = "en-US", Dirty = false };


        paragraph.Append(run);
        paragraph.Append(endParagraphRunProperties);
        textBody.Append(bodyProperties);
        textBody.Append(listStyle);
        textBody.Append(paragraph);


        D.TableCellProperties tableCellProperties = new D.TableCellProperties();
        tableCell.Append(textBody);
        tableCell.Append(tableCellProperties);


        return tableCell;
    }


    #endregion

好的,我可以通过更改 X 和 Y 的值来将表放置在我想要的任何位置。不确定 Cx 和 Cy 值的作用。这样就可以了

graphicFrame.Transform = new Transform(new D.Offset() { X = 1650609L, Y = 4343400L }, new D.Extents() { Cx = 6096000L, Cy = 741680L });

但现在的新问题是我无法减小字体和表格行高。 我尝试更改此值,但没有任何效果。当我发现时会在这里发布。

 D.TableRow tableRow = new D.TableRow() { Height = 370840L };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 openXML 与 c# 和 ASP.net 在 powerpoint 中创建动态表 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐