分享
 
 
 

关于模板中的动态取值 ---反射与javascript脚本编译

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: |||超大  

关于模板中的动态取值 ---反射与javascript脚本编译 在项目中经常遇到一个问题,打印Word或者打印Excel的时候,我们经常使用一对一的赋值或者批量替换的方式来对模板进行修改。

但是现在遇到两种场景:

1、取值是通过自定以方法进行取值的。

如:一个销售单据,会涉及到很多种费用,并且这些费用是由后台配置的,非常灵活。但是我们在制作打印模板时取值各项费用我们该如何去定义他呢,如何给他赋值呢?我们如果针对这一个场景下的模板进行一个特殊定义后,在打印另一份单据或者遇到同样的取值非常灵活的数据,是不是也需要进行特殊处理呢。

2、取值是通过自行定义进行取值的。

如:还是一个销售单据,我们打印的可能是销售价格,成本、毛利,但是如果我们打印的时候涉及到提成配比,提成配比可能是根据销售价格算的,可能根据毛利算的,可能根据效益来算的,那么是不是我们在做这个模板的时候定义:提成(按成本)、提成(按毛利)、提成...。

在这中情况下,我的解决方案是采用反射与Javascript进行处理:

这里大致讲述一下我的解决思路,各位过路大神,各位奋战一线的程序猿们,看过笑过,不喜勿喷~

第一步:建立两种Eval方法,来解析表达式

C#Eval反射式:(此种方式主要应对在程序中自定义的方法,根据参数及方法来模拟程序中的计算,并将结果返回过去,这种方法必须制定处理他的主体Object)

/// <summary>/// CShrapEval 的摘要说明/// </summary>public class CShrapEval{ /// <summary> /// 计算结果,如果表达式出错则抛出异常 /// </summary> public static object Eval(string action,Type type,object obj,object[] parm) { return type.InvokeMember( action, BindingFlags.InvokeMethod, null, obj, parm ); } public static object Eval(string Cstring, Type type, object obj) { string action = Cstring.Split('|')[0]; object[] parm = Cstring.Split('|')[1].Split(','); return type.InvokeMember( action, BindingFlags.InvokeMethod, null, obj, parm ); }}

JavaScript脚本编译方式:模拟javascript工作方式去处理一个表示式,可以使用一个javascript常用函数(如getdate() length等),灵活方便

/**//// <summary>/// 动态求值/// </summary>public class JavaEval{ /**/ /// <summary> /// 计算结果,如果表达式出错则抛出异常 /// </summary> /// <param name="statement">表达式,如"1+2+3+4"</param> /// <returns>结果</returns> public static object Eval(string statement) { return _evaluatorType.InvokeMember( "Eval", BindingFlags.InvokeMethod, null, _evaluator, new object[] { statement } ); } /**/ /// <summary> /// /// </summary> static JavaEval() { //构造JScript的编译驱动代码 CodeDomPRovider provider = CodeDomProvider.CreateProvider("JScript"); CompilerParameters parameters; parameters = new CompilerParameters(); parameters.GenerateInMemory = true; CompilerResults results; results = provider.CompileAssemblyFromSource(parameters, _jscriptSource); Assembly assembly = results.CompiledAssembly; _evaluatorType = assembly.GetType("Evaluator"); _evaluator = Activator.CreateInstance(_evaluatorType); } private static object _evaluator = null; private static Type _evaluatorType = null; /**/ /// <summary> /// JScript代码 /// </summary> private static readonly string _jscriptSource = @"class Evaluator { public function Eval(expr : String) : String { return eval(expr); } }";}

第二步、构建好两个eval之后我们就需要在程序中去识别那些是C#,那些是javascript代码断

这里我处理的办法是:<c...代码 /> 和<J ...代码 />使用这两种方式分别标示是那种代码

然后在处理中我们只需要找出那些是C代码 那些是J代码,并且对代码断进行计算

public void ExportDoc() { ExportReplace(); foreach (NodeTemplate temp in DocTemplateList) { ExportDoc(temp); } if (ActionObject != null) { //动态取值 ExportDymic(); } } //定义C表达式 System.Text.RegularExpressions.Regex RegexC = new System.Text.RegularExpressions.Regex(@"\<C\w*\|\w*[\,\w*]*\\\>"); //定义J表达式 System.Text.RegularExpressions.Regex RegexJ = new System.Text.RegularExpressions.Regex(@"\<J^\>*\\\>"); //业务逻辑理论为先处理C在处理J,但是C与J由存在循环处理的过程 public void ExportDymic() { var MatchesS = RegexC.Matches(doc.GetText()); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Cstring = MatchC.Value.Replace("<C", "").Replace("\\>", ""); string result = CEval(Cstring); //CShrapEval.Eval(Cstring, this.GetType(), this).ToString(); //A = A.Replace(MatchC.Value, result); doc.Range.Replace(MatchC.Value, result, false, false); } MatchesS = RegexJ.Matches(doc.GetText()); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Jstring = MatchC.Value.Replace("<J", "").Replace("\\>", ""); string result = JavaEval.Eval(Jstring).ToString(); doc.Range.Replace(MatchC.Value, result, false, false); } } public string CEval(string A) { var MatchesS = RegexC.Matches(A); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Cstring = MatchC.Value.Replace("<C", "").Replace("\\>", ""); string result = CEval(Cstring).ToString(); A = A.Replace(MatchC.Value, result); } MatchesS = RegexJ.Matches(A); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Jstring = MatchC.Value.Replace("<J", "").Replace("\\>", ""); string result = JEval(Jstring).ToString(); A = A.Replace(MatchC.Value, result); } return CShrapEval.Eval(A, ActionObject.GetType(), ActionObject).ToString(); } public string JEval(string A) { var MatchesS = RegexC.Matches(A); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Cstring = MatchC.Value.Replace("<C", "").Replace("\\>", ""); string result = CEval(Cstring).ToString(); A = A.Replace(MatchC.Value, result); } MatchesS = RegexJ.Matches(A); foreach (System.Text.RegularExpressions.Match MatchC in MatchesS) { string Jstring = MatchC.Value.Replace("<J", "").Replace("\\>", ""); string result = JEval(Jstring).ToString(); A = A.Replace(MatchC.Value, result); } return JavaEval.Eval(A).ToString(); }

这样就可以对表达进行精确的解析了,当然目前还有一些未考虑完全的地方 ,待各位看客老爷指点。

好的~今天就贴到这里, 后期看看被喷的程度来确定是否继续在博客园发一些日志

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有