C#实现导出Word图表通用方法之散点图

 更新时间:2026年01月23日 08:49:01   作者:初九之潜龙勿用  
文章介绍了C#实现数据导出生成Word图表的通用方法,并详细描述了如何处理散点图表的特殊设置,通过将业务数据转化为Json格式并添加查找关键字,可以实现图表的正确呈现,需要的朋友可以参考下

特殊之处

《C#实现数据导出任一Word图表的通用呈现方法及一些体会》一文讲解了数据导出生成 WORD 图表的通用方法, 根据应用需求,大部分的图表(如柱形图)如下设置:

插入后,微缩版 Excel 应用显示了一些通用的数据设置,类别项和系列项的数值,改变其中的项和系列值,图表就会产生相应的变化。  

对于像单一数据来源的,如雷达图:

可以设置必要项,分类和系列1,而不会因为系列2的数据存在而出现错误,WORD会自动“忽略”。但最近在新需求应用中,使用一款散点类型图表时发现了一些问题,其EXCEL数据源如下:

与柱状图、饼状图的格式不同,散点图是 X值和Y值的列名+二维数组设置。但实际的操作实现可能需要进行类似如下的设置:

即模拟去掉列名,直接输出数据,可正常进行显示输出 ,因此我们需要对通用方法进行一些改造。

设计方案

仍遵循原设计方案基础,将业务数据存入一个二维字符串数组,并转化为Json数据格式,并添加一个查找关键字节点,假设为“ t:chart1”。在 Word 模板插入散点图图表,图表的标题设置为Json对应的查找关键字,即“ t:chart1”。最后,读取Word模板文件,遍历模板文件中的图表对象,并按查找关键字与图表的标题进行对比,匹配成功,则将JSON中数组转化为图表需要的EXCEL数组形式,完成图表绘制输出。

经调试,首列单元格需要设置为数字格式,因些增加了Json配置 “ t:chart1_ex ”,例如下代码:

            writer.WritePropertyName("t:chart1_ex");
            writer.WriteStartArray();
            writer.WriteStartObject();
            writer.WritePropertyName("NumberFormat");
            writer.WriteValue("#,##0");
            writer.WriteEndObject();
            writer.WriteEndArray();

为什么用 Json 过渡

我们的云架构里设计了一个 Office 计算中心,在某些环境下,比如 Linux 中需要这种方式传递并返回值,以达到导入导出Office文件的目的。大家可根据实际的应用进行设计,这里仅作为参考。

开发环境

操作系统:Windows Server 2019 DataCenter

开发工具:VisualStudio2019 

框架及语言:.net 4.7.1     C#

服务上需要安装 Office 2016或以上

关键代码实现

假设文件模板中的散点图表如下,关键查找字(图表标题)设为 “ t:chart1”,如下图:

(1)创建Json格式

这里引入 Newtonsoft.Json.dll 程序集进行操作,代码如下:

StringWriter sw = new StringWriter();
        using (Newtonsoft.Json.JsonWriter writer = new Newtonsoft.Json.JsonTextWriter(sw))
        {
            writer.Formatting = Newtonsoft.Json.Formatting.Indented;
            writer.WriteStartObject();

            //t:chart1
            writer.WritePropertyName("t:chart1");
            writer.WriteStartArray();
            //point1
            writer.WriteStartObject();
            writer.WritePropertyName("y");
            writer.WriteValue((int)y);
            writer.WritePropertyName("x");
            writer.WriteValue((int)x);
            writer.WriteEndObject();

            writer.WriteStartObject();
            writer.WriteEndArray();

            writer.WritePropertyName("t:chart1_ex");
            writer.WriteStartArray();
            writer.WriteStartObject();
            writer.WritePropertyName("NumberFormat");
            writer.WriteValue("#,##0");
            writer.WriteEndObject();
            writer.WriteEndArray();

            //t:chart1



            writer.WriteEndObject();
            writer.Flush();
        }
        sw.Close();
        string jsonContent = sw.GetStringBuilder().ToString();

(2)查找图表并设置单元格数字格式

本代码程序只显示示例片断,非完整程序,仅供参考:

////一些引用
using Word=Microsoft.Office.Interop.Word;
using Newtonsoft.Json.Linq;


////转换 json 字符串为 json 对象

Newtonsoft.Json.Linq.JObject jObject = null;
            if (jsonContent != "")
            {
                try
                {
                    jObject = Newtonsoft.Json.Linq.JObject.Parse(jsonContent); //转换为json对象
                }
                catch (Exception e)
                {
                    resultReport += "create json object  fail.<br>";  //失败记入调试报告
                }
            }

