首先页面的展示:
当点击直接弹出选择要导入的文件
代码如下:
<td style="width: 2%; text-align: center">
<span class="SearchLable">选择文件:</span>
</td>
<td style="width:4%;">
<form id="upload" method="post" enctype="multipart/form-data">
<input id="file1" name="file" style="margin-left: 20px;" onchange="UploadFile()"
type="file" />
</form>
<input id="filepath" type="text" hidden="hidden" />
</td>
新建一个Excel,准备好要导入的数据
JavaScript: 直接复制就行,别看多,都已经写好了。
就三个方法,在不同的时期调用。
<script type="text/javascript">
//导入操作
function UploadFile() {
var filepath = $("input[name='file']").val();
if (filepath == "" || filepath == null) {
$.loading(false);
}
else if (filepath.indexOf(".xlsx") < 0 && filepath.indexOf(".xls") < 0) {
$.loading(false);
$.modalAlert("导入文件类型有误,请检查后重新操作!", "warning");
var sdds = document.getElementById("file1");
if (sdds.outerHTML) {
sdds.outerHTML = sdds.outerHTML;
} else { // FF(包括3.5)
sdds.value = "";
}
$("#filepath").val(null);
} else {
$.loading(true, "上传文件中,请稍候...");
var f = document.forms[0];
var options = {
dataType: "JSON",
success: SubmitCallBack
};
f.action = "UploadPersonSubmit1";
$("#upload").ajaxSubmit(options);
}
}
function SubmitCallBack(Json) {
if (Json.success) {
$.loading(false);
$("#filepath").val(Json.FilePath);
top.layer.confirm("注:您确定要导入数据吗?", {
icon: "fa-exclamation-circle",
title: "系统提示",
btn: ['确认', '取消'],
btnclass: ['btn btn-primary', 'btn btn-danger'],
closeBtn: false,
}, function () {
Upload();
}, function () {
var sdds = document.getElementById("file1");
if (sdds.outerHTML) {
sdds.outerHTML = sdds.outerHTML;
} else { // FF(包括3.5)
sdds.value = "";
}
$("#filepath").val(null);
});
}
else {
$.loading(false);
$.modalAlert(Json.msg, "warning", function () {
var sdds = document.getElementById("file1");
if (sdds.outerHTML) {
sdds.outerHTML = sdds.outerHTML;
} else { // FF(包括3.5)
sdds.value = "";
}
$("#filepath").val(null);
});
}
}
function Upload() {
var filepath = $("#filepath").val();
if (filepath == null || filepath == "") {
$.loading(false);
$.modalAlert("未找到上传文件", "warning");
} else {
$.loading(true, "数据录入中,请稍候...");
$.ajax({
type: "POST",
data: { filepath: filepath },
url: "WhitePersonUploadFileToDatabase",
dataType: "JSON",
success: function (data) {
$.loading(false);
if (data.success) {
$.modalAlert(data.msg, "warning", function () {
var sdds = document.getElementById("file1");
if (sdds.outerHTML) {
sdds.outerHTML = sdds.outerHTML;
} else { // FF(包括3.5)
sdds.value = "";
}
$("#filepath").val(null);
});
tabRefreshThis();
}
else {
$.modalAlert(data.msg, "warning", function () {
var sdds = document.getElementById("file1");
if (sdds.outerHTML) {
sdds.outerHTML = sdds.outerHTML;
} else { // FF(包括3.5)
sdds.value = "";
}
$("#filepath").val(null);
});
}
}
});
}
}
</script>
对应的c#后台代码:
我写在了MVC的控制器里面,相信.net开发的人都能理解:
看似代码很多,实则不难,虽然多,但是分解的很好,可以做各种各样的验证。
总体过程就是读取几行,我上面写的是3行,那就把3改成你要导入的行数。
定义一个数据库的实体类来接收Excel读取的东西,添加到数据库里即可。
其中:string defauserverpath = ConfigurationManager.AppSettings["AttachmentPersonPath"];为服务器路径
可以随便写一个本地路径:string defauserverpath = "E:\\"; (按照我的方式写就可以。不报错)
/// <summary>
/// 上传文档文件
/// </summary>
/// <returns></returns>
public JsonResult UploadPersonSubmit1()
{
HttpPostedFileBase file = Request.Files["file"];
#region 上传文件到服务器
try
{
string defauserverpath = "E:\\"; //白名单导入
//string defauserverpath = ConfigurationManager.AppSettings["AttachmentPersonPath"]; //ConfigurationManager.AppSettings["DefaultServerPath"] + "\\UploadFile";
if (Directory.Exists(defauserverpath) == false)//如果不存在就创建file文件夹
{
Directory.CreateDirectory(defauserverpath);
}
string filename = file.FileName.LastIndexOf("\\") > -1 ? file.FileName.Substring(file.FileName.LastIndexOf("\\") + 1) : file.FileName;
string filepath = Path.Combine(defauserverpath,
Path.GetFileName(DateTime.Now.ToString().Replace("/", "").Replace(":", "").Replace(" ", "") + "_" + filename));
file.SaveAs(filepath);
//string str = "上传文件信息:FILENAME:" + file.FileName + ",FILEPATH:" + filepath + ",上传人:" + ServiceContext.GetUserInfo().UserCode + ",时间为:" + DateTime.Now.ToString();
//AddOperaLog(str, "上传", "UploadPersonSubmit");
var result = new { success = true, msg = "上传成功,文件地址:" + filepath + ",", FilePath = filepath };
return Json(result, "text/html;charset=utf-8", JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
var result = new { success = false, msg = "上传失败" + ex.Message, FilePath = string.Empty };
return Json(result, "text/html;charset=utf-8", JsonRequestBehavior.AllowGet);
}
#endregion
}
/// <summary>
/// 将上传文档文件解析,并插入数据库 navymaster
/// </summary>
/// <returns></returns>
public JsonResult WhitePersonUploadFileToDatabase()
{
JsonResultModel result = new JsonResultModel() { success = false };
try
{
string filepath = Request["filepath"];
#region 解析上传文件内容数据到datatable
//定义要返回的datatable对象
DataTable table = new DataTable();
//excel工作表
NPOI.SS.UserModel.ISheet sheet = null;
//数据开始行(排除标题行)
int startRow = 0;
try
{
if (!System.IO.File.Exists(filepath))
{
return null;
}
//根据指定路径读取文件
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
//根据文件流创建excel数据结构
NPOI.SS.UserModel.IWorkbook workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fs);
//IWorkbook workbook = new HSSFWorkbook(fs);
//如果有指定工作表名称
if (!string.IsNullOrEmpty("Sheet1") || !string.IsNullOrEmpty("Sheet1(1)"))
{
sheet = workbook.GetSheet("Sheet1");
if (sheet == null)
{
sheet = workbook.GetSheet("Sheet1(1)");
}
//如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
if (sheet == null)
{
result.success = false;
result.msg = "导入文件内容格式不符合规则";
return Json(result, JsonRequestBehavior.AllowGet);
}
}
else
{
//如果没有指定的sheetName,则尝试获取第一个sheet
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
NPOI.SS.UserModel.IRow firstRow = sheet.GetRow(0);
//一行最后一个cell的编号 即总的列数
int cellCount = firstRow.LastCellNum;
if (cellCount == 3)
{
//如果第一行是标题列名
if (true)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
NPOI.SS.UserModel.ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (cellValue != null)
{
DataColumn column = new DataColumn(cellValue);
table.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
}
}
else
{
result.success = false;
result.msg = "导入文件内容格式不符合规则";
return Json(result, JsonRequestBehavior.AllowGet);
}
//最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null
DataRow dataRow = table.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
{
if (row.GetCell(j).CellType == CellType.Numeric && row.GetCell(j).ToString().IndexOf('-') > 1)
{
dataRow[j] = row.GetCell(j).DateCellValue;
}
else
{
dataRow[j] = row.GetCell(j).ToString().Trim().ToUpper();
}
}
if (i > 0 && j == 0 && string.IsNullOrWhiteSpace(row.GetCell(j).ToString()))
{
dataRow[j] = table.Rows[i - 2][0].ToString().Trim().ToUpper();
}
}
table.Rows.Add(dataRow);
}
}
}
catch (Exception ex)
{
throw ex;
}
#endregion
#region 判断导入内容
if (table.Columns[0].ColumnName != "产品线" || table.Columns[1].ColumnName != "目标" || table.Columns[2].ColumnName != "前两月目标" || table.Columns.Count != 3)
{
result.success = false;
result.msg = "导入数据内容不符合规则";
return Json(result, JsonRequestBehavior.AllowGet);
}
#endregion
#region 将解析出的数据插入数据库
List<SMS_MAINTARGET> mppointlist = new List<SMS_MAINTARGET>();
result.msg = "";
List<DataRow> countlist = new List<DataRow>();
//验证正整数正则
for (int i = 0; i < table.Rows.Count; i++)
{
for (int j = 0; j < table.Columns.Count; j++)
{
//非空
if (string.IsNullOrWhiteSpace(table.Rows[i][j] == null ? "" : table.Rows[i][j].ToString()))
{
result.success = false;
if (!result.msg.Contains("导入数据中第" + (i + 2) + "行" + (j + 1) + "列有空值;"))
{
result.msg += "导入数据中第" + (i + 2) + "行" + (j + 1) + "列有空值;";
}
}
else
{
if (table.Columns.Count == 3 && j == 0)
{
string productline = table.Rows[i][0].ToString();
string ordertarget = table.Rows[i][1].ToString();
string mouthagotarget = table.Rows[i][2].ToString();
}
}
}
}
if (!string.IsNullOrWhiteSpace(result.msg))
{
return Json(result, JsonRequestBehavior.AllowGet);
}
for (int i = 0; i < table.Rows.Count; i++)
{
string productline = "";
string ordertarget = "";
string mouthagotarget = "";
if (table.Columns.Count == 3)
{
productline = table.Rows[i][0].ToString();
ordertarget = table.Rows[i][1].ToString();
mouthagotarget = table.Rows[i][2].ToString();
}
else
{
productline = table.Rows[i][0].ToString();
ordertarget = table.Rows[i][1].ToString();
mouthagotarget = table.Rows[i][2].ToString();
}
SMS_MAINTARGET mppoint = new SMS_MAINTARGET();
mppoint.MAINTARGETID = GetIndexOfTableID("sms_blackperson_Seq").ToString(); //转了string
mppoint.PRODUCTLINE = productline;
mppoint.ORDERTARGET = decimal.Parse(ordertarget);
mppoint.MOUTHAGOTARGET = decimal.Parse(mouthagotarget);
mppoint.CREATE_DT = DateTime.Now;
mppoint.MAINDATE = DateTime.Now.ToString("yyyyMMdd");
mppointlist.Add(mppoint);
}
if (mppointlist.Count > 0)
{
DBAction<SMS_MAINTARGET>.DeleteEntity(DBAction<SMS_MAINTARGET>.LoadEntities().ToList());
DBAction<SMS_MAINTARGET>.AddEntity(mppointlist);
}
#endregion
//string str = "数据添加:表名:SMS_INCENTIVE_BLACKPERSONINFO,操作人:" + ServiceContext.GetUserInfo().UserCode + ",时间为:" + DateTime.Now.ToString() + ",文件地址:" + filepath;
//AddOperaLog(str, "人员黑名单上传并插入", "PersonUploadFileToDatabase");
result.success = true;
result.msg = "导入成功";
//ClearSysWhitCache();
return Json(result, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
result.success = false;
result.msg = "异常信息:" + ex.Message;
return Json(result, JsonRequestBehavior.AllowGet);
}
}
应该会发现没有这个类:
JsonResultModel result = new JsonResultModel() { success = false };
这个类是干嘛的呢?
是我用来追加错误信息的,专门用来累计信息,作为返回结果,如果你不需要可以删除,以下提供这个类的源码:
public class JsonResultModel
{
public bool success { get; set; }
public string state { get; set; }
public string msg { get; set; }
public string error { get; set; }
}
在插入数据库的时候会有要求插入主键,上文中调用了GetIndexOfTableID()方法:
#region 表主键获取
/// <summary>
/// 获取下一主键值
/// </summary>
/// <param name="seq">表序列名称</param>
/// <returns></returns>
private decimal GetIndexOfTableID(string seq)
{
var pkid = new PMSEntities_Fun().Database.SqlQuery<decimal>(string.Format("select spmsadmin.{0}.nextval from dual", seq)).FirstOrDefault();
return pkid;
}
#endregion
是decimal类型的主键,但是我数据库里string类型的主键,所以ToString()即可。如此便可以 “水路通用”
相信通过此文,会帮助大家解决导入问题。
如有疑问可与我联系,欢迎留言\点赞。