系列文章
【C#】代码模板生成工具
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126890673
【C#】MySQL数据库导入工具(批量Excel插入)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126427323
【C#】简单二维码制作和打印工具
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126884228
【C#】最全单据打印源码(打印模板、条形码&二维码、字体样式、logo)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129415723
【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787
目录
我能抽象出整个世界,但是我不能抽象你。 想让你成为私有常量,这样外部函数就无法访问你。 又想让你成为全局常量,这样在我的整个生命周期都可以调用你。 可惜世上没有这样的常量,我也无法定义你,因为你在我心中是那么的具体。
哈喽大家好,本专栏为【项目实战】专栏,有别于【底层库】专栏,我们可以发现增加 了『问题描述』、『项目展示』章节,十分符合项目开发流程,让读者更加清楚项目解决的问题、以及产品能够达到的效果。本专栏收纳项目开发过程的解决方案,是我项目开发相对成熟、可靠方法的提炼,我将这些问题的解决思路梳理,撰写本文分享给大家,大家遇到类似问题,可按本文方案处理。
本专栏会持续更新,不断完善,专栏文章关联性较弱(文章之间依赖性较弱,没有阅读顺序)。如果您对本专栏感兴趣,持续关注吧,我将带你用最简洁的代码,实现复杂的功能。大家有任何问题,可以评论区反馈,私信我。
·提示:本专栏为项目实战篇,未接触项目开发的同学可能理解困难,不推荐阅读。

今天,我完成了【Excel导入工具】第一版,测试成功。本文主要和大家分享一下,我为什么要开发这个工具?
我司推进【条码管理】,一来提高信息化水平,二来方便录入单据,此时就需要有个强大的后台库,能联想到用户想要录入的数据,或者说能够让用户“以选代输”,更加快捷、准确制单。
我们是没有基础库的,但是公司有使用用友U8产品,所有U8中的基础数据可行。经协商,他们只肯开放API数据接口给我们。所以,我决定新建数据库,将数据导入我们的库中,为啥不直连呢?一是,我们为了明确职责,不希望扯皮,不影响原U8服务器性能;二是,用友物理库还是不肯开放给我们的,涉及保密可以理解。

好了,上面是我遇见的情况,其实基础数据建档工作,你们肯定也有做过,我觉得会有如下几种情况:
我的想法是开发一个工具,可以将Excel表格转化成SQL插入语句,这样我们拿SQL语句放数据库里一执行就成功了。
我暗自定了几点要求:
C#窗体,第一步总是先设计界面。你们参考我,设计的界面吧。
主页面:

配置界面

