目标:从DevExpress SpreadsheetControl中导入数据、表格、图表至DevExpress RicheditControl 中的word模板里。(DevExpress版本号15.1.7)
功能:
1、RicheditControl导入Word已制作的文档模板(word做模板毕竟快捷方便),导入格式为rtf。
2、RicheditControl中插入书签,利用bookmark定位导入数据位置。
3、书签种类不同应对将来数据等插入方式。所以需要单独维护存储一套书签列表信息,并保持与文件本身书签列表对应关系。利用bookmark.Name作为外键。
4、最终rtf文件内容和单独书签列表皆以二进制序列化方式存储。
问题及解决办法:
问题1、向RicheditControl中导入doc或docx文件时会出现中文字体全部从宋体转换为方正姚体。
解决办法:设置了RicheditControl的默认字体为宋体,代码如下
DevExpress.XtraRichEdit.RichEditControlCompatibility.DefaultFontName = "宋体"; DevExpress.XtraRichEdit.RichEditControlCompatibility.DefaultFontSize = 11;
这一步未解决问题。最终发现导入rtf格式文件时字体仍保持原样,因此规定只能采用rtf格式。
另外发现,如果导入doc文件时,如果在RicheditControl中重新设置一次字体后,保存再打开,字体未变化为方正姚体,说明DevExpress对中文兼容性还是有问题,这也是用这个控件操作中文时最大的问题。
问题2:书签插入时Name满足标识符起名规则。
解决办法:System.Guid.NewGuid().ToString("N")加特定前缀。
问题3:显示全部书签。
解决办法:为了明确显示书签及含义,采用如下示例代码显示书签
richEditControl1.Options.Bookmarks.Visibility = RichEditBookmarkVisibility.Visible; richEditControl1.Options.Bookmarks.Color = Color.Red; string name = System.Guid.NewGuid().ToString("N"); int start = richEditControl1.Document.Selection.Start.ToInt(); int length = name.Length; richEditControl1.Document.Replace(richEditControl1.Document.Selection, name); Bookmark bookmark = richEditControl1.Document.Bookmarks.Create(richEditControl1.Document.CreatePosition(start),length, name);
问题4:将来用户会对已插入书签的模板做二次编辑,因此需要考虑对模板中特定部分保护,禁止编辑。
解决办法:基本原理利用RicheditControl的Protect 和 Permission。对全文保护,然后根据组别和用户控制可编辑的Range区域。从而控制只有一级管理员可全文编辑,二级用户只能编辑特定区域。示例代码如下
private void barButtonItem3_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { RangePermissionCollection rangePermissions = richEditControl1.Document.BeginUpdateRangePermissions(); rangePermissions.AddRange(CreateRangePermissions(richEditControl1.Document.CreateRange(0, 15), String.Empty, "all"));//Editors richEditControl1.Document.EndUpdateRangePermissions(rangePermissions); RangePermissionCollection rangePermissionspart = richEditControl1.Document.BeginUpdateRangePermissions(); rangePermissionspart.AddRange(CreateRangePermissions(richEditControl1.Document.CreateRange(8, 3), String.Empty, "part"));//Editors richEditControl1.Document.EndUpdateRangePermissions(rangePermissionspart); // Enforce protection and set password. richEditControl1.Document.Protect("123"); //richEditControl1.Options.Authentication.UserName = "part"; //richEditControl1.Options.Authentication.Group = String.Empty; }
private static List<RangePermission> CreateRangePermissions(DocumentRange range, string userGroup, params string[] usernames) { List<RangePermission> rangeList = new List<RangePermission>(); foreach (string username in usernames) { RangePermission rp = new RangePermission(range); rp.Group = userGroup; rp.UserName = username; rangeList.Add(rp); } return rangeList; }
问题5:RicheditControl中Table的基本遍历方式
解决办法:示例代码如下:
DocumentPosition documentPosition = richEditControl1.Document.CreatePosition(bookmark.Range.Start.ToInt()); TableCell tableCell = richEditControl1.Document.Tables.GetTableCell(documentPosition); Table table = tableCell.Table; table.ForEachCell(new TableCellProcessorDelegate(delegate(TableCell cell, int rowIndex, int cellIndex) { richEditControl1.Document.InsertText(cell.Range.Start, string.Format("{0}:{1}", rowIndex, cellIndex)); }));
问题6:从Spreadsheet中导入Chart图片到RicheditControl指定位置。
解决办法:示例代码如下:
Form6中包含spreadsheetControl,其中某个按钮事件代码如下
public Image Image { get; set; } private void barButtonItem2_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { DevExpress.Office.Utils.OfficeImage image = spreadsheetControl1.ActiveWorksheet.Charts[0].GetImage(); Image = image.NativeImage; }
当前窗体按钮事件代码如下
private void barButtonItem4_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { Form6 form6 = new Form6(); form6.ShowDialog(); Image image = form6.Image; richEditControl1.Document.Images.Insert(richEditControl1.Document.CreatePosition(richEditControl1.Document.Selection.Start.ToInt()), image); }