品牌建设对企业的作用,东莞营销网站建设优化,wordpress速度优化,成都网站运营维护厂家疲惫的修改
应人才测评产品的需求#xff0c;导出测评报告是其中一个重要的环节#xff0c;报告的文件类型也多种多样#xff0c;其中WORD输出也扮演了一个重要的角色。
实现方法比较简单#xff0c;结合分析结果数据#xff0c;通过WORD模板文件进行替换输出。在实现的…疲惫的修改
应人才测评产品的需求导出测评报告是其中一个重要的环节报告的文件类型也多种多样其中WORD输出也扮演了一个重要的角色。
实现方法比较简单结合分析结果数据通过WORD模板文件进行替换输出。在实现的过程中图表的设计是必不可少的根据初次产品的设计方案图表采用微软Chart图表控件进行开发采用雷达图进行呈现。使用该控件首先要引入 System.Web.DataVisualization.dll 程序集通过定义 System.Web.UI.DataVisualization.Charting.Chart 类来实现本来采用该开发方案的初衷是觉得都是微软的技术图表的呈现类型也比较丰富可在实际的开发中情况没有想像的那么顺利提供的技术文档非常有限各种百度也是凤毛麟角经过努力与探索最终还是实现了需求。
但后来由于种种原因图表要求采用饼状3D图进行呈现虽然已经有了第一次的经验但细节的变化不得不再次进行探索和学习可当需求再次改变的时候我决定游说产品设计和改变设计思路。
新的思路
由于引入 Microsoft.Office.Interop.Word 程序集进行开发因此在Word上的所有操作都能用程序去实现其内置的图表功能也不例外通过演练和内部讨论图形化的呈现基本能够满足需求。
通用性
举例我们在Word中插入一个图表并选择雷达图如下图 插入后我们看到 Word 会自动弹出一个微缩版的 Excel 应用改变其中的项和系列值图表就会对应的产生变化。
我们右击雷达图选择更改图表类型为饼图如下图 可以看到饼图按照EXCEL数据中的系列1数据进行呈现也不会因为系列2的数据存在而出现错误。由此可以分析出控制好这个 Excel 的数据应用即可按照我们的设计实现任一图表的输出。
设计方案
1负责具体业务的应用程序输出后的数据存入一个二维字符串数组里模拟 Excel 数据存储模式。
2考虑未来的扩展性将二维数组转化为Json数据格式并添加一个查找关键字节点假设为“ t:chart1”。
3在 Word 模板设计图表图表的标题设置为Json对应的查找关键字即“ t:chart1”。
4编写数据导出EXCEL方法传递JSON字符串参数读取Word模板文件遍历模板文件中的图表对象并按查找关键字与图表的标题进行对比匹配成功则将JSON中数组转化为图表需要的EXCEL数组形式到此输出完毕。
为什么用 Json 过渡
我们的云架构里设计了一个 Office 计算中心在某些环境下比如 Linux 中需要这种方式传递并返回值以达到导入导出Office文件的目的。所以大家要根据实际的应用进行设计这里仅作为参考。
关键代码实现
开发环境
操作系统Windows Server 2019 DataCenter
开发工具VisualStudio2019
框架及语言.net 4.7.1 C#
服务上需要安装 Office 2016或以上
现在开始
在此我们以最易懂的代码形式举例假设文件模板中的图表为条状图关键查找字图表标题设为 “ t:chart1”,如下图 1创建二维数组 //定义二维字符串数组第一列为项目名称第二列为值string[,] chart1 new string[11, 2];chart1[0, 0] 项;chart1[0, 1] 值;chart1[1, 0] 全局观;chart1[2, 0] 影响力;chart1[3, 0] 公正性;chart1[4, 0] 果敢性;chart1[5, 0] 执行力;chart1[6, 0] 人际理解;chart1[7, 0] 成就意识;chart1[8, 0] 创新意识;chart1[9, 0] 情绪控制;chart1[10, 0] 学习发展;Random rnd new Random();for (int si 1; si 10; si){chart1[si, 0] rnd.NextDouble().ToString(); //循环赋值随机浮点数}
2二维数组转Json格式
这里引入 Newtonsoft.Json.dll 程序集进行操作代码如下 StringWriter sw new StringWriter(); //using System.IOusing (Newtonsoft.Json.JsonWriter writer new Newtonsoft.Json.JsonTextWriter(sw)){writer.Formatting Newtonsoft.Json.Formatting.Indented;writer.WriteStartObject();//t:chart1 转化数组chart1 为 json 对象writer.WritePropertyName(t:chart1);writer.WriteStartArray();writer.WriteStartObject();writer.WritePropertyName(col1);writer.WriteValue(chart1[0, 0]);writer.WritePropertyName(col2);writer.WriteValue(chart1[0, 1]);writer.WriteEndObject();for (int r chart1.GetLength(0) - 1; r 0; r--){writer.WriteStartObject();//循环写入列2的具体值for (int c 0; c 2; c){writer.WritePropertyName(col (c 1).ToString());writer.WriteValue(chart1[r, c]);}writer.WriteEndObject();}writer.WriteEndArray();//t:chart1writer.WriteEndObject();writer.Flush();}sw.Close();string jsonContent sw.GetStringBuilder().ToString(); //得到最终json字串
转化成功的样例如下
{
t:chart1: [{col1: 项,col2: 值},{col1: 学习发展,col2: 4.1},{col1: 情绪控制,col2: 5},{col1: 创新意识,col2: 5.1},{col1: 成就意识,col2: 4.8},{col1: 人际理解,col2: 4},{col1: 执行力,col2: 5},{col1: 果敢性,col2: 5.7},{col1: 公正性,col2: 4.5},{col1: 影响力,col2: 4.7},{col1: 全局观,col2: 4.2}]
} 3查找图表且替换数据
本代码程序只是示例片断非完整程序仅供参考。
一些引用
using WordMicrosoft.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 WordAppnew Word.Application();//创建一个名为WordDoc的文档对象WordApp.DisplayAlertsWord.WdAlertLevel.wdAlertsNone; //禁止一切提示警告//打开 filename 的文件Word.Document WordDocWordApp.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 里的 shapesfor (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;}//获取图表的titlestring _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;//遍历json对象节点里的数组for (int i 0; i jObject[tcmd].Count(); i){ListJToken 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).Value jToken.ToArray()[0].ToString();k;}}shape.Chart.SetSourceData(sourceDataAddress); //设置更新图表的数据源break;} // index of name} // has chart}//foreach tcmd} //WordDoc.InlineShapes 小结
通过这种设计可以实现任意更换图表的类型基本无需关注图表的实现原理而让开发人员更多的关注于业务逻辑当然这些图表的种类受限于Word的提供能力如果能够满足需求不失为一种解决思路。另外我们可以继续扩展程序的功能实现动态的图表添加或切换能力等。
一些体会
作为一名全程管理加全栈开发的 “野战军”更多的时候考虑的是满足需求、稳定功能和控制各种成本而无法深入地研究各项领域。随着年龄的增长唯一能做到的就是业务经验弥补精力和学习时间的不足还是有几点体会与大家共勉吧
1、后悔学生时代没有端正态度和认识到认真学习的重要性所谓书到用时方恨少熟练掌握修炼数据结构与算法、数学等程序员的内功至关重要。
2、语言只是一种模型和工具而已可先从一门语言入手到实际应用抽象的来看所有语言总体上都是大同小异后来会觉得学习一门新语言是一件非常有趣的事。
3、时间允许的情况下还是要深入掌握一些底层的技术开发和原理这至少是一件非常有趣的事。
4、在工作中平衡最为关键也包括人换位思考很重要。
5、提升设计能力、业务处理能力和总结学习方法尤为关键。
以上就是自己一些体会时间仓促不妥之处还请大家批评指正讨论程序员节就要到啦祝咱们永远保持年轻的心健康的心态用智慧编写美好的人生