Dynamic values of templates and templates
There is often a problem in projects. When printing word or excel, we often use a one-to-one assignment or batch replacement method to modify the template.
But now we have two scenarios:
1. The value can be customized.
For example, a sales document involves a lot of fees, which are configured in the background and flexible. But how do we define the cost of the value when creating a print template? How do we assign a value to the template? If we make a special definition for the template in this scenario and print another document or encounter data with the same value that is very flexible, do we also need to perform special processing.
2. The value is defined by yourself.
For example, if we still use a sales document, we may print the sales price, cost, and gross profit. However, if we have a Commission ratio, the commission ratio may be calculated based on the sales price, it may be calculated based on the gross profit, and may be calculated based on the benefit. Is it our definition when we make this template: Commission (by cost), Commission (by gross profit), Commission ....
In this case, my solution is to use reflection and javascript for processing:
Here I will give a general picture of my solution. You have been on the road, and the programmers who have fought on the ground have read and laughed. Don't like it ~
Step 1: create two Eval methods to parse expressions
C # Eval reflection: (this method mainly deals with custom methods in the program, simulating calculation in the program based on parameters and methods, and returning the results to the past, this method must be used to process the main Object)
/// <Summary> /// CShrapEval abstract description /// </summary> public class CShrapEval {/// <summary> /// calculation result, if an expression error occurs, an exception is thrown. // </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 script compilation method: Simulate the javascript working method to process a representation, you can use a common javascript function (such as getdate () length), flexible and convenient
/** //// <Summary> /// dynamic evaluation // </summary> public class JavaEval {/** /// <summary> /// calculation result, if an expression error occurs, an exception is thrown. // </summary> /// <param name = "statement"> expression, for example, "1 + 2 + 3 + 4" </param> // <returns> result </returns> public static object Eval (string statement) {return _ evaluatorType. invokeMember ("Eval", BindingFlags. invokeMethod, null, _ evaluator, new object [] {statement });} /** // <summary> ///// </summary> static JavaEval () {// construct the JScript compilation driver code 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 code // </summary> private static readonly string _ jscriptSource = @ "class Evaluator {public function Eval (expr: string): String {return eval (expr );}}";}
Step 2: After building two eval, we need to identify the C # in the program, and the javascript code is disconnected.
The solution here is: <c... code/> and <J... code/> use these two methods to identify the code
Then, in the process, we only need to find out the C code, the J code, and calculate the code disconnection.
Public void ExportDoc () {ExportReplace (); foreach (NodeTemplate temp in DocTemplateList) {ExportDoc (temp);} if (ActionObject! = Null) {// The dynamic value ExportDymic () ;}// defines the C expression System. text. regularExpressions. regex RegexC = new System. text. regularExpressions. regex (@ "\ <C \ w * \ | \ w * [\, \ w *] * \>"); // defines the J expression System. text. regularExpressions. regex RegexJ = new System. text. regularExpressions. regex (@ "\ <J ^ \> * \>"); // the business logic theory first processes C in processing J, however, C and J are processed cyclically by the 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 =. 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 =. 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 =. 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 =. 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 =. replace (MatchC. value, result);} return JavaEval. eval (). toString ();}
In this way, the expression can be accurately parsed. Of course, there are still some points that have not been fully considered. We will give you some advice.
Okay ~ I will post it here today. Later I will check the degree of being sprayed to determine whether to continue sending some logs on the blog.