RevitSheetDraw.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //Copyright (c) 2016, 北京探索者软件公司
  3. //All rights reserved.
  4. //文件名称: RevitSheetDraw.cs
  5. //文件描述: 绘图逻辑
  6. //创 建 者: xls
  7. //创建日期: 2017-4-19
  8. //版 本 号:1.0.0.0
  9. ////////////////////////////////////////////////////////////////////////////////
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using Autodesk.Revit.DB;
  14. using FWindSoft.Data;
  15. namespace FWindSoft.Revit.Table
  16. {
  17. /// <summary>
  18. /// Revit绘图逻辑
  19. /// </summary>
  20. public class RevitSheetDraw:ITSheetContext
  21. {
  22. public RevitSheetDraw()
  23. {
  24. this.Location = XYZ.Zero;
  25. }
  26. /// <summary>
  27. /// 绘图数据源
  28. /// </summary>
  29. public List<object> Items { get; set; }
  30. /// <summary>
  31. /// 绘图视图
  32. /// </summary>
  33. public View DrawView { get; set; }
  34. /// <summary>
  35. /// 绘图起始点
  36. /// </summary>
  37. public XYZ Location { get; set; }
  38. public void Draw(TSheet sheet)
  39. {
  40. if (Items==null||Items.Count == 0||DrawView==null||Location==null)
  41. return;
  42. //获取列信息
  43. var columns = sheet.ColumnSettings.OrderBy(s => s.Index).Where(s => s.IsShow).ToList();
  44. int showColumnCount = columns.Count;
  45. if (showColumnCount == 0)
  46. return;
  47. View currentView = DrawView;
  48. int scale = DrawView.Scale;
  49. string fontString = sheet.FontString;
  50. bool isBottom = sheet.IsBottom;
  51. TextNoteType ntypeSheet = currentView.Document.GetTextNodeType(fontString, sheet.TitleWordSetting.WordHeight, 0.7);
  52. TextNoteType ntypeHead = currentView.Document.GetTextNodeType(fontString, sheet.SheetHeaderWordSetting.WordHeight, 0.7);
  53. TextNoteType ntypeContent = currentView.Document.GetTextNodeType(fontString, sheet.SheetRowWordSetting.WordHeight, 0.7);
  54. #region 分页
  55. List<List<object>> pages = new List<List<object>>();
  56. if (sheet.IsUsePagination && sheet.RowCountPrePage > 1)
  57. {
  58. int count = 0;
  59. List<object> pageElement = new List<object>();
  60. int groupCount = this.Items.Count;
  61. for (int i = 0; i < groupCount; i++)
  62. {
  63. count++;
  64. if (count < sheet.RowCountPrePage && i != groupCount - 1)
  65. {
  66. pageElement.Add(this.Items[i]);
  67. }
  68. else if (count == sheet.RowCountPrePage || i == groupCount - 1)//相等
  69. {
  70. pageElement.Add(this.Items[i]);
  71. pages.Add(pageElement);
  72. pageElement = new List<object>();
  73. count = 0;
  74. }
  75. }
  76. }
  77. else
  78. {
  79. pages.Add(this.Items);
  80. }
  81. #endregion
  82. #region 处理表头树
  83. var tuples = columns.Select(c => new Tuple<string, object>(c.Display.ToString(), c)).ToList();
  84. List<TNode> headerNotes = TreePathParse.Parse(tuples);
  85. int headerRows = headerNotes.Max(h => h.Depth);
  86. #endregion
  87. #region 写数据
  88. Document doc = currentView.Document;
  89. Dictionary<int, double> columnsWidth = null;
  90. bool isAutoFit = sheet.AutoFit;
  91. int refCount = TSheet.GetRowCount(this.Items[0]);//一个元素对应多少行revit表格
  92. List<RevitTalbe> tables = new List<RevitTalbe>();
  93. //每一页重新编号
  94. //int num = 0;
  95. foreach (var page in pages)
  96. {
  97. //num =1;
  98. if (isAutoFit)
  99. {
  100. columnsWidth = new Dictionary<int, double>();
  101. for (int i = 0; i < showColumnCount; i++)
  102. {
  103. columnsWidth[i] = 0;
  104. }
  105. }
  106. int currentRowCount = page.Count * refCount + headerRows;
  107. if (sheet.IsShowTitleName)
  108. currentRowCount++;
  109. RevitTalbe table = new RevitTalbe(currentRowCount, showColumnCount);
  110. int currentRowIndex = 0;
  111. Func<int> currentRowIndexMove = () => currentRowIndex++;
  112. if (isBottom)
  113. {
  114. currentRowIndex = currentRowCount - 1;
  115. currentRowIndexMove = () => currentRowIndex--;
  116. }
  117. #region 表格维护
  118. {
  119. if (sheet.IsShowTitleName)
  120. {
  121. var data = new TextNoteData(currentView, XYZ.Zero, XYZ.BasisX, XYZ.BasisY, TextAlignFlags.TEF_ALIGN_CENTER, sheet.TitleName, ntypeSheet);
  122. TextNote tn = data.Create(currentView.Document);
  123. table.SetValueMerge(currentRowIndex, 0, currentRowIndex, showColumnCount - 1, tn);
  124. table.Rows[currentRowIndex].Height = sheet.TitleWordSetting.RowHeight * scale;
  125. currentRowIndexMove();
  126. }
  127. }
  128. #endregion
  129. #region 表头处理
  130. {
  131. List<TCell> cells = GetHeaderCells(ntypeHead, headerRows, headerNotes, 0, 0);
  132. int k = 0;
  133. foreach (TCell cell in cells)
  134. {
  135. table.SetValueMerge(cell.RowIndex,cell.ColumnIndex, cell.RowIndex+cell.RowSpan-1,cell.ColumnIndex+cell.ColumnSpan-1,cell.Value);
  136. if (isAutoFit && cell.ColumnSpan == 1)
  137. {
  138. double tempWidth =Convert.ToDouble(cell.Tag);
  139. columnsWidth[k] = columnsWidth[k].IsThanEq(tempWidth) ? columnsWidth[k] : tempWidth;
  140. k++;
  141. }
  142. }
  143. for (int i = 0; i < headerRows; i++)
  144. {
  145. table.Rows[currentRowIndex].Height = sheet.SheetHeaderWordSetting.RowHeight * scale;
  146. currentRowIndexMove();
  147. }
  148. }
  149. #endregion
  150. #region 表格处理
  151. {
  152. List<Dictionary<string, object>> tempPage = TSheet.GetSheetData(page);
  153. for (int no = 0; no < tempPage.Count; no++)
  154. {
  155. var item = tempPage[no];
  156. #region 自动编号
  157. if (sheet.AutoBuildNo && !string.IsNullOrEmpty(sheet.NoColumnName) && no % refCount == 0)
  158. {
  159. item[sheet.NoColumnName] = no / refCount + 1;
  160. }
  161. #endregion
  162. for (int i = 0; i < showColumnCount; i++)
  163. {
  164. //图例暂时不处理
  165. object tempValue = item.GetValue(columns[i].Name);
  166. string text = tempValue==null?"":item.GetValue(columns[i].Name).ToString();
  167. var data = new TextNoteData(currentView, XYZ.Zero, XYZ.BasisX, XYZ.BasisY, BaseDataSupply.ConvertToTextNodeAlgin(columns[i].TextAlignment), text, ntypeContent);
  168. TextNote tn = data.Create(currentView.Document);
  169. table.SetValue(currentRowIndex, i, tn);
  170. if (isAutoFit)
  171. {
  172. double tempWidth = doc.ComputeTextNoteWidth(currentView, text, ntypeContent).FromApi() * 0.7;
  173. columnsWidth[i] = columnsWidth[i].IsThanEq(tempWidth) ? columnsWidth[i] : tempWidth;
  174. }
  175. }
  176. table.Rows[currentRowIndex].Height = sheet.SheetRowWordSetting.RowHeight * scale;
  177. currentRowIndexMove();
  178. }
  179. }
  180. #endregion
  181. #region 样式设置
  182. if (isAutoFit)
  183. {
  184. //自适应列宽
  185. foreach (var d in columnsWidth)
  186. {
  187. table.Columns[d.Key].Width = d.Value * scale;
  188. }
  189. }
  190. else
  191. {
  192. for (int i = 0; i < Math.Min(table.Columns.Count, columns.Count); i++)
  193. {
  194. table.Columns[i].Width = columns[i].ColomnWidth * scale;
  195. }
  196. }
  197. tables.Add(table);
  198. #endregion
  199. }
  200. #endregion
  201. #region 放置表格
  202. List<XYZ> locations = new List<XYZ>();
  203. double sapce = 2000d;// 2000d.ToApi();
  204. XYZ baseLocation = Location;
  205. XYZ currentLocation = baseLocation.AddX(0);
  206. for (int i = 0; i < tables.Count; i++)
  207. {
  208. if (sheet.Arrange == ContentArragne.Landscape)
  209. {
  210. if (i != 0)
  211. {
  212. double tempWidth = tables[i - 1].Columns.Sum(c => c.Width);
  213. tempWidth = tempWidth + sapce;
  214. locations.Add(currentLocation = currentLocation.AddX(tempWidth.ToApi()));
  215. }
  216. else
  217. {
  218. locations.Add(currentLocation = currentLocation.AddX(0));
  219. }
  220. }
  221. else
  222. {
  223. if (i != 0)
  224. {
  225. double tempHeight = tables[i - 1].Rows.Sum(r => r.Height);
  226. tempHeight = tempHeight + sapce;
  227. locations.Add(currentLocation = currentLocation.OffsetPoint(-XYZ.BasisY, tempHeight.ToApi()));
  228. }
  229. else
  230. {
  231. //double tempHeight = tables[i].Rows.Sum(r => r.Height);
  232. //tempHeight = tempHeight;
  233. //locations.Add(currentLocation=currentLocation.OffsetPoint(-XYZ.BasisY, tempHeight.ToApi()));
  234. locations.Add(currentLocation = currentLocation.AddY(0));
  235. }
  236. }
  237. }
  238. for (int i = 0; i < tables.Count; i++)
  239. {
  240. var revitTalbe = tables[i];
  241. revitTalbe.DrawTable(locations[i], currentView);
  242. }
  243. #endregion
  244. }
  245. #region 可合并表头创建逻辑
  246. /// <summary>
  247. /// 整合表头信息
  248. /// </summary>
  249. /// <param name="noteType">贯穿信息(递归过程中国年保持不变)</param>
  250. /// <param name="rowCount">剩余的行数</param>
  251. /// <param name="nodes"></param>
  252. /// <param name="rowIndex"></param>
  253. /// <param name="columnIndex"></param>
  254. /// <returns></returns>
  255. private List<TCell> GetHeaderCells(TextNoteType noteType, int rowCount, List<TNode> nodes, int rowIndex,
  256. int columnIndex)
  257. {
  258. List<TCell> cells = new List<TCell>();
  259. View currentView = this.DrawView;
  260. Document doc = currentView.Document;
  261. int currentColumn = columnIndex;
  262. int currentRow = rowIndex;
  263. for (int k = 0; k < nodes.Count; k++)
  264. {
  265. TNode currentNode = nodes[k];
  266. int columnSpan = currentNode.LeafCount;
  267. int rowUnit = rowCount/currentNode.Depth; //改树形分支剩余的行数
  268. int rowSpan = rowUnit;
  269. string text = currentNode.Name;
  270. var leaves=currentNode.GetLeaves();
  271. ColumnSetting column = leaves[0].Tag as ColumnSetting;
  272. if (column != null)
  273. {
  274. var data = new TextNoteData(currentView, XYZ.Zero, XYZ.BasisX, XYZ.BasisY,
  275. BaseDataSupply.ConvertToTextNodeAlgin(column.TextAlignment), text, noteType);
  276. TextNote tn = data.Create(currentView.Document);
  277. TCell tCell = null;
  278. cells.Add(tCell = new TCell()
  279. {
  280. RowIndex = currentRow,
  281. ColumnIndex = currentColumn,
  282. RowSpan = rowSpan,
  283. ColumnSpan = columnSpan,
  284. Value = tn
  285. });
  286. //if (isAutoFit)
  287. //{
  288. double tempWidth = doc.ComputeTextNoteWidth(currentView, text, noteType).FromApi() * 0.7;
  289. tCell.Tag = tempWidth;
  290. // columnsWidth[k] = columnsWidth[k].IsThanEq(tempWidth) ? columnsWidth[k] : tempWidth;
  291. //}
  292. }
  293. if (!currentNode.IsLeaf)
  294. {
  295. cells.AddRange(GetHeaderCells(noteType, rowCount - rowSpan, currentNode.Nodes, currentRow + rowSpan,
  296. currentColumn));
  297. }
  298. currentColumn = currentColumn + columnSpan;
  299. }
  300. return cells;
  301. }
  302. #endregion
  303. }
  304. }