/// <summary> /// export file by template and row /// </summary> /// <param name="tplPath">tpl path</param> /// <param name="fileName">export file name</param> /// <param name="row"></param> /// <param name="childs">IEnumerable for anonymous type</param> /// <param name="images"></param> /// <returns>error msg if any</returns> public static async Task <bool> ExportByTplRowAsync(string tplPath, string fileName, dynamic row, List <IEnumerable <dynamic> > childs = null, List <WordImageDto> images = null) { #region 1.check template file if (!File.Exists(tplPath)) { await _Log.ErrorAsync($"_WebWord.cs ExportByTplRow() no tpl file ({tplPath})"); return(false); } #endregion #region 2.prepare memory stream var ms = new MemoryStream(); var tplBytes = File.ReadAllBytes(tplPath); ms.Write(tplBytes, 0, tplBytes.Length); #endregion //3.binding stream && docx var fileStr = ""; using (var docx = WordprocessingDocument.Open(ms, true)) { //initial var wordSet = new WordSetService(docx); var mainStr = wordSet.GetMainPartStr(); //4.add images first if (images != null) { mainStr = await wordSet.AddImagesAsync(mainStr, images); } //get word body start/end pos //int bodyStart = 0, bodyEnd = 0; //no start/end tag var bodyTpl = await wordSet.GetBodyTplAsync(mainStr); #region 5.fill row && childs rows var hasChild = (childs != null && childs.Count > 0); if (hasChild) { var childLen = childs.Count; int oldStart = 0, oldEnd = 0; for (var i = 0; i < childLen; i++) { //int rowStart = 0, rowEnd = 0; var rowTpl = await wordSet.GetRowTplAsync(bodyTpl.TplStr, i); if (rowTpl.TplStr == "") { continue; } //set head or add left string of rows if (i == 0) { fileStr = _Word.TplFillRow(bodyTpl.TplStr[..rowTpl.StartPos], row);
/// <summary> /// generate database word document /// </summary> /// <param name="projectId"></param> /// <param name="tableIds"></param> /// <return>error msg if any</return> public async Task <bool> RunAsync(string projectId, string[] tableIds = null) { #region 1.check input & template file var error = ""; if (_Str.IsEmpty(projectId) && (tableIds == null || tableIds.Length == 0)) { error = "ProjectId & TableIds are need."; goto lab_error; } //var locale = _Fun.GetLocale(); var tplPath = _Xp.GetTplPath("Table.docx", true); if (!File.Exists(tplPath)) { error = "no file " + tplPath; goto lab_error; } #endregion #region 2.read column rows & group by var db = _Xp.GetDb(); var query = (from c in db.Column join t in db.Table on c.TableId equals t.Id join p in db.Project on t.ProjectId equals p.Id where (c.Status && t.Status) select new { c, t, p } ); //add where condition if (!_Str.IsEmpty(projectId)) { query = query.Where(a => a.t.ProjectId == projectId); } if (tableIds != null && tableIds.Length > 0) { query = query.Where(a => tableIds.Contains(a.t.Id)); } var tables = query .Select(a => new { ProjectCode = a.p.Code, TableCode = a.t.Code, TableName = a.t.Name, a.c.Code, a.c.Name, a.c.DataType, Nullable = a.c.Nullable ? "Y" : "", a.c.DefaultValue, a.c.Note, //docx template file use "S" as field name for less space !! S = a.c.Sort, }) .ToList() .GroupBy(a => new { a.ProjectCode, a.TableCode, a.TableName }) .OrderBy(a => a.Key.TableCode) .Select(a => new { a.Key.ProjectCode, a.Key.TableCode, a.Key.TableName, Cols = a.OrderBy(b => b.S).ToList(), }) .ToList(); var tableLen = tables.Count; if (tableLen == 0) { error = "No table found"; goto lab_error; } #endregion #region 3.get memory stream for download file var ms = new MemoryStream(); var tplBytes = File.ReadAllBytes(tplPath); ms.Write(tplBytes, 0, tplBytes.Length); #endregion //binding stream && docx using (var docx = WordprocessingDocument.Open(ms, true)) { #region 4.get body/row template string var wordSet = new WordSetService(docx); var mainTplStr = wordSet.GetMainPartStr(); //get word body start/end pos //int bodyStart = 0, bodyEnd = 0; //no start/end tag var bodyTpl = await wordSet.GetBodyTplAsync(mainTplStr); //get row template string //int rowStart = 0, rowEnd = 0; var rowTpl = await wordSet.GetRowTplAsync(bodyTpl.TplStr); if (rowTpl == null) { error = "can not find rowTpl String."; goto lab_error; } #endregion //table list loop var bodyLeft = bodyTpl.TplStr[..rowTpl.StartPos];