using System; using System.Collections.Generic; using System.IO; using System.Text; using FastReport.Table; using FastReport.Utils; namespace FastReport.Export.Json { /// /// Represents the JSON export filter. /// public partial class JsonExport : ExportBase { #region Fields Encoding encoding; int indent; string indention = " "; int pageNo = 0; bool isCommaNeed = false; #endregion #region Private Methods void write(Stream target, string data) { if (string.IsNullOrEmpty(data)) return; if (data.StartsWith("{") && isCommaNeed) { var trailedBytes = encoding.GetBytes("," + Environment.NewLine); long newPosition = target.Length - encoding.GetBytes(Environment.NewLine).Length; if (newPosition >= 0) { target.Position = newPosition; target.Write(trailedBytes, 0, trailedBytes.Length); } } isCommaNeed = false; if (data.EndsWith("}")) isCommaNeed = true; data = appendIndention(data); byte[] bytes = encoding.GetBytes(data + Environment.NewLine); target.Write(bytes, 0, bytes.Length); } string appendIndention(string str) { for (int i = 0; i < indent; i++) str = indention + str; return str; } string comma(int i, int length) { return i < length - 1 ? "," : ""; } string wrap(string s) { if (string.IsNullOrEmpty(s)) return "\"\""; char c = '\0'; int i; int len = s.Length; StringBuilder sb = new StringBuilder(len + 4); string t; for (i = 0; i < len; i += 1) { c = s[i]; switch (c) { case '\\': case '"': sb.Append('\\'); sb.Append(c); break; case '/': sb.Append('\\'); sb.Append(c); break; case '\b': sb.Append("\\b"); break; case '\t': sb.Append("\\t"); break; case '\n': sb.Append("\\n"); break; case '\f': sb.Append("\\f"); break; case '\r': sb.Append("\\r"); break; default: if (c < ' ') { t = "000" + String.Format("X", c); sb.Append("\\u" + t.Substring(t.Length - 4)); } else { sb.Append(c); } break; } } return "\"" + sb.ToString() + "\""; } void exportObj(Base c, List items) { if (c is ReportComponentBase && (c as ReportComponentBase).Exportable) { ReportComponentBase obj = c as ReportComponentBase; //if (FDataOnly && (obj.Parent == null || !(obj.Parent is DataBand))) //continue; //if (obj is TableCell) //continue; if (obj is TextObject) { TextObject text = obj as TextObject; if (!string.IsNullOrEmpty(text.Text)) items.Add("{\"TextObject\":" + wrap(text.Text) + "}"); } else if (obj is PictureObject) { PictureObject pic = obj as PictureObject; if (!string.IsNullOrEmpty(pic.ImageLocation)) items.Add("{\"PictureObject\":" + wrap(pic.ImageLocation) + "}"); } else if (obj is RichObject) { RichObject rich = obj as RichObject; if (!string.IsNullOrEmpty(rich.Text)) items.Add("{\"RichObject\":" + wrap(rich.Text) + "}"); } else if (obj is HtmlObject) { HtmlObject html = obj as HtmlObject; if (!string.IsNullOrEmpty(html.Text)) items.Add("{\"HtmlObject\":" + wrap(html.Text) + "}"); } else if (obj is TableBase) { StringBuilder tableData = new StringBuilder(); tableData.Append("{\"TableObject\":["); indent++; TableBase table = obj as TableBase; for (int i = 0; i < table.RowCount; i++) { string row = "["; for (int j = 0; j < table.ColumnCount; j++) { TableCell cell = table[j, i]; row += wrap(cell.Text) + comma(j, table.ColumnCount); } row += "]" + comma(i, table.RowCount); tableData.Append(Environment.NewLine + appendIndention(row)); } indent--; tableData.Append(Environment.NewLine + appendIndention("]}")); items.Add(tableData.ToString()); } } } #endregion #region Protected Methods /// protected override void Start() { base.Start(); pageNo = 0; write(Stream, "{"); indent++; write(Stream, "\"report\": ["); indent++; } /// protected override void Finish() { indent--; write(Stream, "]"); indent--; write(Stream, "}"); } /// protected override string GetFileFilter() { return new MyRes("FileFilters").Get("JsonFile"); } /// protected override void ExportPageBegin(ReportPage page) { base.ExportPageBegin(page); write(Stream, "{"); indent++; write(Stream, "\"page\":\"" + (pageNo + 1) + "\","); write(Stream, "\"items\":["); indent++; } /// protected override void ExportPageEnd(ReportPage page) { base.ExportPageEnd(page); indent--; write(Stream, "]"); indent--; write(Stream, "}" + comma(pageNo, Pages.Length)); pageNo++; } /// protected override void ExportBand(BandBase band) { base.ExportBand(band); List items = new List(); exportObj(band, items); foreach (Base c in band.ForEachAllConvectedObjects(this)) exportObj(c, items); for (int i = 0; i < items.Count; i++) { string item = items[i]; if (string.IsNullOrEmpty(item)) continue; write(Stream, item + comma(i, items.Count)); } } #endregion /// /// Initializes a new instance of the class. /// public JsonExport() { encoding = Encoding.Unicode; } } }