/// <summary> /// Performs a complex Dump operation with the given data /// </summary> /// <param name="wb">the workbook that needs to be dumped</param> /// <param name="data">the data that is being exported</param> /// <param name="configuration">the configuration describing the output process</param> private void PerformComplexDump(IWorkbook wb, DynamicResult[] data, DumpConfiguration configuration) { if (configuration.Source != ".") { DumpSection(wb, data, configuration, configuration.Source); } else { var fl = configuration.Files.First(); var item = data.First(); foreach (var child in item.Keys) { var childConfig = fl.Children[child]; if (childConfig == null) { childConfig = fl.Children["Default"]; } if (childConfig != null && item[child] is DynamicResult[] childRows) { DumpSection(wb, childRows, childConfig, child); } } } }
/// <summary> /// Dumps collected data into the given file /// </summary> /// <param name="fileName">the name of the target filename for this dump-run</param> /// <param name="data">the data that must be dumped</param> /// <param name="configuration">the dumper-configuiration</param> /// <returns>a value indicating whether there was any data available for dumping</returns> public bool DumpData(string fileName, DynamicResult[] data, DumpConfiguration configuration) { using (FileStream fst = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)) { return(DumpData(fst, data, configuration)); } }
/// <summary> /// Dumps collected data into the given file /// </summary> /// <param name="fileName">the name of the target filename for this dump-run</param> /// <param name="data">the data that must be dumped</param> /// <param name="configuration">the dumper-configuiration</param> /// <returns>a value indicating whether there was any data available for dumping</returns> public bool DumpData(string fileName, DynamicResult[] data, DumpConfiguration configuration) { using (FileStream fst = File.Create(fileName)) { return(DumpData(fst, data, configuration)); } }
/// <summary> /// Dumps collected data into the given stream /// </summary> /// <param name="outputStream">the output-stream that will receive the dumped data</param> /// <param name="data">the data that must be dumped</param> /// <param name="configuration">the dumper-configuiration</param> /// <returns>a value indicating whether there was any data available for dumping</returns> public bool DumpData(Stream outputStream, DynamicResult[] data, DumpConfiguration configuration) { using ( StreamWriter writer = new StreamWriter(outputStream, Encoding.Default)) { Scope scope = new Scope(true); return(DumpSection(writer, data, configuration, scope)); } }
/// <summary> /// Dumps a single section of data /// </summary> /// <param name="writer">the target writer</param> /// <param name="data">the dumped data</param> /// <param name="configuration">the dumper configuration</param> /// <param name="scope">the scope that is used for variable exposition</param> private bool DumpSection(StreamWriter writer, DynamicResult[] data, DumpConfiguration configuration, Scope scope) { bool retVal = false; foreach (DynamicResult result in data) { foreach (string key in result.Keys) { if (!(result[key] is DynamicResult[])) { scope[key] = result[key]; } } foreach (ConstConfiguration constant in configuration.Constants) { scope[constant.Name] = constant.ConstType == ConstType.SingleExpression ? ExpressionParser.Parse(constant.ValueExpression, scope, a => { DefaultCallbacks.PrepareDefaultCallbacks(a.Scope, a.ReplSession); }) : ExpressionParser.ParseBlock(constant.ValueExpression, scope, a => { DefaultCallbacks.PrepareDefaultCallbacks(a.Scope, a.ReplSession); }); } foreach (DumpFormatFile file in configuration.Files) { retVal = true; writer.Write(scope.FormatText(GetFileText(file))); foreach (DumpConfiguration child in file.Children) { scope.OpenInnerScope(); try { DumpSection(writer, result[child.Source] as DynamicResult[], child, scope); } finally { scope.CollapseScope(); } } } } return(retVal); }
/// <summary> /// Dumps collected data into the given stream /// </summary> /// <param name="outputStream">the output-stream that will receive the dumped data</param> /// <param name="data">the data that must be dumped</param> /// <param name="configuration">the dumper-configuiration</param> /// <returns>a value indicating whether there was any data available for dumping</returns> public bool DumpData(Stream outputStream, DynamicResult[] data, DumpConfiguration configuration) { IWorkbook wb = OpenWorkbook(); try { if (configuration == null) { PerformSimpleDump(wb, data); } else { PerformComplexDump(wb, data, configuration); } return(true); } finally { wb.Write(outputStream); wb.Close(); } }
private void DumpSection(IWorkbook wb, DynamicResult[] data, DumpConfiguration configuration, string sheetName) { if (configuration.Files.Count != 0) { throw new ArgumentException("No child-sections allowed in a sheet"); } var scope = new Scope(true); scope["$sheetName"] = sheetName; var first = true; string[] keys = null; int rowId = 0; ISheet shiit = wb.CreateSheet(sheetName.Replace("'", "").Replace("\"", "").Replace("/", "").Replace("\\", "")); using (var context = ExpressionParser.BeginRepl(scope, a => { DefaultCallbacks.PrepareDefaultCallbacks(a.Scope, a.ReplSession); })) { var badKeys = scope.Keys.ToList(); badKeys.Add("$sheetTitle"); foreach (var item in data) { foreach (var key in item.Keys) { if (!(item[key] is DynamicResult[])) { scope[key] = item[key]; } } foreach (ConstConfiguration constant in configuration.Constants) { scope[constant.Name] = constant.ConstType == ConstType.SingleExpression ? ExpressionParser.Parse(constant.ValueExpression, context) : ExpressionParser.ParseBlock(constant.ValueExpression, context); } IRow row; if (first) { keys = (from k in scope.Keys join b in badKeys on k equals b into bk from g in bk.DefaultIfEmpty() where g == null select k).ToArray(); if (scope["$sheetTitle"] is string s && !string.IsNullOrEmpty(s)) { row = shiit.CreateRow(rowId++); SetTitleRow(row, s, keys.Length); } row = shiit.CreateRow(rowId++); DumpRow(row, keys, (IDictionary <string, object>)null); first = false; } row = shiit.CreateRow(rowId++); DumpRow(row, keys, scope); } if (keys != null) { for (int i = 0; i < keys.Length; i++) { shiit.AutoSizeColumn(i); } } } }
/// <summary> /// Dumps collected data into the given stream /// </summary> /// <param name="outputStream">the output-stream that will receive the dumped data</param> /// <param name="data">the data that must be dumped</param> /// <param name="configuration">the dumper-configuiration</param> /// <returns>a value indicating whether there was any data available for dumping</returns> public bool DumpData(Stream outputStream, DynamicResult[] data, DumpConfiguration configuration) { bool retVal = true; if (configuration.Files.Count > 1) { LogEnvironment.LogDebugEvent(null, "The Dump-Configuration contains more than one file. All settings but the first one are being ignored.", (int)LogSeverity.Warning, null); } CsvSettings settings = null; if (configuration.Files.Count != 0) { settings = new DumpRuleFile(configuration.Files[0]).ParseJsonFile <CsvSettings>(); } if (settings == null) { settings = new CsvSettings(); } bool first = true; try { using (StreamWriter writer = new StreamWriter(outputStream, Encoding.GetEncoding(settings.Encoding))) { List <string> fields = new List <string>(); string format = ""; var scope = new Scope(); scope["$$Format"] = new Func <string, string>(s => { var rv = s; foreach (var es in settings.EscapeSettings) { rv = Regex.Replace(rv, es.MatchRegex, es.RegexReplaceExpression, RegexOptions.CultureInvariant | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); } return(rv); }); using (var scriptingContext = ExpressionParser.BeginRepl(scope, i => DefaultCallbacks.PrepareDefaultCallbacks(i.Scope, i.ReplSession))) { foreach (DynamicResult result in data) { if (first) { first = false; fields.AddRange(result.Keys); fields.AddRange(from t in configuration.Constants select t.Name); Dictionary <string, object> firstRow = new Dictionary <string, object>(); fields.ForEach(n => firstRow.Add(n, n)); var tmpFields = (from t in fields join c in settings.Formattings on t equals c.ColumnName into cj from cn in cj.DefaultIfEmpty() join v in configuration.Constants on t equals v.Name into vj from vn in vj.DefaultIfEmpty() select new { ColumnName = t, CustomFormat = cn, ConstDefinition = vn }).ToArray(); format = string.Join(settings.CsvSeparator, from t in tmpFields select $"{settings.ValueStartCharacter}{GetColumnDefinition(t.ColumnName, t.CustomFormat, t.ConstDefinition, false)}{settings.ValueEndCharacter}"); var headFormat = string.Join(settings.CsvSeparator, from t in tmpFields select $"{settings.ValueStartCharacter}{GetColumnDefinition(t.ColumnName, t.CustomFormat, t.ConstDefinition, true)}{settings.ValueEndCharacter}"); scope["$$fmt"] = format; scope["$$hdr"] = headFormat; scope["$data"] = firstRow; scope["$$RowNum"] = -1; foreach (var cst in configuration.Constants.Where(n => n.ConstType == ConstType.ExpressionBlock)) { ExpressionParser.ParseBlock($"fx_{cst.Name}={cst.ValueExpression}", scriptingContext); ExpressionParser.ParseBlock($"fx_{cst.Name}.ParentScope=Scope()", scriptingContext); } if (settings.TableHeader) { writer.WriteLine(ExpressionParser.Parse("$$($$hdr)", scriptingContext)); } } ExpressionParser.Parse("$$RowNum++", scriptingContext); scope["$data"] = result; foreach (var cst in configuration.Constants) { if (cst.ConstType == ConstType.SingleExpression) { ExpressionParser.Parse($"{cst.Name}={cst.ValueExpression}", scriptingContext); } else { ExpressionParser.Parse($"{cst.Name}=fx_{cst.Name}()", scriptingContext); } } writer.WriteLine(ExpressionParser.Parse("$$($$fmt)", scriptingContext)); } } } } catch (Exception ex) { LogEnvironment.LogEvent($"Error: {ex.OutlineException()}", LogSeverity.Error); retVal = false; } return(retVal); }