这几天一直在研究TX Text Control的使用,由于这方面的资料相对比较少,主要靠下载版本的案例代码进行研究,以及官方的一些博客案例进行学习,使用总结了一些心得,特将其总结出来,供大家分享学习。本篇随笔主要介绍TX Text Control V20的相关使用心得。
TX Text Control是一款功能类似于 MS Word 的文字处理控件,包括文档创建、编辑、打印、邮件合并、格式转换、拆分合并、导入导出、批量生成等功能。广泛应用于企业文档管理,网站内容发布,电子病历中病案模板创建、病历书写、修改历史、连续打印、病案归档等功能的实现。
这个控件主要的功能就是可以作为Word以及其他文档的编辑器使用,虽然展示WORD内容的控件也有一些,如我们可以利用DevExpress里面的RTF文档编辑器来实现,同样运行的很好,结合Aspose.Word后台的文档处理,我们可以做到类似报表的数据生成,而且可以把生成后的文档进行显示、编辑等操作处理。
TX Text Control虽然作为文档编辑各方面都表现不错,不过其MailMerge邮件合并功能还是经常使用的一个功能,就是把我们的数据和文档模板来一个合并,然后显示最终的文档内容,这种可以用来做一些类似发票、邮件、员工信息等的数据处理和显示,MailMerge邮件合并可以绑定主从表的数据,能够符合大多数的要求。
我本来想用它做一个类似电子病历一样的功能模块,不说在文档里面,我们很难做到一些下拉列表的处理( 官方博客里面有一个简单的案例,不过不好用),一般情况下,如果我们只是做文档展示、数据合并等常规的操作,还是很不错的。
这个控件的功能介绍,可以参考葡萄城里面的网页介绍(http://www.gcpowertools.com.cn/products/textcontrol_winform_features.htm),这个控件的相关开发人员使用然后分享经验的文章很少,能在网上搜到的大多数是葡萄城人员对这个控件的Demo代码进行一个简单粘贴说明,没有进一步的深入介绍和应用场景的介绍。虽然葡萄城列举了几个电子病历的公司产品案例,不过这几家公司的电子病历产品是很难下载到,也无从知道真假或者使用情况。
这几天我把这个控件的各种特性做了一些学习,并重新把官网的文档编辑例子进行了全新开发,参考着做了一个完全一样的编辑器版本,也基本上对它的各个属性、方法处理有了一个更加深入的了解。
我们先通过一个软件界面来了解整个软件的一些功能(这个是我仿照官方案例做的一个程序)。
这个控件默认安装后,会带有很多Demo案例,具体可以参考目录C:\Users\Administrator\Documents\TX Text Control 20.0.NET for Windows Forms\Samples\ 进行了解。
这个控件界面默认是英文版本的,控件的相关菜单以及提示都是英文,因此我们需要对资源做一些中文本地化处理才能正确显示。
官方没有提供中文汉化包,只提供一个标准的英文资源,如下所示。
我们需要做的就是将它们进行中文翻译,然后重新编译(使用buildres.bat脚本编译)为中文资源dll。
我们先使用VS编辑工具,把这些英文资源记录转换为英文(这是一个比较繁琐的工作,官方网站上有一些旧版本的中文包可供参考,以及最新的V20软件(编辑器软件)下载下来运行参考)。
我们逐一进行中文处理,可以使用百度、Google的翻译,以及软件界面的参考哦。
以管理员方式运行VS的命令行,然后执行命令进行编译资源即可。
buildres.bat zh-CN
编译成功后,在目录里面,会增加两个资源程序集。
txdocumentserver.resources.dll
txtextcontrol.resources.dll
然后我们把它复制到运行目录下,并放在zh-CN的目录里面即可。有了这些中文化的资源程序集,我们就可以利用它进行对控件的内置菜单提示进行中文化了。
中文化操作和其他常规的做法一样,我们在Main函数里面,添加如下代码即可。
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN"); Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("zh-CN");
运行程序,我们使用右键菜单,发现里面的资源都已经正常汉化了,其他相关的内置菜单和界面也都可以看到正常汉化。
有了汉化,只是我们正常使用控件的第一步,我们需要在程序里面整合控件,那么就需要对它进行使用,以及对控件的属性、事件进行处理,才能得到最佳的应用效果。
我们在VS工具栏里面加入对应的控件,可以看到有以下相关的控件对象可供使用,一般情况下我们使用TextControl,然后在其基础上创建其他RulerBar、ButtonBar、StatusBar即可,而如果我们需要合并数据(很常用)就需要加入MailMerge控件对象。
添加控件后,我们可以对控件的相关基础的复制、粘贴、剪切等操作可以直接利用控件的API即可实现。
private void menuEdit_Undo_Click(object sender, EventArgs e) { _textControl.Undo(); } private void menuEdit_Redo_Click(object sender, EventArgs e) { _textControl.Redo(); } private void menuEdit_Cut_Click(object sender, EventArgs e) { _textControl.Cut(); }
其中查找、替换对话框也是可以通过API进行调出。
private void menuEdit_Find_Click(object sender, EventArgs e) { _textControl.Find(); } private void menuEdit_Replace_Click(object sender, EventArgs e) { _textControl.Replace(); }
利用这些最基础的API是常规的操作。
而利用插入相关的对象,如图片、文本框等,就需要做一些简单的编码,方便把对象加入到TextControl对象里面。
private void menuInsert_Image_Click(object sender, EventArgs e) { TXTextControl.Image imageNew = new TXTextControl.Image(); _textControl.Images.Add(imageNew, TXTextControl.HorizontalAlignment.Left, -1, TXTextControl.ImageInsertionMode.DisplaceText); } private void menuInsert_TextFrame_Click(object sender, EventArgs e) { try { // Force Exception if standard version: _textControl.TextFrames.GetItem(); Size sizeTextFrame = new Size(2268, 2268); // 4 x 4 cm TXTextControl.TextFrame textFrameNew = new TXTextControl.TextFrame(sizeTextFrame); _textControl.TextFrames.Add(textFrameNew, TXTextControl.HorizontalAlignment.Left, -1, TXTextControl.TextFrameInsertionMode.DisplaceCompleteLines); } catch (Exception ex) { MessageBox.Show(ex.Message, ProductName); } }
这个控件最常见的就是MailMerge进行合并数据的操作了,这个也是我们利用它来处理很多模板化文档的目的。
MailMerge对象合并数据的操作,主要是接受集合对象或者是DataTable对象,所以我们必须将我们的数据转换为这种格式,否则合并数据得不到要的结果。
合并数据的处理方式,最开始就是需要设计好模板,这点很重要,模板的设计还是沿用了常规Word文档域对象的概念,需要添加一些域来做后续数据替换的对象占位符,如下是我测试的一个模板。
这个里面主要是主从表整合的一个模板,我们需要绑定常规的主表记录,也需要绑定明细表的集合记录,不过最后我们都需要把数据对象转换为集合(如DataSet),然后才能绑定到文档对象上去。
在上面的文档里面,你知识看到了域对象,而没有看到一个隐藏的一个集合记录的开始和结束的书签设置。关于书签的作用和如何操作,可以了解我之前的随笔文章《利用Aspose.Word控件实现Word文档的操作》、《利用Aspose.Word控件和Aspose.Cell控件,实现Word文档和Excel文档的模板化导出》
书签的作用很重要,否则无法正常解析集合的记录并绑定在WORD界面上的,我们打开书签管理对话框,可以看到上述文档里面有两个位置,书签标记的开始和结束位置。
这样我们设计好模板后,第二步就是通过代码生成相关对象,然后和文档进行合并就可以了。
例如我构建一个主表和一个从表的记录,统一把它们生成一个DataSet对象供使用。
public static DataSet CreateDataSet() { DataSet ds = new DataSet(); DataTable dtMain = DataTableHelper.CreateTable("Company,HandNo,Creator,CreateTime|DateTime"); dtMain.TableName = "main"; DataRow dr = dtMain.NewRow(); dr["Company"] = "广州爱奇迪软件科技有限公司"; dr["HandNo"] = "123456"; dr["Creator"] = "伍华聪"; dr["CreateTime"] = DateTime.Now; dtMain.Rows.Add(dr); DataTable dt = DataTableHelper.CreateTable("ID,ProductName,Description,Price|decimal,Quantity|int"); dt.TableName = "ProductInfo"; dr = dt.NewRow(); dr["ID"] = "1"; dr["ProductName"] = "海飞丝洗发水"; dr["Description"] = "海飞丝洗发水, 550ml"; dr["Price"] = 19.8M; dr["Quantity"] = 100; dt.Rows.Add(dr); dr = dt.NewRow(); dr["ID"] = "2"; dr["ProductName"] = "联想品牌电脑"; dr["Description"] = "联想Y700-15ISK-ISE 旗舰版"; dr["Price"] = 6500M; dr["Quantity"] = 10; dt.Rows.Add(dr); dr = dt.NewRow(); dr["ID"] = "3"; dr["ProductName"] = "IPhone7 128G"; dr["Description"] = "苹果IPhone7, 128G"; dr["Price"] = 5800M; dr["Quantity"] = 10; dt.Rows.Add(dr); ds.Tables.Add(dtMain); ds.Tables.Add(dt); return ds; }
先加载模板文档
if (setting == null) { setting = new TXTextControl.LoadSettings(); setting.ApplicationFieldFormat = TXTextControl.ApplicationFieldFormat.MSWord; } _textControl.Load(Application.StartupPath + "\\Template\\template1.docx", TXTextControl.StreamType.WordprocessingML, setting);
整合合并数据
DataSet ds = PurchaseInfoHelper.CreateDataSet(); mailMerge1.MergeBlocks(ds); mailMerge1.Merge(ds.Tables["main"], true);
最后就可以看到我们所需要的结果了。
当然,如果很熟悉Aspose.Word控件的使用,我们其实也可以利用Aspose.Word控件来做后台的数据整合处理,Aspose.Word控件支持很多变量定义,以及更加复杂的处理,如我把原来在框架模块里面的人员信息导出Word功能抽取出来,这个模块原先是利用Aspose.Word来处理数据合并的,我不修改其中的逻辑,只是把合并后的数据展示在TX Text Control即可,如下代码所示。
var saveFile = StaffHelper.GenerateDoc(); //加载文档 _textControl.Load(saveFile, StreamType.MSWord);
最后就生成了我们开始介绍的软件界面效果。
这个控件目前使用起来还算不错,不过对于一些数据源的处理方面,以后希望继续增加更多的接口,继续保持观察,希望能将研究的成果用在具体的项目上。