zoukankan      html  css  js  c++  java
  • Excel导出插件-VSTO

    前言

    一个游戏通常需要10多个Excel表格或者更多来配置,一般会通过导出csv格式读取配置。

    本文提供导出Excel直接生成c#文件,对应数据直接生成结构体和数组,方便开发排错和简化重复写每个表格的读取配置方法。

    导出效果

                      

    上图左图为Excel表格数据,右图 为导出生成的cs文件。

    ExcelAddIn工程

      官方文档:https://msdn.microsoft.com/en-us/library/jj620922.aspx

    项目环境配置(VS2015配置):

      1、根据博客The Visual Studio Blog VS2015需要下载一个Update,其他的VS版本没试过。

      2、Microsoft Visual Studio Tools for Applications 2015 SDK

      3、Visual Studio 2010 Tools for Office Runtime 

    依次安装上述SDK,重启VS后新建项目看到可以创建Excel的外接程序了。如下图:

    为了在加载项显示对应的按钮图标,需要在项目工程上右键->添加->选择功能区窗口,如下图:

    在窗口界面中通过可视化界面可以直接编辑对应的点击按钮功能等。

    导出模板

           为了方便导出数据配置,在项目中添加一个App.config:

    配置如下:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <appSettings>
        <add key="template" value="//
    //  #SHEET_NAME#   表格名
    //
    //  #PARAM_DEF# 定义结构体参数
    //  #DATA_DEF#  初始化表格数据
    //  #PAIR_DEF# 定义每个参数数据 需要在#DATA_DEF#定义内
    using System;
    public struct ES_#SHEET_NAME#
    {
        #PARAM_DEF#
        public {0} {1};
        #PARAM_END#
    };
    
    public partial class  ESSheet
    {
        private static ES_#SHEET_NAME#[] _#SHEET_NAME# = null;
        public static ES_#SHEET_NAME#[] F#SHEET_NAME#
        {
            get
            {
                if (_#SHEET_NAME#==null)
                {
                    _#SHEET_NAME# = new ES_#SHEET_NAME#[] 
                    { 
                       #DATA_DEF# new ES_#SHEET_NAME# { #PAIR_DEF#{0}={1}#PAIR_END# }, #DATA_END#
                    };
                }
                return _#SHEET_NAME#;
            }
        }
    };" />
      </appSettings>
    </configuration>

    正则解析数据代码如下:

    // export c#
    Excel.Worksheet worksheet = (Excel.Worksheet)Globals.ThisAddIn.Application.ActiveSheet;
    
    string s = System.Configuration.ConfigurationManager.AppSettings.Get("template");
    //去注释
    Regex regex = new Regex("//[^\r\n]*[\r\n]+");
    var match = regex.Match(s);
    while (match.Success)
    {
        s = s.Replace(match.Value, "");
        match = regex.Match(s);
    }
    // 替换表格名字
    string clsName = worksheet.Name;
    regex = new Regex(@"#SHEET_NAME#");
    match = regex.Match(s);
    while (match.Success)
    {
        s = s.Replace(match.Value, clsName);
        match = regex.Match(s);
    }
    
    // 参数定义
    regex = new Regex("#PARAM_DEF#.*#PARAM_END#", RegexOptions.Singleline);
    match = regex.Match(s);
    if (match.Success)
    {
        string formatStr = match.Value.Replace("#PARAM_DEF#", "");
        formatStr = formatStr.Replace("#PARAM_END#", "").Trim();
    
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < columnCount; i++)
        {
            sb.AppendFormat(formatStr, param_types[i], param_names[i]);
            if (i != columnCount - 1)
            {
                sb.AppendLine();
            }
        }
        s = s.Replace(match.Value, sb.ToString());
    }
    else
    {
        MessageBox.Show("#PARAM_DEF# 匹配失败!");
        return;
    }
    
    // 数据定义
    regex = new Regex("#DATA_DEF#.*#DATA_END#", RegexOptions.Singleline);
    match = regex.Match(s);
    if (match.Success)
    {
        string matchAllStr = match.Value;
        string formatStr = matchAllStr.Replace("#DATA_DEF#", "");
        formatStr = formatStr.Replace("#DATA_END#", "").Trim();
    
        regex = new Regex("#PAIR_DEF#.*#PAIR_END#", RegexOptions.Singleline);
        match = regex.Match(formatStr);
        if (match.Success)
        {
            string pairStr = match.Value;
            string formatStr2 = pairStr.Replace("#PAIR_DEF#", "");
            formatStr2 = formatStr2.Replace("#PAIR_END#", "").Trim();
    
    
            regex = new Regex(@"string");
            StringBuilder sb = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
            for (int i = 3; i <= rowCount; i++)
            {
                sb2.Clear();
                for (int j = 1; j <= columnCount; j++)
                {
    
                    string stype = param_types[j - 1];
                    string sname = param_names[j - 1];
                    bool strflg = regex.Match(stype).Success;
    
                    var value = (worksheet.Cells[i, j] as Excel.Range).Value;
                    bool nullflg = value == null;
                    if (!nullflg)
                    {
                        string vstr = value.ToString();
                        vstr = vstr.Trim();
                        if (string.IsNullOrEmpty(vstr))
                        {
                            nullflg = true;
                        }
                        else
                        {
                            if (strflg)
                            {
                                vstr = string.Format(""{0}"", vstr);
                            }
                            sb2.AppendFormat(formatStr2, sname, vstr);
                        }
                    }
                    if (nullflg)
                    {
                        // null cell
                        if (strflg)
                        {
                            // string type?
                            sb2.AppendFormat(formatStr2, sname, """");
                        }
                        else
                        {
                            sb2.AppendFormat(formatStr2, sname, 0);
                        }
                    }
                    if (j != columnCount)
                    {
                        sb2.Append(',');
                    }
                }
    
                sb.Append(formatStr.Replace(pairStr, sb2.ToString()));
                if (i != rowCount)
                {
                    sb.AppendLine();
                }
            }
            s = s.Replace(matchAllStr, sb.ToString());
        }
        else
        {
            MessageBox.Show("#PAIR_DEF# 匹配失败!");
            return;
        }
    }
    else
    {
        MessageBox.Show("#DATA_DEF# 匹配失败!");
        return;
    }
    View Code

    部分说明

    1、几个导出定义:第一行 参数名 , 第二行  参数类型  ,第三行起为 数据,表格名为 结构体名字

    2、Globals.ThisAddIn.Application.ActiveSheet 为当前选中的Excel表格。

    3、获取 i 行 j 列数据方法如下:

    var value = (worksheet.Cells[i, j] as Excel.Range).Value;

     4、这里导出cs文件,如果需要导出cpp文件可以自己修改上面的模板配置即可实现。

    导出路径设置

     由于插件没有存储数据的地方,因此这里将导出路径直接存在了注册表上。

    方法如下:

         #region RegistStoreData
            public static readonly string registryPath = @"SoftwareYourCompanyNameYourAddInName";
    
            public static void StoreInRegistry(string keyName, string value)
            {
                RegistryKey rootKey = Registry.CurrentUser;
                using (RegistryKey rk = rootKey.CreateSubKey(registryPath))
                {
                    rk.SetValue(keyName, value, RegistryValueKind.String);
                }
            }
    
            public static string ReadFromRegistry(string keyName, string defaultValue = "")
            {
                RegistryKey rootKey = Registry.CurrentUser;
                using (RegistryKey rk = rootKey.OpenSubKey(registryPath, false))
                {
                    if (rk == null)
                    {
                        return defaultValue;
                    }
    
                    var res = rk.GetValue(keyName, defaultValue);
                    if (res == null)
                    {
                        return defaultValue;
                    }
    
                    return res.ToString();
                }
            }
            #endregion
    下载

    完整代码地址:https://github.com/mydishes/ESExport

    可执行插件地址https://github.com/mydishes/ESExport/tree/master/public

  • 相关阅读:
    许可管理工具
    浅谈MapControl控件和PageLayoutControl控件
    通过Bresenham算法实现完成矢量线性多边形向栅格数据的转化
    四叉树算法原理与实现
    OC系列foundation Kit基础-NSNumber
    OC系列foundation Kit基础-NSdictionary
    OC系列foundation Kit基础-NSMutableArray
    OC系列foundation Kit基础-NSArray
    OC系列foundation Kit基础-NSMutableString
    OC系列foundation Kit基础-NSString
  • 原文地址:https://www.cnblogs.com/stratrail/p/7677772.html
Copyright © 2011-2022 走看看