對於系統有很多需要導入Excel數據的情況。比如基礎數據導入,比如外送標本等,比如外來菌入庫。對CS操作Excel還好,BS就費勁很多,需要先在界面加上傳文件部分,把用戶選擇的Excel上傳到服務器後臺解析,然後再做業務處理。
大體代碼如下
頁面元素
<input type="file" id="file_upload" name="f" onchange="LoadImportData(this);" accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" style="display: none" />
<a id="btnInportData" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-page_white_excel'" onclick="ImportData();" plain="true">導入</a>
js邏輯
//導入
function ImportData(){
$("#file_upload").click()
}
//載入導入數據
function LoadImportData(a) {
var data = new FormData();
var file = document.getElementById('file_upload').files[0]
data.append("file", file);
ajaxLoading();
var url = "../ashx/ashCodeTable.ashx?method=Import&Model="+Model;
var callback = function(retData){
retData = JSON.parse(retData);
//沒數據返回
if (retData.length == 0) {
ajaxLoadEnd();
return;
}
if (retData.length > 0) {
var infoString = '<table style="width:100%;border:1px solid #000;">';
var infoCommonString = '<table style="width:100%;border:1px solid #000;">';
for (var i = 0; i < retData.length; i++) {
var color = "orange;";
if (retData[i].indexOf("UNIQUE or PRIMARY KEY Constraint failed uniqueness check upon INSERT") > -1) {
retData[i] += "  系統已有該條數據!";
color = "blue;";
infoCommonString += '<tr><td style="text-align:left;border:1px solid #000;word-wrap:break-word;word-break:break-all;color:' + color + '">' + retData[i].replace(/[<]/ig, '').replace(/[>]/ig, '') + '</td></tr>';
}
if (retData[i].indexOf("is a required field") > -1) {
retData[i] += "  缺少必填字段!";
color = "red;";
infoString += '<tr><td style="text-align:left;border:1px solid #000;word-wrap:break-word;word-break:break-all;color:' + color + '">' + retData[i].replace(/[<]/ig, '').replace(/[>]/ig, '') + '</td></tr>';
}
if (retData[i].indexOf("failed validation") > -1) {
retData[i] += "  長度等不合格!";
color = "orange;";
infoString += '<tr><td style="text-align:left;border:1px solid #000;word-wrap:break-word;word-break:break-all;color:' + color + '">' + retData[i].replace(/[<]/ig, '').replace(/[>]/ig, '') + '</td></tr>';
}
else {
infoString += '<tr><td style="text-align:left;border:1px solid #000;word-wrap:break-word;word-break:break-all;color:' + color + '">' + retData[i].replace(/[<]/ig, '').replace(/[>]/ig, '') + '</td></tr>';
}
}
infoString += '</table>';
infoCommonString += '</table>';
$("#tableDiv").html(infoString + infoCommonString);
$('#winErr').window({
title:"錯誤信息展示",
width:700,
height:500,
modal:true
});
$("#file_upload").val("");
}
else if (retData.length == 0) {
$.messager.show({
title: '提示',
msg: '保存成功!',
timeout: 1500,
showType: 'slide'
});
$("#file_upload").val("");
}
else {
showError(retData["Message"]);
$("#file_upload").val("");
}
ajaxLoadEnd();
};
http(data,url,callback);
}
//上傳方法(HTML5)
function http(date,url,callback) {
function createXHttpRequest() {
if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
return;
}
}
function starRequest(date) {
createXHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
callback(xmlhttp.response);
}
}
};
xmlhttp.open("POST", url, true);
xmlhttp.send(date);
}
starRequest(date);
}
後臺處理邏輯(還得操作Excel文件),是不是很複雜,哈哈,因爲他把業務和操作Excel文件,上傳揉一起了,像一團亂麻
/// <summary>
/// 後臺導入數據
/// </summary>
/// <returns></returns>
public string ImportBackDo(string fModelName)
{
//插入數據
string oper = Helper.ValidParam(Request["Oper"], "Insert");
//返回結果
List<string> retList = new List<string>();
HttpFileCollection files = Request.Files;
if (files.Count > 0)
{
IWorkbook workbook = null;
string fileName = files[0].FileName;
// 2007版本
if (fileName.IndexOf(".xlsx") > 0)
{
workbook = new XSSFWorkbook(files[0].InputStream);
}
// 2003版本
else if (fileName.IndexOf(".xls") > 0)
{
workbook = new HSSFWorkbook(files[0].InputStream);
}
else
{
retList.Add("導入文件格式錯誤!");
return Helper.Object2Json(retList);
}
//得到表單的個數
int numSheets = workbook.NumberOfSheets;
//更新列
Dictionary<string, bool> dicUpdateCol = new Dictionary<string, bool>();
//遍歷找到當前表單表單
for (int i = 0; i < numSheets; i++)
{
string curName = workbook.GetSheetAt(i).SheetName;
string[] nameArr = curName.Split('^');
if (nameArr.Length == 2)
{
ISheet sheet = null;
//存儲所有列
List<string> columnsTitle = new List<string>();
string modelName = nameArr[1];
//指定實體導入
if (fModelName != "" && fModelName != modelName)
{
continue;
}
sheet = workbook.GetSheet(curName);
//如果沒有找到指定的sheetName對應的sheet,則嘗試獲取第一個sheet
if (sheet == null)
{
continue;
}
//清除更新說明
dicUpdateCol.Clear();
//找到表單,且行數大於4行才導入數據
if (sheet != null && sheet.LastRowNum >= 4)
{
IRow firstRow = sheet.GetRow(3);
//判斷第一行
if (firstRow == null)
{
retList.Add("導入文件內容爲空!");
return Helper.Object2Json(retList);
}
//一行最後一個cell的編號 即總的列數
int cellCount = firstRow.LastCellNum;
for (int j = firstRow.FirstCellNum; j < cellCount; j++)
{
ICell cell = firstRow.GetCell(j);
if (cell != null)
{
string cellName = "";
if (cell.CellType == CellType.Numeric)
{
cellName = Convert.ToString(cell.NumericCellValue);
}
else if (cell.CellType == CellType.String)
{
cellName = cell.StringCellValue.Trim();
}
else if (cell.CellType == CellType.Boolean)
{
cellName = Convert.ToString(cell.BooleanCellValue);
}
columnsTitle.Add(cellName);
}
else
{
columnsTitle.Add("");
}
}
//用來存一列的最後值
Dictionary<string, object> lastColVal = new Dictionary<string, object>();
//最後一列的標號
int rowCount = sheet.LastRowNum;
//更新列明
List<string> updateColName = new List<string>();
//條件更新
Hashtable hsUpdate = new Hashtable();
for (int k = 4; k <= rowCount; k++)
{
IRow curRow = sheet.GetRow(k);
if (curRow == null)
{
continue;
}
this.type = this.EntityManager.GetTypeByName(modelName);
//創建對象
Object obj = this.type.Assembly.CreateInstance("LIS.Model.Entity." + modelName);
//記錄延遲處理列
List<int> lazyDeal = new List<int>();
//更新的列名
updateColName.Clear();
//更新條件
hsUpdate.Clear();
for (int n = curRow.FirstCellNum; n < cellCount; n++)
{
//沒寫列名的列忽略
if (columnsTitle[n] == "" || columnsTitle[n] == null)
{
continue;
}
string[] colNameMianArr = columnsTitle[n].Split('#');
string[] colNameArr = colNameMianArr[0].Split('^');
//描述更新列,標識爲更新類
if (colNameMianArr.Length == 2 && colNameMianArr[1] == "Key")
{
if (!dicUpdateCol.ContainsKey(colNameArr[0].Trim()))
{
dicUpdateCol.Add(colNameArr[0].Trim(), true);
}
}
else
{
if (!dicUpdateCol.ContainsKey(colNameArr[0].Trim()))
{
dicUpdateCol.Add(colNameArr[0].Trim(), false);
}
//更新列名
updateColName.Add(colNameArr[0].Trim());
}
//描述的外部列,先不處理
if (colNameArr.Length >= 3)
{
lazyDeal.Add(n);
}
ICell cell = curRow.GetCell(n);
if (cell != null)
{
//得到屬於
PropertyInfo pro = this.type.GetProperty(colNameArr[0]);
if (pro != null)
{
object cellVal = null;
if (cell.CellType == CellType.Numeric)
{
cellVal = cell.NumericCellValue;
}
else if (cell.CellType == CellType.String)
{
cellVal = cell.StringCellValue;
}
else if (cell.CellType == CellType.Boolean)
{
cellVal = cell.BooleanCellValue;
}
//是否取最該列最後一行值
if (colNameArr.Length >= 4)
{
if (cellVal == null)
{
if (lastColVal.ContainsKey(colNameArr[0]))
{
cellVal = lastColVal[colNameArr[0]];
}
}
if (cellVal != null)
{
if (lastColVal.ContainsKey(colNameArr[0]))
{
lastColVal[colNameArr[0]] = cellVal;
}
else
{
lastColVal.Add(colNameArr[0], cellVal);
}
}
}
if (colNameArr.Length == 1 && cellVal != null)
{
//加入更新條件
if (dicUpdateCol[colNameArr[0]] == true)
{
hsUpdate.Add(colNameArr[0], cellVal);
}
if (cell.CellType == CellType.String)
{
if (pro.Name.Length > 4)
{
string lastName = pro.Name.Substring(pro.Name.Length - 4, 4);
if (lastName == "Date")
{
if (cellVal != null)
{
cellVal = Helper.DateToInt(cellVal.ToString());
}
}
if (lastName == "Time")
{
if (cellVal != null)
{
cellVal = Helper.TimeToInt(cellVal.ToString());
}
}
}
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro, cellVal);
}
}
}
}
MethodInfo wrapAdd = null;
object exeobj = null;
//更新和插入
if (oper == "Update")
{
exeobj = this;
wrapAdd = this.GetType().GetMethod("UpdatePri");
}
else
{
exeobj = this;
wrapAdd = this.GetType().GetMethod("WrapAdd");
}
wrapAdd = wrapAdd.MakeGenericMethod(type);
//如果有延遲處理列,處理
if (lazyDeal.Count > 0)
{
//存翻譯的二維數據
Dictionary<string, List<int>> dic = new Dictionary<string, List<int>>();
List<string> colDicNames = new List<string>();
//遍歷處理延遲列
foreach (int z in lazyDeal)
{
ICell cell = curRow.GetCell(z);
if (cell == null)
{
continue;
}
string curCellVal = "";
if (cell.CellType == CellType.Numeric)
{
if (cell.NumericCellValue != null)
{
curCellVal = cell.NumericCellValue.ToString().Trim();
}
}
else if (cell.CellType == CellType.String)
{
curCellVal = cell.StringCellValue.Trim();
}
else if (cell.CellType == CellType.Boolean)
{
if (cell.NumericCellValue != null)
{
curCellVal = cell.BooleanCellValue.ToString();
}
}
string[] colNameArr = columnsTitle[z].Split('^');
//是否取最該列最後一行值
if (colNameArr.Length >= 4)
{
if (curCellVal == "" || curCellVal == null)
{
if (lastColVal.ContainsKey(colNameArr[0]))
{
curCellVal = lastColVal[colNameArr[0]].ToString().Trim();
}
}
if (curCellVal != null && curCellVal != "")
{
if (lastColVal.ContainsKey(colNameArr[0]))
{
lastColVal[colNameArr[0]] = curCellVal;
}
else
{
lastColVal.Add(colNameArr[0], curCellVal);
}
}
}
char spchar = ',';
if (colNameArr.Length == 4)
{
spchar = colNameArr[4][0];
}
//分割數據
string[] cellValArr = curCellVal.Split(spchar);
if (cellValArr != null && cellValArr.Length > 0)
{
dic.Add(colNameArr[0].Trim(), new List<int>());
colDicNames.Add(colNameArr[0].Trim());
MethodInfo getRowIDByPara = this.GetType().GetMethod("GetRowIDByPara");
getRowIDByPara = getRowIDByPara.MakeGenericMethod(this.EntityManager.GetTypeByName(colNameArr[1]));
foreach (var cv in cellValArr)
{
object[] obParams = new object[] { colNameArr[2], cv };
int ret = (int)getRowIDByPara.Invoke(this, obParams);
if (ret != 0)
{
dic[colNameArr[0].Trim()].Add(ret);
}
}
}
}
if (colDicNames.Count > 0)
{
foreach (var dz in dic[colDicNames[0]])
{
//得到屬於
PropertyInfo pro0 = this.type.GetProperty(colDicNames[0]);
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[0]) && dicUpdateCol[colDicNames[0]] == true)
{
hsUpdate.Add(colDicNames[0], dz);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro0, dz);
if (colDicNames.Count > 1 && dic[colDicNames[1]].Count > 0)
{
foreach (var dz1 in dic[colDicNames[1]])
{
//得到屬於
PropertyInfo pro1 = this.type.GetProperty(colDicNames[1]);
if (pro1 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[1]) && dicUpdateCol[colDicNames[1]] == true)
{
hsUpdate.Add(colDicNames[1], dz1);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro1, dz1);
if (colDicNames.Count > 2 && dic[colDicNames[2]].Count > 0)
{
foreach (var dz2 in dic[colDicNames[2]])
{
//得到屬於
PropertyInfo pro2 = this.type.GetProperty(colDicNames[2]);
if (pro2 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[2]) && dicUpdateCol[colDicNames[2]] == true)
{
hsUpdate.Add(colDicNames[2], dz2);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro2, dz2);
if (colDicNames.Count > 3 && dic[colDicNames[3]].Count > 0)
{
foreach (var dz3 in dic[colDicNames[3]])
{
//得到屬於
PropertyInfo pro3 = this.type.GetProperty(colDicNames[3]);
if (pro3 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[3]) && dicUpdateCol[colDicNames[3]] == true)
{
hsUpdate.Add(colDicNames[3], dz3);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro3, dz3);
if (colDicNames.Count > 4 && dic[colDicNames[4]].Count > 0)
{
foreach (var dz4 in dic[colDicNames[4]])
{
//得到屬於
PropertyInfo pro4 = this.type.GetProperty(colDicNames[4]);
if (pro4 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[4]) && dicUpdateCol[colDicNames[4]] == true)
{
hsUpdate.Add(colDicNames[4], dz4);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro4, dz4);
if (colDicNames.Count > 5 && dic[colDicNames[5]].Count > 0)
{
foreach (var dz5 in dic[colDicNames[5]])
{
//得到屬於
PropertyInfo pro5 = this.type.GetProperty(colDicNames[5]);
if (pro5 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[5]) && dicUpdateCol[colDicNames[5]] == true)
{
hsUpdate.Add(colDicNames[5], dz5);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro5, dz5);
if (colDicNames.Count > 6 && dic[colDicNames[6]].Count > 0)
{
foreach (var dz6 in dic[colDicNames[6]])
{
//得到屬於
PropertyInfo pro6 = this.type.GetProperty(colDicNames[6]);
if (pro6 == null)
{
LIS.Core.Util.LogUtils.WriteDebugLog("導入數據列名:" + colDicNames[1] + "在" + modelName + "不存在");
//清除錯誤
this.Err = "";
continue;
}
//加入更新條件
if (dicUpdateCol.ContainsKey(colDicNames[6]) && dicUpdateCol[colDicNames[6]] == true)
{
hsUpdate.Add(colDicNames[6], dz6);
}
LIS.DAL.ORM.Common.ReflectionUtils.SetPropertyValue(obj, pro6, dz6);
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
else
{
object[] obParams = null;
if (oper == "Update")
{
obParams = new object[] { obj, hsUpdate, this.Err, updateColName };
}
else
{
obParams = new object[] { obj, this.Err };
}
try
{
int ret = (int)wrapAdd.Invoke(exeobj, obParams);
this.Err = obParams[1] as string;
if (ret != 1)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + this.Err);
//清除錯誤
this.Err = "";
}
}
catch (Exception ex)
{
retList.Add("導入" + obj.GetType().Name + "數據保存錯誤:" + Helper.Object2Json(obj) + "<br/>" + ex.Message);
//清除錯誤
this.Err = "";
}
}
}
}
}
}
this.Err = "";
return Helper.Object2Json(retList);
}
this.Err = "";
retList.Add("導入的數據有問題! 請以^分割第二位指定某個表單對應的數據實體名,並約定第4行來指定數據庫的列名");
return Helper.Object2Json(retList);
}
上面的模式導致一個簡單讀取Excel數據到界面展示都很麻煩,不可避免的都有那三部操作。難度高,維護困難,有bug還不好跟。
從讀Excel這個事其實不難發現,業務讀Excel並不關心怎麼讀,只是想得到數據然後進行業務處理,那麼爲什麼不提供個公共JS方法,調用之後自動彈窗讓用戶選擇文件,然後選擇後上傳後臺,後臺統一解析文件後返回JSON數據給調用方回調,調用方根據回調的JSON數據做業務處理豈不是美哉。
公共JS實現
//檢驗上傳文件到FTP返回相對路徑,注意在單擊事件裏調用
//RetCallBack:帶一個參數的方法,返回數據會回調,參數就放第一個參數裏格式:{IsOk:true,Path:"",ShowBase:""}
//DirName:目錄文件夾名稱,不傳爲SYSHashFile
//LISUpFileToFTP(function (retPath) {
// alert(retPath);
//});
function LISUpFileToFTP(RetCallBack,DirName) {
LISUpFileToFTPCallBack = RetCallBack;
if (DirName == null) {
DirName = "";
}
LISUpFileToFTPDirName = DirName;
if ($("#LisSysCommonFTPFileUpload").length == 0) {
$(document.body).append('<input type="file" id="LisSysCommonFTPFileUpload" name="f" οnchange="LISSysLoadImportFTPData(this);" style="display: none" />');
}
$("#LisSysCommonFTPFileUpload").click();
}
//檢驗從Excel獲得json數據,注意在單擊事件裏調用
//RetCallBack:帶一個參數的方法,返回數據會回調,參數就放第一個參數裏
//LISGetExcelJson(function (retJson) {
// alert(JSON.stringify(retJson));
//});
function LISGetExcelJson(RetCallBack) {
LISGetExcelJsonRetCallBack = RetCallBack;
if ($("#LisSysCommonFileUpload").length == 0) {
$(document.body).append('<input type="file" id="LisSysCommonFileUpload" name="f" οnchange="LISSysLoadImportExcelData(this);" accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" style="display: none" />');
}
$("#LisSysCommonFileUpload").click();
}
//檢驗從文本文件獲得文本數據,注意在單擊事件裏調用
//RetCallBack:帶一個參數的方法,返回數據會回調,參數就放第一個參數裏
//LISGetTxtStr(function (retTxt) {
// alert(retTxt);
//});
function LISGetTxtStr(RetCallBack) {
LISGetTxtRetCallBack = RetCallBack;
if ($("#LisSysCommonTxtFileUpload").length == 0) {
$(document.body).append('<input type="file" id="LisSysCommonTxtFileUpload" name="f" οnchange="LISSysLoadImportTxtData(this);" accept=".txt,.json,.cs,.xml,.ashx,.aspx,html" style="display: none" />');
}
$("#LisSysCommonTxtFileUpload").click();
}
//載入導入數據
var LISGetExcelJsonRetCallBack = null;
function LISSysLoadImportExcelData(a) {
var data = new FormData();
var file = document.getElementById('LisSysCommonFileUpload').files[0];
data.append("file", file);
ajaxLoading();
var url = "../../sys/ashx/ashCommon.ashx?Method=GetExcelJson";
var callback = function (retData) {
$("#LisSysCommonFileUpload").val("");
ajaxLoadEnd();
if (LISGetExcelJsonRetCallBack != null) {
LISGetExcelJsonRetCallBack(jQuery.parseJSON(retData));
}
};
httpLisSys(data, url, callback);
}
//載入導入數據
var LISGetTxtRetCallBack = null;
function LISSysLoadImportTxtData(a) {
var data = new FormData();
var file = document.getElementById('LisSysCommonTxtFileUpload').files[0];
data.append("file", file);
ajaxLoading();
var url = "../../sys/ashx/ashCommon.ashx?Method=GetTxtStr";
var callback = function (retData) {
$("#LisSysCommonTxtFileUpload").val("");
ajaxLoadEnd();
if (LISGetTxtRetCallBack != null) {
LISGetTxtRetCallBack(retData);
}
};
httpLisSys(data, url, callback);
}
//上傳文件到FTP
var LISUpFileToFTPCallBack = null;
var LISUpFileToFTPDirName = "";
function LISSysLoadImportFTPData(a) {
var data = new FormData();
var file = document.getElementById('LisSysCommonFTPFileUpload').files[0]
data.append("file", file);
ajaxLoading();
var url = "../../sys/ashx/ashCommon.ashx?Method=UpFileToFTP&DirName=" + LISUpFileToFTPDirName;
var callback = function (retData) {
$("#LisSysCommonFTPFileUpload").val("");
ajaxLoadEnd();
if (LISUpFileToFTPCallBack != null) {
var retJson = jQuery.parseJSON(retData);
if (retJson.IsOk == true) {
LISUpFileToFTPCallBack(retJson);
}
else {
alert(retJson.Message);
}
}
};
httpLisSys(data, url, callback);
}
//上傳方法(HTML5)
function httpLisSys(date, url, callback) {
function createXHttpRequest() {
if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else {
return;
}
}
function starRequest(date) {
createXHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
callback(xmlhttp.response);
}
}
};
xmlhttp.open("POST", url, true);
xmlhttp.send(date);
}
starRequest(date);
}
後臺公共實現
/// <summary>
/// 把上傳的Excel文件讀取數據返回JSON
/// </summary>
/// <returns></returns>
public string GetExcelJson()
{
//返回結果
HttpFileCollection files = Request.Files;
//存Json串
StringBuilder sb = new StringBuilder();
sb.Append("[");
if (files.Count > 0)
{
IWorkbook workbook = null;
string fileName = files[0].FileName;
// 2007版本
if (fileName.IndexOf(".xlsx") > 0)
{
workbook = new XSSFWorkbook(files[0].InputStream);
}
// 2003版本
else if (fileName.IndexOf(".xls") > 0)
{
workbook = new HSSFWorkbook(files[0].InputStream);
}
else
{
return Helper.Error("導入文件格式錯誤!");
}
//得到表單的個數
int numSheets = workbook.NumberOfSheets;
int curSheetNum = 0;
//遍歷找到當前表單表單
for (int i = 0; i < numSheets; i++)
{
string curName = workbook.GetSheetAt(i).SheetName;
ISheet sheet = workbook.GetSheet(curName);
if (sheet == null)
{
continue;
}
//最後一列的標號
int rowCount = sheet.LastRowNum;
if (rowCount == 0)
{
continue;
}
IRow firstRow = sheet.GetRow(0);
if (curSheetNum == 0)
{
sb.Append("[");
}
else
{
sb.Append(",[");
}
curSheetNum++;
//一行最後一個cell的編號 即總的列數
int cellCount = 0;
if (firstRow != null)
{
cellCount = firstRow.LastCellNum;
}
int curRowNum = 0;
for (int j = 0; j <= rowCount; j++)
{
IRow curRow = sheet.GetRow(j);
if (curRow == null)
{
continue;
}
if (firstRow == null)
{
firstRow = curRow;
cellCount = firstRow.LastCellNum;
}
if (curRowNum == 0)
{
sb.Append("{");
}
else
{
sb.Append(",{");
}
curRowNum++;
int curCellNum = 0;
for (int k = curRow.FirstCellNum; k < cellCount; k++)
{
ICell cell = curRow.GetCell(k);
if (cell == null)
{
continue;
}
object cellVal = null;
if (cell.CellType == CellType.Numeric)
{
cellVal = cell.NumericCellValue;
}
else if (cell.CellType == CellType.String)
{
cellVal = cell.StringCellValue;
}
else if (cell.CellType == CellType.Boolean)
{
cellVal = cell.BooleanCellValue;
}
else
{
cellVal = "";
}
if (curCellNum == 0)
{
sb.Append("\"" + NumbertoString(k + 1) + "\":\"" + DealForJsonString(cellVal.ToString()) + "\"");
}
else
{
sb.Append(",\"" + NumbertoString(k + 1) + "\":\"" + DealForJsonString(cellVal.ToString()) + "\"");
}
curCellNum++;
}
sb.Append("}");
}
sb.Append("]");
}
}
sb.Append("]");
return sb.ToString();
}
/// <summary>
/// 把上傳的txt文件讀取數據返回JSON
/// </summary>
/// <returns></returns>
public string GetTxtStr()
{
HttpFileCollection files = Request.Files;
string retStr = "";
if (files.Count > 0)
{
StreamReader sr = new StreamReader(files[0].InputStream, Encoding.Default);
retStr = sr.ReadToEnd();
sr.Close();
sr = null;
files[0].InputStream.Close();
}
return retStr;
}
/// <summary>
/// 處理json衝突串
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private string DealForJsonString(string str)
{
if (str == "")
{
return str;
}
else
{
return str.Replace("\0", " ").Replace("\a", "\\a").Replace("\b", "\\b").Replace("\f", "\\f").Replace("\t", "\\t").Replace("\v", "\\v").Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\r", " ").Replace("\n", " ");
}
}
/// <summary>
/// 將指定數值轉換成Excel列名
/// </summary>
/// <param name="colIndex">數值</param>
/// <returns>返回數值對應的Excel列名</returns>
private string NumbertoString(int colIndex)
{
string strResult = "";
int once = colIndex / 26;
int twice = colIndex % 26;
strResult = ((char)(twice - 1 + 'A')).ToString() + strResult;
if (once > 26)
{
strResult = NumbertoString(once) + strResult;
}
else if (once > 0)
{
strResult = ((char)(once - 1 + 'A')).ToString() + strResult;
}
return strResult;
}
使用示例
//模板導入
$("#btnInport").click(function () {
LISGetExcelJson(function (retJson) {
//刪除模板頭
retJson[0].splice(0, 1);
//往數據表格綁定數據
$("#dgData").datagrid("loadData", retJson[0]);
});
});
Excel示例
回調返回的數據
[[{"A":"醫院","B":"菌株編號","C":"年齡","D":"性別","E":"病例號","F":"科室","G":"門診/急診/病房","H":"臨牀診斷","I":"化驗號","J":"標本採集日期","K":"標本類型","L":"標本分離部位","M":"原始鑑定結果","N":"鑑定方法","O":"複覈結果"},{"A":"標準版醫院","B":"16LN12001","C":"10","D":"男","E":"DH000001","F":"消化內科","G":"門診","H":"腎積水","I":"DHL00001","J":"20191111","K":"血液","L":"胃液","M":"光滑念珠菌","N":"vitek","O":"vi"},{"A":"標準版醫院","B":"16LN12002","C":"21","D":"男","E":"DH000002","F":"呼吸內科","G":"門診","H":"胃惡性腫瘤","I":"DHL00002","J":"20191111","K":"引流液","L":"痰","M":"白色念珠菌","N":"vitek","O":""},{"A":"標準版醫院","B":"16LN12003","C":"12","D":"女","E":"DH000003","F":"呼吸內科","G":"門診","H":"胃腸惡性腫瘤","I":"DHL00003","J":"20191111","K":"血液","L":"痰","M":"無名假絲酵母菌","N":"vitek","O":""}]]
這樣就把開始那種複雜模式直接簡化到只有JS調用那一句話然後處理JSON數據的事了。有了基礎了再做讀Excel數據的功能是不是就簡單了呢。讀取模塊還穩定。