完整教程鏈接:ASP.Net: EshineASPNet-基於ASP.Net敏捷開發開源框架
Excel的導入與導出是後臺最常用的功能之一了,這裏分享一下實現方式。
導入
要實現excel導入,這裏使用OLEDB,先引用System.Data.OleDb。
public DataTable InputExcel(string TableName)
{
try
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + "Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
string strExcel = "select * from [" + TableName + "$]";
OleDbDataAdapter myCommand = new OleDbDataAdapter(strExcel, strConn);
DataTable dt = new DataTable();
myCommand.Fill(dt);
conn.Close();
return dt;
}
catch (Exception ex)
{
return null;
}
}
上面的函數以Sheet名作爲輸入,支持中文,可以選擇Excel裏面的哪張表來導入,讀取的數據保存在DataTable。然後就可以對DataTable裏面的數據逐行處理並插入數據庫。
導出
如果數據是存在GridView控件裏面的,那麼有個簡便方法可以導出,先添加System.Web.UI和System.Web.UI.HtmlControls引用。
public void gridviewtoexcel(GridView gv, string filename)
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(sw);
Page page = new Page();
HtmlForm form = new HtmlForm();
for (int i = 0; i < gv.Rows.Count; i++)
{
if (gv.Rows[i].FindControl("GridView2") != null)
{
gv.Rows[i].Cells.RemoveAt(0);
gv.Rows[i].Cells.RemoveAt(gv.Rows[i].Cells.Count - 1);
}
}
gv.EnableViewState = false;
// Deshabilitar la validación de eventos, sólo asp.net 2
page.EnableEventValidation = false;
// Realiza las inicializaciones de la instancia de la clase Page que requieran los diseñadores RAD.
page.DesignerInitialize();
page.Controls.Add(form);
form.Controls.Add(gv);
page.RenderControl(htw);
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".xls");
System.Web.HttpContext.Current.Response.Charset = "UTF-8";
System.Web.HttpContext.Current.Response.ContentEncoding = Encoding.Default;
System.Web.HttpContext.Current.Response.ContentType = "application/excel";
string style = @"<style> .text { mso-number-format:\@; } </script> ";
System.Web.HttpContext.Current.Response.Write(style);
System.Web.HttpContext.Current.Response.Write(sb.ToString());
System.Web.HttpContext.Current.Response.End();
}
上面是實現導出的標準代碼,其中Charset和style的設置用來支持中文和避免亂碼。
但如果是MVC的話這個就不太合適了,而且這種導出方式也有點問題,當遇到大且複雜的gridview時就知道了。那麼這時候就用下面的方法,在使用前需要引用NPOI.XSSF.UserModel,NPOI.SS.UserModel,NPOI.SS.Util。
/// <summary>
/// 根據dataTable生成Excel
/// </summary>
/// <param name="dt">數據源</param>
/// <param name="sheetName">sheet名稱</param>
/// <param name="header">標題</param>
/// <returns></returns>
public static XSSFWorkbook Export(DataTable dt, string sheetName, string header, out string msg)
{
try
{
XSSFWorkbook workbook = new XSSFWorkbook();
ISheet sheet;
if (!string.IsNullOrEmpty(sheetName))
sheet = workbook.CreateSheet(sheetName);
else
sheet = workbook.CreateSheet("sheet1");
ICellStyle dateStyle = workbook.CreateCellStyle();
IDataFormat format = workbook.CreateDataFormat();
dateStyle.DataFormat = format.GetFormat("yyyy-MM-dd hh:ss:mm");
//取得列寬
int[] arrColWidth = new int[dt.Columns.Count];
foreach (DataColumn item in dt.Columns)
{
arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
}
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
int intTemp = Encoding.GetEncoding(936).GetBytes(dt.Rows[i][j].ToString()).Length;
if (intTemp > arrColWidth[j])
{
arrColWidth[j] = intTemp;
}
}
}
int rowIndex = 0;
foreach (DataRow row in dt.Rows)
{
#region 新建表,填充表頭,填充列頭,樣式
//if (rowIndex >= 1048570 || rowIndex == 0)
if (rowIndex >= 1048570 || rowIndex == 0)
{
if (rowIndex != 0)
{
sheet = workbook.CreateSheet();
}
#region 表頭及樣式
{
IRow headerRow = sheet.CreateRow(0);
headerRow.HeightInPoints = 25;
headerRow.CreateCell(0).SetCellValue(header);
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 20;
font.Boldweight = 700;
headStyle.SetFont(font);
headerRow.GetCell(0).CellStyle = headStyle;
sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dt.Columns.Count - 1));
//headerRow
}
#endregion
#region 列頭及樣式
{
IRow headerRow = sheet.CreateRow(1);
ICellStyle headStyle = workbook.CreateCellStyle();
headStyle.Alignment = HorizontalAlignment.Center;
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 10;
font.Boldweight = 700;
headStyle.SetFont(font);
foreach (DataColumn column in dt.Columns)
{
headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
//設置列寬
sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 1) * 256);
}
//headerRow.Dispose();
}
#endregion
rowIndex = 2;
}
#endregion
#region 填充內容
IRow dataRow = sheet.CreateRow(rowIndex);
foreach (DataColumn column in dt.Columns)
{
ICell newCell = dataRow.CreateCell(column.Ordinal);
string drValue = row[column].ToString();
switch (column.DataType.ToString())
{
case "System.String"://字符串類型
newCell.SetCellValue(drValue);
break;
case "System.DateTime"://日期類型
DateTime dateV;
bool torf = DateTime.TryParse(drValue, out dateV);
if (torf && dateV != System.Data.SqlTypes.SqlDateTime.MinValue && dateV != new DateTime())
{
newCell.SetCellValue(dateV);
newCell.CellStyle = dateStyle;//格式化顯示
}
else
newCell.SetCellValue("");
break;
case "System.Boolean"://布爾型
bool boolV = false;
bool.TryParse(drValue, out boolV);
newCell.SetCellValue(boolV);
break;
case "System.Int16"://整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
int intV = 0;
int.TryParse(drValue, out intV);
newCell.SetCellValue(intV);
break;
case "System.Decimal"://浮點型
case "System.Double":
double doubV = 0;
double.TryParse(drValue, out doubV);
newCell.SetCellValue(doubV);
break;
case "System.DBNull"://空值處理
newCell.SetCellValue("");
break;
default:
newCell.SetCellValue("");
break;
}
}
#endregion
rowIndex++;
}
msg = string.Empty;
return workbook;
}
catch (Exception ex)
{
msg = ex.Message;
return null;
}
//try
//{
// FileStream fs = new FileStream(filename, FileMode.CreateNew);//(filename, FileMode.Create, FileAccess.Write);
// workbook.Write(fs);
// //fs.Flush();
// return true;
//}
//catch (Exception ex)
//{
// throw new Exception(ex.Message);
// return false;
//}
//using (MemoryStream ms = new MemoryStream())
//{
// workbook.Write(ms);
// ms.Flush();
// //ms.Position = 0;
// //sheet.Dispose();
// return ms;
//}
}
public void DatatableToExcel(DataTable list)
{
string msg = string.Empty;
XSSFWorkbook work = Export(list, "", "header", out msg);
Response.Clear();
Response.ClearHeaders();
if (work == null && !string.IsNullOrEmpty(msg))
throw new Exception(msg);
Response.Buffer = false;
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";//ContentType;
Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode("export.xlsx", System.Text.Encoding.UTF8));
MemoryStream ms = new MemoryStream();
work.Write(ms);
Response.BinaryWrite(ms.ToArray());
work = null;
ms.Close();
ms.Dispose();
Response.Flush();
Response.End();
}
上面這種導出Excel方式同樣適用於MVC,可以實現DataTable到Excel的導出,並且網頁端直接彈出文件下載。如果要保存文件到本地可以參考註釋掉的那段代碼。
本教程代碼參考
EshineASPNet\Web\App_Code\upExcel.cs
EshineASPNet\Web\App_Code\PublicClass.cs