Excel导出插件
一个游戏通常需要10多个Excel表格或者更多来配置,一般会通过导出csv格式读取配置。
本文提供导出Excel直接生成c#文件,对应数据直接生成结构体和数组,方便开发排错和简化重复写每个表格的读取配置方法。

上图左图为Excel表格数据,右图 为导出生成的cs文件。
官方文档: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 {} {};
#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#{}={}#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 = ; i < columnCount; i++)
{
sb.AppendFormat(formatStr, param_types[i], param_names[i]);
if (i != columnCount - )
{
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 = ; i <= rowCount; i++)
{
sb2.Clear();
for (int j = ; j <= columnCount; j++)
{ string stype = param_types[j - ];
string sname = param_names[j - ];
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, );
}
}
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;
}
部分说明
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 = @"Software\YourCompanyName\YourAddInName"; 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
Excel导出插件的更多相关文章
- Excel导出插件-VSTO
前言 一个游戏通常需要10多个Excel表格或者更多来配置,一般会通过导出csv格式读取配置. 本文提供导出Excel直接生成c#文件,对应数据直接生成结构体和数组,方便开发排错和简化重复写每个表格的 ...
- jsexcel导出插件
ExcelTable.js /* * author:wenluanlai */ (function ($) { Date.prototype.Format = function (fmt) { var ...
- PHP原生EXCEL导出带样式无插件无乱码实现
PHP原生EXCEL导出 经测试 带样式 无插件 无乱码,不需要引入任何插件,不需要修改任何编码 (使用时只需要修改引入php数据库配置文件.修改thead tbody中的数据即可.根据自己的需要去接 ...
- Asp.Net 常用工具类之Office—Excel导出(4)
开发过程中各类报表导入导出防不胜防,网上也是各种解决方法层出不穷,比如Excel,CSV,Word,PDF,HTML等等... 网上各种导出插件也是层出不穷,NPOI,微软Microsoft.Offi ...
- .NET Excel导出方法及其常见问题详解
摘要:.NET Excel导出方法及其常见问题详解. 一.Excel导出的实现方法 在.net 程序开发中,对于Excel文件的导出我们一共有三种导出方式: 利用文件输出流进行读写操作 这种方式的导出 ...
- .Net Excel 导出图表Demo(柱状图,多标签页) .net工具类 分享一个简单的随机分红包的实现方式
.Net Excel 导出图表Demo(柱状图,多标签页) 1 使用插件名称Epplus,多个Sheet页数据应用,Demo为柱状图(Epplus支持多种图表) 2 Epplus 的安装和引用 新建一 ...
- laravel 导出插件
转发:https://blog.csdn.net/gu_wen_jie/article/details/79296470 版本:laravel5 php 5.6 安装步骤: 一.安装插件 ①.首先在L ...
- js-xlsx 实现前端 Excel 导出(支持多 sheet)
之前写文章介绍了使用 js-xlsx 实现导入 excel 的功能,现在再介绍一下如何使用 js-xlsx 进行 excel 导出. [实现步骤] 1. 首先安装依赖 npm install xlsx ...
- [moka同学笔记]PHPexcel之excel导出和导入
原案例来自http://www.sucaihuo.com/有修改 1.目录结构(文件不用解释,应该都可以看得懂,直接看代码)
随机推荐
- 自制OSPF配置实验大全
OSPF综合实验(gns模拟器) 注意点: Ospf实验推荐用gns制作 //图中的交换机可以视觉忽略或缩小成一个点.(^ v^) Ospf 实验拓扑图 目录 OSPF综合实验... 1 Os ...
- Web in Linux小笔记001
Linux灾难恢复: Root密码修复 Centos single Filesystem是硬盘文件根目录,无法再cd ..就像macitosh 硬盘图标 Pwd:显示绝对路径 MBR修复 模拟MBR被 ...
- 201521123084 《Java程序设计》第14周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结数据库相关内容. answer: 2. 书面作业 1. MySQL数据库基本操作 1.1 建立数据库test.表studen ...
- 【Alpha】Daily Scrum Meeting——Day2
站立式会议照片 1.本次会议为第二次 Meeting会议: 2.本次会议在中午12:30,在陆大楼召开,本次会议为30分钟讨论昨天的任务完成情况以及接下来的任务安排. 每个人的工作分配 成 员 昨天已 ...
- java:接口特性 接口与抽象类/普通类的区别
接口 书面定义: Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 在ja ...
- Hibernate第五篇【inverse、cascade属性详解】
前言 上一篇博文已经讲解了一对多和多对一之间的关系了,一对多和多对一存在着关联关系(外键与主键的关系).本博文主要讲解Inverse属性.cascade属性.这两个属性对关联关系都有影响 Invers ...
- JVM 菜鸟进阶高手之路九(解惑)
转载请注明原创出处,谢谢! 在第八系列最后有些疑惑的地方,后来还是在我坚持不懈不断打扰笨神,阿飞,ak大神等,终于解决了该问题.第八系列地址:http://www.cnblogs.com/lirenz ...
- Matlab入门学习(程序设计)
一.循环(for,while) for循环: for i=begin:step:end ...... end while循环: while condition ...... end 二.分枝(if,i ...
- openGPS.cn - 高精度IP定位原理,定位误差说明
[ip定位历史] 关于IP定位,最早是通过运营商实现,每个运营商申请到的ip段,在某个范围内使用. 因此早期只能是国家为单位的基础数据. 对于比较大的国家,就进一步划分,比如,中国某通讯公司(不打广告 ...
- 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 引言&前言
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 译者团队(排名不分先后):阿希.blueken.brucec ...