public string TreeRowToHtml(TreeListItem row, int rowIdx, int depth, TreeMatrix matrix)//, int level = 0) { var sb = new StringBuilder(); int level = depth - 1; //sb.AppendFormat("<tr class='{0}' expanded='expanded' level='{1}' >", _itemClass, level); sb.AppendFormat("<tr class='{0}' level='{1}' {2} {3}>", _itemClass, level, _closeTree ? "" : "expanded='expanded'", _closeTree && level > 0 ? "style='display:none'" : ""); //选择列 var selectTh = ""; //var depth = GetDepth() - 1; //var selectThRowSpan = depth > 1 ? ("rowspan=" + _rowSpan) : ""; switch (GetSelectMode()) { case PFGrid.SelectMode.Single: case PFGrid.SelectMode.Multi: selectTh = "<td><input type=\"checkbox\" class=\"pf-row-select\"></td>"; break; default: break; } sb.Append(selectTh); //暂时固定第一列为树型列-- int i = 0; if (_header != null) { _header.EachLeaf(h => { var column = _columns.First(c => c.Text == h.Text); sb.Append(TreeCellToHtml(row, rowIdx, level, column, matrix, (_header.FirstLeaf(a => (a).Visible)).Text == column.Text)); if (h.Visible) { i++; } }); } else { _columns.ForEach(column => { sb.Append(TreeCellToHtml(row, rowIdx, level, column, matrix, column == _columns[0])); }); } sb.Append("</tr>"); return(sb.ToString()); }
/// <summary> /// 注意:Model为DataTable时没必要写自动生成列的方法,因为在PFGrid.ColumnsFor方法里循环Table生成也是很简单的 /// </summary> /// <param name="htmlHelper"></param> /// <returns></returns> public MvcHtmlString Html(HtmlHelper htmlHelper) { var sb = new StringBuilder(); ////特性 var htmlAttributes = GetHtmlAttributes(); var sAttributes = ""; foreach (var a in htmlAttributes) { sAttributes += string.Format(" {0}='{1}' ", a.Key, a.Value); } var configMapper = PFDataHelper.GetConfigMapper(); var pathConfig = configMapper.GetPathConfig(); if (htmlHelper.ViewData["hasPFGridCss"] == null) { sb.AppendFormat("<link href=\"/{0}/PFGrid.css\" rel=\"stylesheet\" />", pathConfig.CssPath); htmlHelper.ViewData["hasPFGridCss"] = true; } #region 标题 // if (!string.IsNullOrWhiteSpace(_title)) // { //// sb.AppendFormat(@" //// <tr> //// <td style='' class='txt_86433c_12 pf-grid-head-td' align='left'> //// <strong>◎ {0}</strong> //// </td> //// </tr> ////", _title); // } #endregion 标题 #region 主体table sb.AppendFormat(@"<table {0}>", sAttributes); bool hasData = _model != null && _model.Count > 0; #region 表头 if (hasData) { if (_header != null) { sb.Append(_header.Html(this)); } else { sb.AppendFormat("<thead><tr class='{0}'>", _headClass); _columns.ForEach(c => { var style = c.GetStyle(false); if (!string.IsNullOrWhiteSpace(c.Width)) { style += ";min-width:" + c.Width; } if (!string.IsNullOrWhiteSpace(style)) { style = string.Format("style='{0} '", style); } sb.AppendFormat("<th {1} field-name='{2}' >{0}</th>", c.Text, style, c.DataIndex); //var style = ""; //if (!c.Visible) { style += "display:none;"; } //if (c.Width != null) { style += "width:" + c.Width + ";"; } //if (!string.IsNullOrWhiteSpace(style)) { style = string.Format("style='{0}'", style); } //sb.AppendFormat("<th {1} >{0}</th>", c.Text, style); }); sb.Append("</tr></thead>"); } } #endregion 表头 sb.Append(@"<tbody>"); if (hasData) { #region 行内容 int i = 0; bool isTree = false; foreach (var row in _model) { if (row is TreeListItem) { isTree = true; if (_columns.Any()) { var style = "text-align:left;padding-left:5px;padding-right:5px;white-space:nowrap;"; if (_header != null) { _columns.First(c => c.Text == _header.FirstLeaf(a => a.Visible).Text).SetStyle(style); } else { _columns.First(a => a.Visible).SetStyle(style); } } break; } } if (isTree) { var matrix = new TreeMatrix(_model); foreach (var row in _model) { var tRow = row as TreeListItem; sb.Append(TreeRowToHtml(tRow, i, 1, matrix)); i++; tRow.EachChild((a, b) => { //sb.Append(TreeRowToHtml(tRow, i, b, matrix)); sb.Append(TreeRowToHtml(a, i, b, matrix)); i++; }); } } else { foreach (var row in _model) { sb.Append(RowToHtml(row)); } } #endregion 行内容 } else { sb.AppendFormat("<tr><td>{0}</td></tr>", "无相关数据"); //sb.AppendFormat("<table style='width: 100%;'><tr class='{0}'><td style='text-align:center;color:red'>无相关数据</td></tr></table>", _itemClass); } sb.Append(@"</tbody>"); sb.Append(@"</table>"); #endregion 主体table return(MvcHtmlString.Create(sb.ToString())); }
private string TreeCellToHtml(TreeListItem row, int rowIdx, int level, PFGridColumn column, TreeMatrix matrix, bool isFirstColumn) { var sb = new StringBuilder(); object val = GetCellText(row.Data, column); if (isFirstColumn) { //var css = "tree-tr-hitarea tree-tr-hitarea-expanded"; var css = _closeTree ? "hitarea hitarea-closed" : "hitarea hitarea-expanded"; var line = ""; for (var j = 0; j < level; j++) { //line += string.Format("<div class='{0} {1}'></div>", "tree-tr-linearea ", GetClassByTreeMatrixNetLine(matrix.GetNetLine(j, rowIdx))); line += string.Format("<div class='{0} {1}'></div>", "linearea ", GetClassByTreeMatrixNetLine(matrix.GetNetLine(j, rowIdx))); } val = line + string.Format("<div class='{0}'></div>", css) + val; //前面的GetCellText已经有调用render了,这里就不用了--benjamin20190705 ////sb.AppendFormat("<td {1} onclick='$pf.expandTree(this)'>{0}</td>", val, column.GetStyle()); //if (column.Render != null) //{ // sb.AppendFormat("<td>{0}</td>", column.Render(column, row, (string)val)) ; //} //else //{ sb.AppendFormat("<td>{0}</td>", val);//样式不要加到tbody上,否则页面太大了,onclick事件改到pfTreeTable的init上 //} } else { //if (column.Render != null) //{ // //sb.AppendFormat("<td>{0}</td>", column.Render(column, row, (string)val));//样式不要加到tbody上,否则页面太大了 // sb.AppendFormat("<td {1}>{0}</td>", column.Render(column, row, (string)val), column.GetClassName());//样式不要加到tbody上,否则页面太大了,加上类名的页面大小多了1/23,但为了数字列右对齐 //} //else //{ //sb.AppendFormat("<td {1}>{0}</td>", val, column.GetStyle()); sb.AppendFormat("<td {1}>{0}</td>", val, column.GetClassName());//样式不要加到tbody上,否则页面太大了 //} } return(sb.ToString()); }
public Exporter Export(IExport export) { int i = 0; if (_title == null) { _title = new List <List <StoreColumn> >(); _title.Add(new List <StoreColumn>()); //PFDataHelper.EachListHeader(_data, (i, field, type) => _title[0].Add(new StoreColumn() { title = field, field = field, rowspan = 1, colspan = 1 })); PFDataHelper.EachListHeader(_data, (a, field, type) => _title[0].Add(new StoreColumn() { title = field, data = field //, rowspan = 1, colspan = 1 })); } Dictionary <int, int> currentHeadRow = new Dictionary <int, int>(); Dictionary <string, List <int> > fieldIndex = new Dictionary <string, List <int> >(); int titleRowCount = 0; if (!string.IsNullOrWhiteSpace(_sheetTitle)) { titleRowCount++; } Func <int, int> GetCurrentHeadRow = cell => currentHeadRow.ContainsKey(cell) ? currentHeadRow[cell] : titleRowCount; var currentRow = 0; var currentCell = 0; export.Init(_data, _printPageScheme); //标题--wxj20181011 var temp = new StoreColumn { Children = _columns }; int columnCount = temp.GetAllLeafCount(a => a.visible); var firstData = temp.FirstLeaf(a => true).data; if (!string.IsNullOrWhiteSpace(_sheetTitle)) { export.FillData(0, 0, firstData, _sheetTitle); export.SetTitleStyle(0, 0, columnCount - 1, 0); currentRow++; } //Stopwatch sw = new Stopwatch(); //sw.Start(); //int resultCount = 0; #region 3秒(后来发现只有调试时特别慢,原因未明) ////生成多行题头 for (i = 0; i < _title.Count; i++) { currentCell = 0; for (var j = 0; j < _title[i].Count; j++) { var item = _title[i][j]; if (item.visible == false) { continue; } //隐藏列不导出--wxj20181009 while (currentRow < GetCurrentHeadRow(currentCell)) { currentCell++; } //export.FillData(currentCell, currentRow, "title_" + item.data, item.title); export.FillData(currentCell, currentRow, "title_" + item.data, item.title ?? item.data);//e:\svn\businesssys2018\yjquery.web\areas\bonus\views\reportquery05\treegrid.cshtml里的title是null if (item.rowspan + item.colspan > 2) { export.MergeCell(currentCell, currentRow, currentCell + item.colspan - 1, currentRow + item.rowspan - 1); } if (!string.IsNullOrEmpty(item.data)) { if (!fieldIndex.ContainsKey(item.data)) { fieldIndex[item.data] = new List <int>(); } fieldIndex[item.data].Add(currentCell); } for (var k = 0; k < item.colspan; k++) { currentHeadRow[currentCell] = GetCurrentHeadRow(currentCell++) + item.rowspan; } //resultCount++; } currentRow++; } #endregion #region 一样是3秒 ////生成多行题头 //foreach (var ii in _title) //{ // currentCell = 0; // foreach (var j in ii) // { // //var item = _title[i][j]; // var item = j; // if (item.visible == false) { continue; }//隐藏列不导出--wxj20181009 // //if (item.hidden) continue; // while (currentRow < GetCurrentHeadRow(currentCell)) // currentCell++; // //export.FillData(currentCell, currentRow, "title_" + item.data, item.title); // export.FillData(currentCell, currentRow, "title_" + item.data, item.title ?? item.data);//e:\svn\businesssys2018\yjquery.web\areas\bonus\views\reportquery05\treegrid.cshtml里的title是null // if (item.rowspan + item.colspan > 2) // export.MergeCell(currentCell, currentRow, currentCell + item.colspan - 1, currentRow + item.rowspan - 1); // if (!string.IsNullOrEmpty(item.data)) // { // if (!fieldIndex.ContainsKey(item.data)) // fieldIndex[item.data] = new List<int>(); // fieldIndex[item.data].Add(currentCell); // } // for (var k = 0; k < item.colspan; k++) // currentHeadRow[currentCell] = GetCurrentHeadRow(currentCell++) + item.rowspan; // } // currentRow++; //} #endregion //sw.Stop(); //var aa = string.Format("插入{0}条记录共花费{1}毫秒,{2}分钟", resultCount, sw.ElapsedMilliseconds, sw.ElapsedMilliseconds / 1000 / 60); //设置题头样式 //export.SetHeadStyle(0, 0, currentCell - 1, currentRow - 1); export.SetHeadStyle(0, titleRowCount, currentHeadRow.Count - 1, currentRow - 1);//上面那样,当后面的列不是多表头时,背景色只填到最后一个多表头为止 ////设置数据样式 var dataCount = 0; if (_data is PagingResult) { var data = _data as PagingResult; var list = data.data as ArrayList; if (list != null) { for (var rowIndex = 0; rowIndex < list.Count; rowIndex++) { dataCount++; } } else { var list1 = data.data as List <TreeListItem>; if (list1 != null) { (new TreeListItem { Children = list1 }).EachChild(a => dataCount++); } } } else { PFDataHelper.EachListRow(_data, (a, r) => dataCount++);//原版 } ////export.SetRowsStyle(0, currentRow, currentCell - 1, currentRow + dataCount - 1); //此句内报错,要优化--benjamin todo if (!PFDataHelper.IsDebug) { export.SetRowsStyle(0, currentRow, currentHeadRow.Count - 1, currentRow + dataCount - 1);//上面那样,当后面的列不是多表头时,边框不见了 } //填充数据 if (_data is PagingResult) { var data = _data as PagingResult; if (data.data is List <TreeListItem> ) { export.SetFont(0, currentRow, 0, currentRow + dataCount - 1, "宋体");//默认的Arial字体中,树型的┝等符号对不齐--benjamin20190711 var tree = new TreeListItem(); tree.Children = data.data as List <TreeListItem>; int rowIndex = 0; //int colIndex = 0; var matrix = new TreeMatrix(tree.Children); tree.EachChild((a, deep) => { //colIndex = 0; PFDataHelper.EachObjectProperty(a.Data, (b, name, value) => { if (fieldIndex.ContainsKey(name)) { foreach (int cellIndex in fieldIndex[name]) { if (_fieldFormatter.ContainsKey(name)) { value = _fieldFormatter[name].Format(value); } //if (colIndex == 0) if (cellIndex == 0) { var line = ""; for (var j = 0; j < deep - 2; j++) { //line += string.Format("<div class='{0} {1}'></div>", "tree-tr-linearea ", GetClassByTreeMatrixNetLine(matrix.GetNetLine(j, rowIdx))); line += matrix.GetNetLineString(j, rowIndex); } value = line + PFDataHelper.ObjectToString(value); //var line = GetClassByTreeMatrixNetLine(matrix.GetNetLine(cellIndex, currentRow)) } export.FillData(cellIndex, currentRow, name, value); } //colIndex++; } }); rowIndex++; currentRow++; }); } else { var list = data.data as ArrayList; for (var rowIndex = 0; rowIndex < list.Count; rowIndex++) { var rowData = list[rowIndex] as Dictionary <string, object>; for (i = 0; i < rowData.Count; i++) { var name = rowData.ElementAt(i).Key; var value = rowData.ElementAt(i).Value; if (fieldIndex.ContainsKey(name)) { foreach (int cellIndex in fieldIndex[name]) { if (_fieldFormatter.ContainsKey(name)) { value = _fieldFormatter[name].Format(value); } export.FillData(cellIndex, currentRow, name, value); } } } currentRow++; } } } else { //原版 PFDataHelper.EachListRow(_data, (rowIndex, rowData) => { PFDataHelper.EachObjectProperty(rowData, (a, name, value) => { if (fieldIndex.ContainsKey(name)) { foreach (int cellIndex in fieldIndex[name]) { if (_fieldFormatter.ContainsKey(name)) { value = _fieldFormatter[name].Format(value); } export.FillData(cellIndex, currentRow, name, value); } } }); currentRow++; }); } //汇总行 bool hasSummary = false; i = 0; int firstSummary = 0;//第一个有汇总的格的位置 string firstSummaryField = ""; new StoreColumn { Children = _columns }.EachLeaf(a => { //设置列宽--wxjtodo20190417 if (!PFDataHelper.StringIsNullOrWhiteSpace(a.width)) { //export.SetColumnWidth(i, PFDataHelper.WebWidthToExcel(a.width).Value); export.SetColumnWidth(i, a.width); } //if (a.excelWidth.HasValue) //{ // export.SetColumnWidth(i, double.Parse(a.width.Replace("px", ""))); //} //var column = _title[_title.Count - 1][i]; if (a.visible) { var column = a; if (!hasSummary) { firstSummary = i; firstSummaryField = column.data; } if (column.summary != null) { hasSummary = true; export.FillData(i, currentRow, column.data, column.summary); } i++; } }); if (hasSummary) { export.FillData(firstSummary - 1, currentRow, firstSummaryField, "合计:"); export.SetRowsStyle(0, currentRow, columnCount - 1, currentRow);//上面那样,当后面的列不是多表头时,边框不见了 currentRow++; } //Foot--wxj20181011 if (!string.IsNullOrWhiteSpace(_sheetFoot)) { export.FillData(0, currentRow, firstData, _sheetFoot); export.SetFootStyle(0, currentRow, columnCount - 1, currentRow); //titleRowCount++; currentRow++; } _exporter = export; //_fileStream = export.SaveAsStream(); _suffix = export.suffix; if (string.IsNullOrEmpty(_fileName)) { _fileName = DateTime.Now.ToString("yyyyMMddHHmmss"); } return(this); }