场景:在实际开发过程中,特别是接口对接之类的,对于这种需求是屡见不鲜,现在很多在线平台也都提供了像json转实体、sql转实体等。但是很多情况下,我们接收到的其实都是一份接口文档,在文档中利用表格标明了字段的名称、备注、类型等,而关于json什么的都是后来才有的,或者说,传输根本不用json。因此,表格数据能够转成实体类的需求就比较明显了。
需求:所以,综上场景所述,我们需要一个小工具,可以将表格数据直接转换为c#代码,当然,本着通用化的思想,小工具当然不会单纯的做一个读取excel文件的功能,这样一点也不好用,因为由其他地方提供的文档有的是excel,有的是word,所以,我们利用剪切板来做,只要解析剪切板的数据就可以了。
开发环境:.NET Framework版本:4.7.2
开发工具: Visual Studio 2022
实现代码:
- 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///
" ; - readonly string endDesc = "\t\t/// ";
-
-
- 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中。