////初始化 Word 应用程序

			Word.Application WordApp=new Word.Application();
            
			//创建一个名为WordDoc的文档对象
			WordApp.DisplayAlerts=Word.WdAlertLevel.wdAlertsNone;  //禁止一切提示警告
            //打开 filename 的文件
			Word.Document WordDoc=WordApp.Documents.Open(ref filename,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
            //禁用拼写检查
            WordDoc.SpellingChecked = false;
            WordDoc.ShowSpellingErrors = false;



////遍历word 里的 shapes

for (int i = 1; i <= WordDoc.InlineShapes.Count; i++)
{
  Word.InlineShape shape = WordDoc.InlineShapes[i];  //得到 shape对象
   //遍历 json 对象
  foreach (var item in jObject)
  {
    string tcmd = item.Key.ToString();   //取关键字
    //如果 shape 包含图表,则继续
    if (shape.HasChart == Microsoft.Office.Core.MsoTriState.msoTrue)
    {
        //如果图表未设置标题,则短路
        if (shape.Chart.HasTitle == false)
        {
            continue;
        }
        //获取图表的title
        string _name = shape.Chart.ChartTitle.Text.Trim().ToLower();
        if (_name.IndexOf(tcmd) != -1) //如果包含关键字则继续
        {
            //替换掉关键字,保留下来的是真正的标题
           shape.Chart.ChartTitle.Text = shape.Chart.ChartTitle.Text.Replace(tcmd, "");

            //这是一个玄机,否则会报错,目前我是这样的解决,A1:Z100,先赋值为空串
           shape.Chart.ChartData.Workbook.Worksheets[1].Range("A1:Z100").Value = "";
            //计算最后的单元格地址
           string lastcellAddress = "$" + ((char)(64 + jObject[tcmd][0].Count())).ToString() + "$" + jObject[tcmd].Count().ToString();
           //获得最终地址字串 
           string sourceDataAddress = "='Sheet1'!$A$1:" + lastcellAddress;

           //计算附加配置,设置单元格数字格式字串
           string numberFormat = "#,##0.0";
           if (jObject[_name + "_ex"] != null)
           {
                if (jObject[_name + "_ex"][0]["NumberFormat"] != null)
                {
                  numberFormat = jObject[_name + "_ex"][0]["NumberFormat"].ToString();
                }
           }


           //遍历json对象节点里的数组
           for (int i = 0; i < jObject[tcmd].Count(); i++)
           {
                List<JToken> tokens = jObject[tcmd][i].ToList();
                int k = 0;
                foreach (JToken jToken in tokens)
                {
                  //为每一个单元格赋值

                  string celladdress = ((char)(65 + k)).ToString() + (i + 1).ToString();  
//设置单元格数字格式                             
shape.Chart.ChartData.Workbook.Worksheets[1].Range(celladdress).NumberFormat = numberFormat;
shape.Chart.ChartData.Workbook.Worksheets[1].Range(celladdress).Value = jToken.ToArray()[0].ToString();
                  k++;
                }
           }
           shape.Chart.SetSourceData(sourceDataAddress);  //设置更新图表的数据源
           break;
         } // index of name
      } // has chart

   }//foreach tcmd


} //WordDoc.InlineShapes


小结

图表数据的正确呈现受限于Word的提供能力,需要细心的测试、调试,比如

shape.Chart.ChartData.Workbook.Worksheets[1].Range("A1:Z100").Value = "";  的初始化,散点图首列的设置等。

以上就是C#实现导出Word图表通用方法之散点图的详细内容,更多关于C#导出Word图表的资料请关注脚本之家其它相关文章!

相关文章

  • 使用VS2005自带的混淆器防止你的程序被反编译的方法

    使用VS2005自带的混淆器防止你的程序被反编译的方法

    使用VS2005自带的混淆器防止你的程序被反编译的方法...
    2007-07-07
  • 使用C#实现在word中插入页眉页脚的方法

    使用C#实现在word中插入页眉页脚的方法

    这篇文章主要介绍了使用C#实现在word中插入页眉页脚的方法,是操作Word的常见方法,有一定的学习借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C#中is与as的区别分析

    C#中is与as的区别分析

    这篇文章主要介绍了C#中is与as的区别,较为详细的分析了is与as的原理与特性及用法区别,具有很好的学习借鉴价值,需要的朋友可以参考下
    2014-10-10
  • C# Event Bus事件总线实现

    C# Event Bus事件总线实现

    在C#中实现事件总轴,涵盖事件、发布者与订阅者概念,通过具体代码示例展示在.NET框架中实现事件总轴,提升系统灵活性与扩展性,下面就来详细的介绍一下
    2026-05-05
  • string类的使用方法详解

    string类的使用方法详解

    string类的使用方法详解...
    2006-12-12
  • 基于C#实现屏幕桌面截图

    基于C#实现屏幕桌面截图

    这篇文章主要为大家详细介绍了如何利用C#实现屏幕桌面截图以及左上角区域截图功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以了解一下
    2022-12-12
  • C#给Word不同页面设置不同背景

    C#给Word不同页面设置不同背景

    这篇文章主要介绍了C#给Word不同页面设置不同背景,文章图文讲解的很清晰,有对于这方面不懂得同学可以学习下
    2021-02-02
  • C#异步迭代IAsyncEnumerable应用实现

    C#异步迭代IAsyncEnumerable应用实现

    IAsyncEnumerable可以来实现异步迭代,本文就主要介绍了C#异步迭代IAsyncEnumerable应用实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • 在C#中如何使用JSON

    在C#中如何使用JSON

    JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有易读、易解析的特点,广泛用于API数据交互、配置文件等,本文介绍在C#中如何使用JSON,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • C#简易人机对抗“石头剪刀布”游戏的实现

    C#简易人机对抗“石头剪刀布”游戏的实现

    本文主要介绍了C#简易人机对抗“石头剪刀布”游戏的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05

最新评论