创建类ExcelHelper.cs,实现将Excel中sheet数据读取,并转换转换成DataTable格式。
请阅读下文:
C#底层库--Excel数据读取类(可读加密表格)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/126887445
创建类AppConfig.cs,实现【配置】界面,参数的读取和写入。
请阅读下文:
C#底层库--XML配置参数读写辅助类(推荐阅读)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129175304
创建类CodeFactory.cs,实现SQL Insert 语句的生成,请复制以下代码:
- using System;
- using System.Data;
- using System.Text;
-
- namespace ExcelImportTool
- {
- public static class CodeFactory
- {
- ///
- /// 创建Insert语句(采用分批处理)
- ///
- /// DataTable
- /// 数据库表名
- /// 每批数量
- ///
- public static string CreateInsertSQLBatch(DataTable a_dtSource, string a_strTableName,int a_intBatchNum)
- {
- //insert语句
- string str_Insert = $"INSERT INTO {a_strTableName} ({GetColumnsByDataTable(a_dtSource)})";
-
- bool l_bflag = false;
- StringBuilder str_builder = new StringBuilder();
-
- //表格总行数
- int int_RowCount = a_dtSource.Rows.Count;
- //select语句,采用for循环便于计算行数
- for (int i = 0; i < int_RowCount; i++)
- {
- if (i % a_intBatchNum == 0)
- {
- if (l_bflag)
- {
- //以分号结尾,分批执行
- str_builder.Append(";");
- }
- str_builder.AppendLine();
- str_builder.AppendLine(str_Insert);
- l_bflag = false;
- }
-
- if (l_bflag)
- {
- str_builder.AppendLine();
- str_builder.AppendLine("UNION ALL");
- }
-
- DataRow dr = a_dtSource.Rows[i];
-
- str_builder.Append("SELECT ");
- string text = string.Empty;
- for (int j = 0; j < a_dtSource.Columns.Count; j++)
- {
- text = text + "'" + dr[j].ToString() + "'" + ",";
- }
- //去掉末尾分号
- text = DelLastComma(text);
- str_builder.Append(text);
- l_bflag = true;
- }
-
- return str_builder.ToString();
- }
-
-
- ///
- /// 创建Insert语句
- ///
- /// DataTable
- /// 数据库表名
- ///
- public static string CreateInsertSQL(DataTable a_dtSource, string a_strTableName)
- {
- //insert语句
- string str_Insert = $"INSERT INTO {a_strTableName} ({GetColumnsByDataTable(a_dtSource)})";
-
- bool l_bflag = false;
- StringBuilder str_builder = new StringBuilder();
- str_builder.AppendLine(str_Insert);
-
- //表格总行数
- int int_RowCount = a_dtSource.Rows.Count;
- //select语句,采用for循环便于计算行数
- for (int i = 0; i < int_RowCount; i++)
- {
- if (l_bflag)
- {
- str_builder.AppendLine("UNION ALL");
- }
-
- DataRow dr = a_dtSource.Rows[i];
-
- str_builder.Append("SELECT ");
- string text = string.Empty;
- for (int j = 0; j < a_dtSource.Columns.Count; j++)
- {
- text = text + "'" + dr[j].ToString() + "'" + ",";
- }
- //去掉末尾分号
- text = DelLastComma(text);
- str_builder.Append(text);
- str_builder.AppendLine();
- l_bflag = true;
- }
-
- return str_builder.ToString();
- }
-
-
- ///
- /// 内部获取字段列表
- ///
- /// DataTable param >
- /// < returns > SQL returns >
- private static string GetColumnsByDataTable(DataTable a_tbSchema)
- {
- string text = string.Empty;
- for (int i = 0; i < a_tbSchema.Columns.Count; i++)
- {
- string text2 = a_tbSchema.Columns[i].ColumnName;
- text = text + text2 + ",";
- }
- return DelLastComma(text);
- }
-
-
- ///
- /// 删除最后结尾的逗号
- ///
- /// 源字符串
- ///
string - public static string DelLastComma(string a_strSource)
- {
- return a_strSource.Substring(0, a_strSource.LastIndexOf(","));
- }
-
- }
- }
扩展阅读,本库已经二次优化,方法已经汇总进《MySQLBuilder脚本构建类》中。
C#底层库--MySQLBuilder脚本构建类(select、insert、update、in、带条件的SQL自动生成)
本文链接:https://blog.csdn.net/youcheng_ge/article/details/129179216
没啥好讲解的,都可以看得懂吧
- //转换
- private void BTN_Change_Click(object sender, EventArgs e)
- {
- if (!File.Exists(this.text_ExcelDir.Text))
- {
- FrmTips.ShowTipsInfo(this, "文件不存在,请检查!");
- return;
- }
-
- ConvertSQL();
- }
- //保存
- private void BTN_Save_Click(object sender, EventArgs e)
- {
- string l_strFileName = DateTime.Now.ToString("yyyyMMddHHmmssff") + ".txt";
-
- FolderBrowserDialog fbd = new FolderBrowserDialog();
- fbd.Description = "选择脚本保存位置";
- fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory;
- DialogResult dialogResult = fbd.ShowDialog();
- if (dialogResult == DialogResult.OK)
- {
- string l_strDir = Path.Combine(fbd.SelectedPath, l_strFileName);
- Utils.FileWrite(richTextBox1.Text, l_strDir);
- FrmTips.ShowTipsSuccess(this, "保存成功!");
-
- System.Diagnostics.Process.Start(l_strDir);
- }
- }
因为二次调用,所以单独出一个方法。转换、保存 按钮单击事件,均有调用此方法。
- //转换SQL
- private void ConvertSQL()
- {
- this.richTextBox1.Clear();
- string l_strFileName = Path.GetFileNameWithoutExtension(this.text_ExcelDir.Text);
-
- ExcelHelper excelHelper = new ExcelHelper();
- DataTable dt_Temp = excelHelper.ExcelToDataTableWhithEncryp(this.text_ExcelDir.Text);
- if (dt_Temp == null || dt_Temp.Rows.Count==0)
- {
- FrmTips.ShowTipsError(this, "表格读取为空!");
- return;
- }
-
- //每批数量
- decimal dec_num = 100;
- decimal.TryParse(AppConfig.GetValue("batch_num"), out dec_num);
-
- //是否开启
- bool b_Open = false;
- bool.TryParse(AppConfig.GetValue("open_tag"), out b_Open);
-
- if (b_Open)
- {
- int int_num = Convert.ToInt32(Math.Truncate(dec_num));
- richTextBox1.AppendText(CodeFactory.CreateInsertSQLBatch(dt_Temp, l_strFileName, int_num));
- }
- else
- {
- richTextBox1.AppendText(CodeFactory.CreateInsertSQL(dt_Temp, l_strFileName));
- }
-
- FrmTips.ShowTipsSuccess(this, "转换成功!");
- }
这里主要展示我开发完的程序,你们也可以在我的基础上进行个性化的修改。
主界面


点击复制按钮,拷贝脚本到数据库管理工具。

好了,是不是很完美。
提示:为了高性能执行,建议数据分批,在【配置】界面设置分批数量。
工具名称:ExcelImportTool
链接:https://pan.baidu.com/s/1NgZEGVzXDXecUxiqMmYAeg?pwd=858o
提取码:858o