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">&#xe715;</i><span class="layui-hide-xs">上传文件</span>
                </button>
                <button class="layui-btn usbtnblue" data-pwid="obutton" id="import">
                    <i class="us-icon">&#xe768;</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">&#xe649;</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">&#xe71e;</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">&#xe767;</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>
cshtml
复制代码
//页面引入外部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;
        }
读取后缀名为 .xls的数据
复制代码

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();
        }
    }
UsImportSet_Object
复制代码
复制代码
 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);
    }
UsImportSet_ImpIn、UsImportSet_ImpRun、UsImportSet_ImpOut、UsImport_UResolverSettings
复制代码

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;
        }
    }
UsImportSet_ImpIn
复制代码

2-3、翻译字段(根据Excel的列标题,翻译数据)

2-4、特殊列的翻译,例如:Excel中是下拉形式的数据

2-5、

2-6、

2-7、

 

 

3、

五、

五、 

 

 

 

 

 

 

 

 

 

 

 

 

posted @   じ逐梦  阅读(148)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示