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

  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/stratrail/p/7677772.html
Copyright © 2011-2022 走看看