c# Execel文件上传其数据映射界面中(主要为后端).net core6.0 api
c# Execel文件上传其数据映射界面中(主要为后端)
一、效果图 (前端操作逻辑) --layui工具
操作列状态显示含义:
二、功能实现
前端:直接粘贴效果可能不一样(布局样式有区别)
1、页面:

@{ Layout = "~/areas/uscore/Views/Shared/_LayoutEdit.cshtml"; ViewBag.Title = "导入功放设置"; } <div class="usnboxlistinfo"> 导入说明:如果是第一次导入,请直接下载EXCEL模板后,把您的数据编辑到EXCEL文件中后,上传到系统中在进行导入。 </div> <form class="layui-form layui-form-item us-form us-othform usnboxborder" id="us-form"> <div class="layui-form-item"> <div class="layui-inline"> <label class="layui-form-label">导入数据<span class="usStar">*</span></label> <div class="layui-input-inline"> <input type="text" name="id" autocomplete="off" placeholder="导入文件地址" class="layui-input" value=""> </div> <div class="layui-btn-group layui-inline us-submitsave"> <button class="layui-btn" data-pwid="upload" usdata="{uscallback:'uploadfinish'}"> <i class="us-icon"></i><span class="layui-hide-xs">上传文件</span> </button> <button class="layui-btn usbtnblue" data-pwid="obutton" id="import"> <i class="us-icon"></i><span class="layui-hide-xs">导入数据</span> </button> <button class="layui-btn usbtnblack" data-pwid="oexport" usdata="{usurl:'/extacs/acs_diset/usexportfile?m=1'}"> @*Excel模板存放物理路径:/upload/sys/管控-功放设置模板.xlsx*@ <i class="us-icon"></i><span class="layui-hide-xs">模板下载</span> </button> <div class="nodisplay"> <button class="layui-btn layui-hide-xs" data-pwid="query" id="refresh"> <i class="us-icon"></i><span class="layui-hide-xs">刷新</span> </button> </div> </div> </div> </div> </form> <div id="divprocess" class="nodisplay"> <div class="layui-progress layui-progress-sm" lay-showpercent="yes" lay-filter="process"> <div class="layui-progress-bar layui-bg-blue" lay-percent="0%"></div> </div> </div> <div class="usnboxlisttable"> <table id="usdatagrid" lay-filter="usdatagrid" class="usdatagrid" usdata="{uspage:'0',uspagesize:'10',usload:'0',usheight:'',usurl:'',ussurl:'/extacs/acs_diset/usimportgetlist' ,useurl:'/extacs/acs_diset/edit',usdurl:'/extacs/acs_diset/usdelete',uswidth:'',usheight:'full-200',ustitle:'班级信息',usewidth:'w3',useheight:'500'}"> <thead> <tr> <th lay-data="{type:'numbers',align:'center'}"></th> <th lay-data="{checkbox:true,align:'center'}" lay_checked="true"></th> <th lay-data="{field:'id',sort: true,align:'center',pstype:'all'}">序号</th> <th lay-data="{field:'roomid' , sort: true,align:'center',pstype:'all'}">教室编号</th> <th lay-data="{field:'building',sort: true,align:'center'}">教学楼</th> <th lay-data="{field:'floor',sort: true,align:'center',pstype:'all'}">楼层</th> <th lay-data="{field:'roomname' , sort: true,align:'center',pstype:'all'}">教室名称</th> <th lay-data="{field:'channelid',sort: true,align:'center'}">功放编号</th> <th lay-data="{field:'ampname',sort: true,align:'center'}">功放名称</th> <th lay-data="{field:'portname',sort: true,align:'center'}">功放通道</th> <th lay-data="{field:'isenable',sort: true,align:'center'}">是否启用</th> <th lay-data="{field:'oestatename',sort: true,align:'center',templet:'#switchTplstate'}">数据格式</th> <th lay-data="{field:'oestatename',sort: true,align:'center',templet:'#switchTplisexist'}">数据状态</th> <th lay-data="{field:'oestatename',sort: true,align:'center',templet:'#switchTpl'}">处理状态</th> </tr> </thead> </table> </div> <div class="usnboxlistinfo"> 导出说明:如果是想修改数据的话,可以直接下载全部的数据,修改后在导入到系统中。 <button class="layui-btn layui-btn-sm usbtnblue" data-pwid="oexport" id="oexport" usdata="{usurl:'/extacs/acs_diset/usexportfile'}"> <i class="us-icon"></i><span class="layui-hide-xs">导出数据</span> </button> </div> <script type="text/html" id="switchTplyesno"> <input type="checkbox" name="yesno" lay-skin="switch" class="layui-disabled" disabled lay-text="是|否" {{ d.isexpand==0 ? 'checked' : '' }}> </script> <script type="text/html" id="switchTplisexist"> {{# if(d.isexist==0 ){ }} <button class="layui-btn layui-btn-xs ">插入数据</button> {{# } else { }} <button class="layui-btn layui-btn-xs layui-btn-normal">更新数据</button> {{# }}} </script> <script type="text/html" id="switchTplstate"> @*id,roomid,building,floor,roomname,ampname,portname,isenable*@ {{# if(d.roomid!=null &&d.roomname!=null && d.ampname!=null && d.portname!=null && d.isenable!=null ){ }} <button class="layui-btn layui-btn-xs ">数据正常</button> <button class="layui-btn layui-btn-xs layui-btn-primary nodisplay" id="state{{ d.id }}">0</button> {{# } else { }} <button class="layui-btn layui-btn-xs layui-btn-danger" title="教室编号错误或功放通道无法识别、功放名称、是否启用不能为空">数据错误</button> <button class="layui-btn layui-btn-xs layui-btn-primary nodisplay" id="state{{ d.id }}">1</button> {{# }}} </script> <script type="text/html" id="switchTpl"> <button class="layui-btn layui-btn-xs layui-btn-primary" id="oprstate{{ d.id }}">等待操作</button> </script> <script type="text/javascript"> var importpagetitle = "@ViewBag.Title"; </script> <script type="text/javascript" src="/assets5/kiop/usacs/js/import_acs_diset.js?jsdate=@ViewBag.JSVersion"></script>
//页面引入外部js方式 <script type="text/javascript" src="/assets5/kiop/usacs/js/import_acs_diset.js?jsdate=@ViewBag.JSVersion"></script>
2、js文件:
///************************************************************************ ///作者代号:CF ///创建日期:2023-01-10 ///功能描述:导入功放配置 ///修改时间: ///修改代号: ///修改内容: ///************************************************************************ //#region 0.通用变量定义 var impsetting1 = { "btnrefresh": "#refresh",//刷新按钮id值 "txtpathselect": "input[name='id']",//放置文件路径input "btnimport": "#import",//导入按钮id值 "msg_noupload": "您必须上传需要导入的数据!", "msg_impconfirm": "是否要导入选择的数据?", "msg_mustselect": "您必须选择需要导入的数据!", "processbar": "#divprocess",//进度条div "cls_danger": "layui-btn-danger",//样式class名 "cls_normal": "layui-btn-normal",//样式class名 "cls_primary": "layui-btn-primary",//样式class名 "msg_skip": "跳过导入", "url_import": "/extacs/acs_diset/usimportone", //导入数据路径 "url_finish": "/extacs/acs_diset/usimportfinish",//导入完成调用 "msg_finish": "{0}信息完成。共{1}条数据:其中成功{2}条,失败{3}条,跳过{4}条!",//导入成功提示 "spagetitle": importpagetitle,//系统标题 "data_key": "id",//获取选中data中的指定key的值 "data_btn_state": "#state", //数据状态类id值 --跟新数据、插入数据 "data_btn_oprstate": "#oprstate"//处理状态列id值 }; //#endregion //#region 1.通用回调入口 /** * 系统基础回调,列表加载完成的回调(自己封装方法) * @param {any} table * @param {any} element */ function usdatagrid_controlfinish(table, element) { //获取layui的table, element句柄并给导入按钮添加点击事件 usbtnclickinit(table, element); } //#endregion //#region 2.文件上传完成 /** * 上传文件的回调,点击上传按钮后进入这个功能 * @param {any} url */ function uploadfinish(url) { if (url != "") { $(impsetting1.txtpathselect).val(url);//input填入导入文件的地址 $(impsetting1.btnrefresh).click();//触发刷新按钮(自己封装的方法,就是实现了layui获取数据动态表格显示数据) } } //#endregion //#region 3.按钮实现功能 /** * 导入功能按钮点击事件 * @param {any} table * @param {any} element */ function usbtnclickinit(table, element) { //给导入按钮添加点击事件 $(impsetting1.btnimport).on("click", function () { var txt = $(impsetting1.txtpathselect).val();//获取导入文件的地址 input的值 if (txt == "") { usbasic.us_msg_error(impsetting1.msg_noupload);//自己封装的方法,出现错误弹窗提示 return; } usalert.us_confirm_basic(impsetting1.msg_impconfirm, function (b) {//自己封装的方法,有一个是否确认导入的弹窗提示,返回值b为true或false if (b) { //确认导入后调用导入方法导入数据,layui句柄作为传参 usbtnimport(table, element); } }); }); } //#endregion //#region 4.导入的实现 /** * 实际导入功能实现 * @param {any} _table 句柄 * @param {any} element 句柄 * @returns */ function usbtnimport(_table, element) { //获取选中的要导入的数据 layui表格自带功能,可参考博客:https://www.cnblogs.com/ZhuMeng-Chao/p/17036215.html var data = _table.getCheckData(); //遍历数据,获取数据的序号,多选情况将其组合为一个数据 //可参考博客$.map的使用:https://www.cnblogs.com/ZhuMeng-Chao/p/17039324.html var ids = $.map(data, function (row) { return '"' + row[impsetting1.data_key] + '"'; }); var idlist = ids; if (idlist == "") { //自己封装的方法,出现错误弹窗提示 usbasic.us_msg_error(impsetting1.msg_mustselect); return; } //显示进度条 div显示(默认隐藏) $(impsetting1.processbar).show(); usbasic.usload_open();//打开和关闭加载类 -显示Loading //选择的数据长度 var icount_all = data.length; var icount_yes = 0; //成功导入数据个数 var icount_no = 0; //失败导入数据个数 var icount_cancel = 0; //跳过导入数据个数 $.map(data, function (row) { //获取数据格式列隐藏button的id,id不同 id=state+序列号 var stateid = impsetting1.data_btn_state + row[impsetting1.data_key]; //获取其数据格式隐藏button的html值,0数据正常 1数据错误 var iscancel = $(stateid).html(); //获取处理状态列的id ,id不同 id=oprstate+序列号 var oprstate = impsetting1.data_btn_oprstate + row[impsetting1.data_key]; //先清理处理状态列样式 $(oprstate).removeClass(impsetting1.cls_normal).removeClass(impsetting1.cls_danger).removeClass(impsetting1.cls_primary); //跳过导入情况(该行数据错误-有值为空) if (iscancel != "0") { icount_cancel++; //该行处理状态列显示红色底样式 $(oprstate).addClass(impsetting1.cls_danger); //处理状态显示'跳过导入'汉字 $(oprstate).html(impsetting1.msg_skip) } else { //该行数据ajax请求导入数据库(下面方法自己封装,其就是实现了ajax请求控制器api方法) ushttp.us_ajax_post_jsonv2(impsetting1.url_import, JSON.stringify(row), false, true, function (config) { //判断返回结果,==0导入成功 则icount_yes+1 if (config.result == 0) { console.error(config); console.error("config"); icount_yes++; } //否则导入失败 则icount_no+1 else { icount_no++; } var state = config.result; var typemess = config.msg; //处理状态列添加样式 红、蓝…… if (state == 0) { $(oprstate).addClass(impsetting1.cls_normal); } else { $(oprstate).addClass(impsetting1.cls_danger); } $(oprstate).attr("title", config.data); //处理状态列文本 --添加(修改)成功 $(oprstate).html(typemess); }); } }); var tInterval; //用户显示导入进度条 tInterval = setInterval(function () { var icount_finish = (icount_yes + icount_no + icount_cancel); var p = icount_finish * 100.0 / icount_all * 1.0; p = p.toFixed(2) + "%"; element.progress('process', p); if (icount_all == icount_finish) { //调用us_string_format方法 拼接提示文本,字符串格式化 var info = us_string_format(impsetting1.msg_finish, impsetting1.spagetitle, icount_all, icount_yes, icount_no, icount_cancel); var datajson = { "info": info, "id": idlist }; data = JSON.stringify(datajson); //数据导入完成ajax调用api记录日志 ushttp.us_ajax_post_jsonv2(impsetting1.url_finish, data, false, true, function (config) { }); usbasic.us_msg_success(info);//自己封装方法,导入成功后弹出窗提示用户成功几条,失败几条,跳过几条数据 $(impsetting1.txtpathselect).val(""); usbasic.usload_close(); $(impsetting1.processbar).hide(); clearTimeout(tInterval); } }, 500); } //#endregion /** * 字符串格式化 var content=us_string_format("我是{0} 几年{1}","大卫","25"); * @param {any} source 带{0}的字符串 * @param {any} params 可以多个 * @returns */ function us_string_format(source, params) { if (arguments.length == 1) return function () { var args = $.makeArray(arguments); args.unshift(source); return $.format.apply(this, args); }; if (arguments.length > 2 && params.constructor != Array) { params = $.makeArray(arguments).slice(1); } if (params.constructor != Array) { params = [params]; } $.each(params, function (i, n) { source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n); }); return source; };
三、使用layui提供功能写一个下载文件方法(获取Excel导入数据模板)
1、方式一:开发人员将固定的Excel放入项目指定中,用户点击下载模板,通过项目的相对路径中获取并下载Excel模板
2、方式二:通过代码的方式生成Excel (好处就是不用放文件到项目中)
四、后端实现上传Excel后,将Excel录入数据使用layui动态表格方法将其数据展示在界面
1、点击上传按钮使用layui布局上传功能
2、点击开始上传后,弹窗关闭,通过使用ajax方法并携带Excel文件路径请求控制器相应方法进行对上传的Excel数据读取
3、成功读取后,界面成功显示相应数据,显示效果如图:
实现过程:
导入显示流程 1.读取excel,2.读取翻译字段 3.数据翻译 4.显示
1、通过ajax请求将excel路径传递给控制器相应方法--根据路径分析Excel数据
1-1、根据路径获取excel数据 读取最终获取到一个datetable数据
/// <summary> /// 根据Excel文件地址读取Excel数据 /// </summary> /// <param name="sPath">Excel相对路径</param> /// <param name="SheetName">Excel表名</param> /// <returns></returns> public DataTable UsToolsExcel2DataTable(string sPath, string SheetName = "Sheet1") { DataTable dataTable = new DataTable(); //根据相对路径获取该Excel的完整路径 //例如:D:\项目文件\02.KIOP\Us.eIOP.Dev\Us.eIOP.Web\bin\Debug\net6.0\upload\1001\1002\202301\教室其他设备管理模板2023年01月11日-17时04分42秒-10726.xlsx sPath = UsMapPath.UsPath(sPath); //调用UsReadExcelFile方法获取Excel数据 return UsReadExcelFile(sPath, SheetName); }
public static string UsPath(string sPath) { string baseDirectory = AppContext.BaseDirectory; string text = sPath; text = Path.Combine(baseDirectory + sPath); return Path.GetFullPath(text); }
1-2、UsReadExcelFile方法获取Excel数据
public static DataTable UsReadExcelFile(string filePath, string SheetName = "Sheet1") { //路径名小写 filePath = filePath.ToLower(); //获取后缀名 .xlsx或.xls string extension = Path.GetExtension(filePath); DataTable result = new DataTable(); //根据后缀名调用不同的方法进行数据读取 if (".xlsx" == extension) { result = ImportExcelFile2007(filePath, SheetName); } else if (".xls" == extension) { result = ImportExcelFile2003(filePath, SheetName); } return result; }
1-3、读取后缀名为 .xlsx的数据
/// <summary> /// 读取.xlsx后缀名文件 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="SheetName">表名</param> /// <returns></returns> private static DataTable ImportExcelFile2007(string filePath, string SheetName = "Sheet1") { DataTable dataTable = new DataTable(); try { //读取源文件 using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); //获取或设置当前流的位置 fileStream.Position = 0L; //使用HSSFWorkbook导出、操作excel 由输入流文件得到工作簿对象 XSSFWorkbook xSSFWorkbook = new XSSFWorkbook((Stream)fileStream); //根据sheet名获取要读取的sheet ISheet sheet = xSSFWorkbook.GetSheet(SheetName);
//通过MoveNext()得到集合中的所有元素。GetEnumerator是返回实例的枚举数 如图1: IEnumerator rowEnumerator = sheet.GetRowEnumerator(); dataTable.TableName = SheetName; //将枚举数推进到集合的下一个元素。 rowEnumerator.MoveNext(); //获取集合中位于枚举数当前位置的元素。 XSSFRow xSSFRow = (XSSFRow)rowEnumerator.Current; //循环向dataTable中插入Columns 添加列 for (int i = 0; i < sheet.GetRow(0).LastCellNum; i++) { if (xSSFRow.GetCell(i) != null) { dataTable.Columns.Add(xSSFRow.GetCell(i).ToString()); } else { dataTable.Columns.Add("column_name" + i); } } //将枚举推进到集合的下一个元素(也就是读取excel的第二行) 开始循环读取数据并插入到daterow中 效果如下图2 while (rowEnumerator.MoveNext()) {
xSSFRow = (XSSFRow)rowEnumerator.Current; DataRow dataRow = dataTable.NewRow(); for (int j = 0; j < xSSFRow.LastCellNum; j++) { ICell cell = xSSFRow.GetCell(j); if (cell == null) { dataRow[j] = null; } else if (cell.CellType == CellType.Numeric && DateUtil.IsCellDateFormatted(cell)) { dataRow[j] = cell.DateCellValue.ToString(); } else { dataRow[j] = cell.ToString(); } } //向dataTable中添加上新的行 dataTable.Rows.Add(dataRow); } } catch (Exception ex) { //记录日志 UsLog.UsLogInfoError("ImportExcelFile2007error:" + filePath, ex); } //返回dataTable 此时已经成功读取完数据 return dataTable; }
图一:
返回了Excel所有列的名称
//通过MoveNext()得到集合中的所有元素。GetEnumerator是返回实例的枚举数 如图1:
IEnumerator rowEnumerator = sheet.GetRowEnumerator();
图二:
读取Excel过程中
1-4、读取后缀名为 .xls的数据

/// <summary> /// 读取.xls后缀名文件 /// </summary> /// <param name="filePath"></param> /// <param name="SheetName"></param> /// <returns></returns> private static DataTable ImportExcelFile2003(string filePath, string SheetName = "Sheet1") { DataTable dataTable = new DataTable(); try { using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); fileStream.Position = 0L; HSSFWorkbook hSSFWorkbook = new HSSFWorkbook(fileStream); ISheet sheet = hSSFWorkbook.GetSheet(SheetName); IEnumerator rowEnumerator = sheet.GetRowEnumerator(); dataTable.TableName = SheetName; rowEnumerator.MoveNext(); HSSFRow hSSFRow = (HSSFRow)rowEnumerator.Current; for (int i = 0; i < sheet.GetRow(0).LastCellNum; i++) { if (hSSFRow.GetCell(i) != null) { dataTable.Columns.Add(hSSFRow.GetCell(i).ToString()); } else { dataTable.Columns.Add("column_name" + i); } } while (rowEnumerator.MoveNext()) { hSSFRow = (HSSFRow)rowEnumerator.Current; DataRow dataRow = dataTable.NewRow(); for (int j = 0; j < hSSFRow.LastCellNum; j++) { ICell cell = hSSFRow.GetCell(j); if (cell == null) { dataRow[j] = null; } else { dataRow[j] = cell.ToString(); } } dataTable.Rows.Add(dataRow); } } catch (Exception ex) { UsLog.UsLogInfoError("ImportExcelFile2003", ex); } return dataTable; }
2、上面获取到了上传Excel的数据值(是一个DateTable数据形式)
进行读取翻译字段、进行数据翻译
//导入显示流程 1.读取excel,2.读取翻译字段 3.数据翻译 4.显示
2-1、
UsImportSet_Object InSetting = new UsImportSet_Object();

public class UsImportSet_Object { public bool isImport { get; set; } public UsImportSet_ImpIn ImpSetting { get; set; } public UsImportSet_ImpRun ImpSettingRun { get; set; } public UsImportSet_ImpOut ExpSetting { get; set; } public UsImport_UResolverSettings ResolverSettings { get; set; } public bool bExcelColumnIsAllString { get; set; } public UsImportSet_Object() { isImport = true; ImpSetting = new UsImportSet_ImpIn(); ImpSettingRun = new UsImportSet_ImpRun(); ExpSetting = new UsImportSet_ImpOut(); ResolverSettings = new UsImport_UResolverSettings(); } }

public class UsImportSet_ImpIn : UsImport_Basic { public string FieldChina { get; set; } public string FieldEnglish { get; set; } public string DictionarySQL { get; set; } public string RowIsExistSQL { get; set; } public string RowIsExistKey { get; set; } public string RowClearKey { get; set; } public bool ExcelFieldSpaceToNull { get; set; } public UsImportSet_ImpIn() { ExcelFieldSpaceToNull = true; } } public class UsImport_Basic { public bool IsCheckUpdateKey { get; set; } public UsImport_Basic() { IsCheckUpdateKey = false; } } public class UsImportSet_ImpRun : UsImport_Basic { public string[] zFieldChina { get; set; } public string[] zFieldEnglish { get; set; } public List<UsImportSet_Dictionary> FieldList { get; set; } public DataTable dtDictionary { get; set; } public DataTable dtRowIsExist { get; set; } public string RowIsExistKey { get; set; } public string RowClearKey { get; set; } public UsImportSet_ImpRun() { FieldList = new List<UsImportSet_Dictionary>(); dtDictionary = new DataTable(); dtRowIsExist = new DataTable(); } } public class UsImportSet_ImpOut { public string FieldChina { get; set; } public string FieldEnglish { get; set; } public string sExcelWidthKey { get; set; } public string sShowName { get; set; } public bool Landscape { get; set; } public int iReapterRow { get; set; } public string ExportSQL { get; set; } public DataTable dtExport { get; set; } public UsImportSet_ImpOut() { Landscape = false; iReapterRow = 1; } } public class UsImport_UResolverSettings { public IUsImportContractResolver ContractResolver { get; set; } } public interface IUsImportContractResolver { void EXP_DataTableUpdate(ref DataTable dt); void IMP_CheckIsExist(ref UsImport_IsExist Key); }
2-2、用作翻译datetable数据
UsImportSet_ImpIn ImpSetting = new UsImportSet_ImpIn() {
//Excel文件的标题行的所有标题信息 FieldChina是编写excel的标题行,要和导入的Excel模板列数量、汉字一模一样,分别对应相应行列的值 FieldChina = "序号,教室,设备名称,设备类型,设备标识码,检测方式,检测地址,是否启用,备注说明",
//给标题行起英文名(供前端使用的,最后返回给前端的对象就是这个名字)--如果前段需要的东西多于标题行,这里就把所需都写上 FieldEnglish = "id,building,floor,roomid,roomname,othername,othertype,othernum,otheracsway,otherurl,isenable,onote", //字典SQL语句(例如:此处excel中教室、设备类型、检测方式、是否启用为下拉输入形式)
//所以此处要写一个SQL语句用来翻译这些下拉数据
//以此处'是否启用'为例子解释:
1、数据库中'是否启用'是用字符1和0表示的 0表示'是' 1表示'否'
DictionarySQL = @"select codeid,codename,codeof,isdel from tb_systemdictionary where codeof in ('yesno') union select codeid,codename,codeof,isdel from tb_systemdictionary w where codeof in('acsway') union select codeid,codename,codeof,isdel from tb_systemdictionary w where codeof in('acsdtype')",
//本人使用mysql数据库中查询SQL的效果
RowIsExistSQL = "select * from tb_acs_others where 1=1 ", RowIsExistKey = "id",//判断导入的数据在表中是否有,有则是修改,无则添加 RowClearKey = "roomid",//判断该行有没有用的标准(为空则会被过滤掉) IsCheckUpdateKey = IsCheckUpdateKey };

public class UsImportSet_ImpIn : UsImport_Basic { public string FieldChina { get; set; } public string FieldEnglish { get; set; } public string DictionarySQL { get; set; } public string RowIsExistSQL { get; set; } public string RowIsExistKey { get; set; } public string RowClearKey { get; set; } public bool ExcelFieldSpaceToNull { get; set; } public UsImportSet_ImpIn() { ExcelFieldSpaceToNull = true; } } public class UsImport_Basic { public bool IsCheckUpdateKey { get; set; } public UsImport_Basic() { IsCheckUpdateKey = false; } }
2-3、翻译字段(根据Excel的列标题,翻译数据)
2-4、特殊列的翻译,例如:Excel中是下拉形式的数据
2-5、
2-6、
2-7、
3、
五、
五、
本文来自博客园,作者:じ逐梦,转载请注明原文链接:https://www.cnblogs.com/ZhuMeng-Chao/p/17040106.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构