场景:在实际开发过程中,特别是接口对接之类的,对于这种需求是屡见不鲜,现在很多在线平台也都提供了像json转实体、sql转实体等。但是很多情况下,我们接收到的其实都是一份接口文档,在文档中利用表格标明了字段的名称、备注、类型等,而关于json什么的都是后来才有的,或者说,传输根本不用json。因此,表格数据能够转成实体类的需求就比较明显了。
需求:所以,综上场景所述,我们需要一个小工具,可以将表格数据直接转换为c#代码,当然,本着通用化的思想,小工具当然不会单纯的做一个读取excel文件的功能,这样一点也不好用,因为由其他地方提供的文档有的是excel,有的是word,所以,我们利用剪切板来做,只要解析剪切板的数据就可以了。.
开发环境:.NET Framework版本:4.5
开发工具: Visual Studio 2013
实现代码:
public class GeneratorFieldModel{public string FieldDesc { get; set; }public string Modifier { get { return "public"; } }public string Type { get; set; }public string FieldName { get; set; }public string Property { get { return "{ get; set; }"; } }public bool IsNull { get; set; }public bool IsKey { get; set; }public string DefaultText { get; set; }readonly string startDesc = "\t\t/// <summary>";readonly string endDesc = "\t\t/// </summary>";public string FieldDescText{get{List<string> list = new List<string>();list.Add(startDesc);list.Add("\t\t///" + FieldDesc + "");list.Add(endDesc);return "\r\n" + string.Join("\r\n", list);}}public string PropertyText{get { return "\t\t" + string.Join(" ", Modifier, Type + (IsNull ? "?" : ""), FieldName, Property); }}}
public partial class Form_ToEntity : Form{BindingList<Entity> bindData = new BindingList<Entity>();public Form_ToEntity(){InitializeComponent();}private void Form_ToEntity_Load(object sender, EventArgs e){string[] types = new string[]{"string","decimal","double","int","bool","long"};DataGridViewComboBoxColumn dgvComboBox = Column2 as DataGridViewComboBoxColumn;dgvComboBox.Items.AddRange(types);dataGridView1.DataSource = bindData;}#region 处理点击选中着色private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e){DataGridViewColumn selectColumn = dataGridView1.Columns[e.ColumnIndex];Color color = selectColumn.DefaultCellStyle.BackColor == Color.LightGray ? Color.White : Color.LightGray;selectColumn.DefaultCellStyle.BackColor = color;selectColumn.HeaderCell.Style.BackColor = color;selectColumn.Tag = color;}private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e){if (e.RowIndex == -1 && e.ColumnIndex > -1){DataGridViewColumn selectColumn = dataGridView1.Columns[e.ColumnIndex];Color color = selectColumn.Tag == null ? Color.White : (Color)selectColumn.Tag;e.CellStyle.BackColor = color;}}#endregion/// <summary>/// 获取剪切板数据/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void dataGridView1_KeyDown(object sender, KeyEventArgs e){if (e.Control && e.KeyCode == Keys.V){try{string text = Clipboard.GetText();if (string.IsNullOrWhiteSpace(text)){return;}string[] clipData = text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);bindData = Clip2Entity(clipData);dataGridView1.DataSource = new BindingList<Entity>(bindData);}catch (Exception ex){MessageBox.Show(ex.Message);}}}/// <summary>/// 将剪切板数据转换为表格数据/// </summary>/// <param name="data"></param>/// <returns></returns>private BindingList<Entity> Clip2Entity(string[] data){BindingList<Entity> list = new BindingList<Entity>();foreach (string s in data){Entity entity = new Entity();string[] arr = s.Split('\t');if (arr.Length == 2){//选中名称和类型if (isCheck(dataGridView1.Columns[0]) && isCheck(dataGridView1.Columns[1])){entity.name = arr[0];entity.type = arr[1].ToLower();entity.remark = "";}//选中名称和备注if (isCheck(dataGridView1.Columns[0]) && isCheck(dataGridView1.Columns[2])){entity.name = arr[0];entity.type = "string";entity.remark = arr[1];}//选中类型和备注if (isCheck(dataGridView1.Columns[1]) && isCheck(dataGridView1.Columns[2])){entity.name = "";entity.type = arr[0].ToLower();entity.remark = arr[1];}}else if (arr.Length == 3){entity.name = arr[0];entity.type = arr[1].ToLower();entity.remark = arr[2];}else{if (isCheck(dataGridView1.Columns[0])){entity.name = s;entity.type = "string";entity.remark = "";}else if (isCheck(dataGridView1.Columns[1])){entity.name = "";entity.type = s.ToLower();entity.remark = "";}else if (isCheck(dataGridView1.Columns[2])){entity.name = "";entity.type = "string";entity.remark = s;}}list.Add(entity);}return list;}/// <summary>/// 判断列是否被选中/// </summary>/// <param name="column"></param>/// <returns></returns>private bool isCheck(DataGridViewColumn column){if (column.DefaultCellStyle.BackColor == Color.LightGray){return true;}else{return false;}}private class Entity{public string name { get; set; }public string type { get; set; }public string remark { get; set; }}private void btn_add_Click(object sender, EventArgs e){bindData.Add(new Entity{type = "string"});}private void btn_delete_Click(object sender, EventArgs e){foreach (DataGridViewRow row in dataGridView1.SelectedRows){dataGridView1.Rows.Remove(row);}}private void btn_generate_Click(object sender, EventArgs e){StringBuilder stringBuilder = new StringBuilder();foreach (Entity entity in bindData){GeneratorFieldModel field = new GeneratorFieldModel{FieldName = entity.name,FieldDesc = entity.remark,Type = entity.type};stringBuilder.AppendLine(field.FieldDescText);stringBuilder.AppendLine(field.PropertyText);}string path = Application.StartupPath + "\\entity.txt";File.WriteAllText(path, stringBuilder.ToString());Process.Start(path);}}
实现效果:

代码解析:首先我们定义了一个GeneratorFieldModel类,在这个类中根据不同的字段属性进行了代码的拼接,这样就可以很方便的调用,直接把值传进去即可得到要生成的实体代码,然后在Ui中,首先处理了一下选中变色(标识我们要处理哪些数据列),然后就是分析剪切板数据,转化成需要的结构化数据(表格复制到剪切板的数据,其实就是以"\r\n"来分割的),显示到dataGridView中。