
在金融大数据功能中,使用了TuShare的数据接口,其所有接口都采用WebAPI的方式提供,本来还在纠结着应该搬那些数据接口给用户使用,后来发现,所有数据接口都有其通用性,结合Excel灵活友好的输入方式,将其输入参数统一在Excel界面进行维护,最终实现了所有接口均可由用户自己去维护参数的方式发出查询获得所有的结果,非常完美。
此篇对应的Excel催化剂功能实现:第98波-零代码零距离轻松接触并拥有金融大数据 - 简书 https://www.jianshu.com/p/3cd41a483448
如上述所说,若非想到这些共性的部分,再结合对Excel的深度认识,这样的功能实现,很难由单一的程序员思维可以完成,在VBA、VSTO开发群体中,由于其有相当的业务背景知识和对Excel工具的每一个功能在界面和代码层的熟练掌握,才能发挥到这种让人惊叹的效果出来。
调用TuShare接口时,也用到了json反序列化的知识,和http请求的知识,这些在前面的开源文章里也有所提及。
为了用户配置的参数表,可以最大程度的复用,也引用了参数模板的概念
internal static void CreateTemplateSheet()
{
Excel.Worksheet sht = Common.ExcelApp.Worksheets.Add();
sht.Activate();
//参数表
sht.Range["A1:F1"].Value2 = new string[] { "api_name", "fields", "参数2", "参数3", "参数4", "参数5" };
ListObjectOfParas = sht.ListObjects.Add(
SourceType: Excel.XlListObjectSourceType.xlSrcRange,
Source: sht.Range["A1:F2"],
XlListObjectHasHeaders: Excel.XlYesNoGuess.xlYes
);
//字段信息表
sht.Range["H1:K1"].Value2 = new string[] { "原字段名称", "类型", "描述", "返回表字段名称" };
ListObjectOfOutputFields = sht.ListObjects.Add(
SourceType: Excel.XlListObjectSourceType.xlSrcRange,
Source: sht.Range["H1:K2"],
XlListObjectHasHeaders: Excel.XlYesNoGuess.xlYes
);
sht.Range["M1"].Value2 = "TuShare平台接口文档";
sht.Range["M1"].Interior.Color = ColorTranslator.ToOle(Color.Yellow);
Excel.Range hyperRange = sht.Range["M2"];
hyperRange.Hyperlinks.Add(Anchor: hyperRange, Address: "https://tushare.pro/document/2", TextToDisplay: "https://tushare.pro/document/2");
hyperRange.EntireColumn.AutoFit();
}

代码生成了这样的模板工作表
关键一步,通过参数表,生成提交所用的post数据,json格式,通过对象反序列化所得。这里可认真体会下在Excel表格中做参数配置的极大优势,特别是ListObject对象的对结构化数据的最大支持。
private static string GetPostData(Excel.Range row, string[] columnNamesOfParas)
{
PostData postData = new PostData();
postData.token = Properties.Settings.Default.TuShareAPIKey;
int apiColIndex = ListObjectOfParas.ListColumns["api_name"].Index;
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (Excel.Range cell in row.Cells)
{
if (cell.Column == ListObjectOfParas.ListColumns["api_name"].Range.Column)
{
var cellValue = cell.Value2;
if (cellValue!=null)
{
string apiName = cellValue.ToString();
postData.api_name = apiName.Trim();
}
else
{
throw new Exception("api_name列的值不能为空");
}
}
else if (columnNamesOfParas.Contains("fields") && cell.Column == ListObjectOfParas.ListColumns["fields"].Range.Column)
{
var cellValue = cell.Value2;
if (cellValue!=null)
{
string fieldNames = cell.Value2.ToString();
postData.fields = fieldNames.Trim();
}
}
else
{
var paraRange = Common.ExcelApp.Intersect(cell.EntireColumn, ListObjectOfParas.HeaderRowRange);
string paraName = paraRange.Value2.ToString();
var cellValue = cell.Value2;
if (cellValue!=null)
{
string paraValue = cell.Value2.ToString();
dic.Add(paraName.Trim(), paraValue.Trim());
}
}
}
postData.Params = dic;
return JsonConvert.SerializeObject(postData);
}
现接下来的核心代码,就是向Web API提交数据了,使用了苏飞封装的httpHelper,几行代码完事。
HttpHelper httpHelper = new HttpHelper();
DataTable resultTable = null;
foreach (Excel.ListRow row in ListObjectOfParas.ListRows)
{
string postData = GetPostData(row.Range, columnNamesOfParas);
HttpItem httpItem = new HttpItem()
{
URL = "http://api.tushare.pro",
Method = "POST",
Postdata = postData
};
string resultJson = httpHelper.GetHtml(httpItem).Html;
if (resultTable==null)
{
resultTable = GetResultTableStructure(resultJson);
}
在程序员的世界中,难免容易带上一些自负的情绪,Excel催化剂坚持为技术社区做贡献,可能很大一个群体总以为这不是个东西,太皮毛的分享。
认真看下来的人,总是会有收获的,特别是Excel催化剂并且单一的一个技术产品,它乃是集合了业务和技术的理解,才能诞生出这么优秀的符合业务需要的大量刚需功能。没有对零售业、制造业、商贸行业的理解,和对Excel的极深入的精通,再带上对数据分析、数据处理ETL、商业智能BI、面向对象编程语言的掌握,最后附上对共性事物的抽象理解能力、并横向跨界发散思维的活跃,是没法带出这么多优秀成果的。