今天就不扯淡了,写点有用的!最近公司接了一个小任务,有家商务公司要弄一个工资Excel表格的导入导出。然后这个任务就交给我了。因为以前没整过,经过一天半的研究弄完了,可能不太好。就当给没弄过这个的人一个Demo吧!
其实网上这个材料很多。有的是用微软的office自带的去实现(缺点是进程需要强制杀死!),有的是用第三方插件!但是都有利弊。我也是参照了很多人的东西最后选择了Oledb 方式来实现的。因为这样客户端可以不装office软件。主要是实现与数据库的简单互操作,下面我就把代码贴出来。
1、首先我们要创建数据库中的相关字段(这个不是工资的,是人员的。其实都一样),和解决方案截图。
--ID(主键自增) 、姓名、年龄、地址
简单的解决方案
2、创建一个增加、查询的方法(当然数据Helper层也要创建)那好吧都粘出来了!
private string sqlcon = "server=.;database=ExcelDB;uid=sa;pwd=sa"; /// <summary> /// ExecuteNonQuery /// </summary> public int ExecuteNonQuery(string sql, SqlParameter[] pars, CommandType cmdType) { using (SqlConnection SConn = new SqlConnection(sqlcon)) { SConn.Open(); int i = 0; try { SqlCommand cmd = new SqlCommand(); if (pars != null) { cmd.Parameters.AddRange(pars); } cmd.CommandText = sql; cmd.CommandType = cmdType; cmd.Connection = SConn; i = cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); } catch (Exception ex) { throw new ApplicationException(ex.Message); } finally { SConn.Close(); } return i; } } /// <summary> /// DataTable /// </summary> public DataTable GetDataTable(string sql, CommandType cmdType, params SqlParameter[] pars) { using (SqlConnection SConn = new SqlConnection(sqlcon)) { SConn.Open(); DataSet ds = new DataSet(); try { SqlCommand cmd = new SqlCommand(); if (pars != null) { foreach (SqlParameter p in pars) { cmd.Parameters.Add(p); } } cmd.CommandText = sql; cmd.CommandType = cmdType; cmd.Connection = SConn; SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(ds); cmd.Parameters.Clear(); } catch (Exception ex) { throw new ApplicationException(ex.Message); } finally { SConn.Close(); } return ds.Tables[0]; } }
上面的这些就不解释了,为了方便我当时也是从别的地方拷贝过来的。
3、下面构造三个方法
AddExcel()是向数据库中插入表格用的、GetList()页面显示数据、GetTable()
/// <summary> /// 添加 /// </summary> /// <param name="en"></param> /// <returns></returns> public int AddExcel(Entity en) { string sql = "insert into userinfo(name,age,[address]) values(@name,@age,@address)"; SqlParameter[] pars = new SqlParameter[]{ new SqlParameter("@name",SqlDbType.VarChar,50), new SqlParameter("@age",SqlDbType.Int), new SqlParameter("@address",SqlDbType.VarChar,50) }; pars[0].Value = en.Name; pars[1].Value = en.Age; pars[2].Value = en.Address; try { int res = ExecuteNonQuery(sql, pars, CommandType.Text); return res; } catch (Exception ex) { throw new ApplicationException(ex.Message); } } /// <summary> /// 查询全部数据 /// </summary> /// <returns>返回List</returns> public IList<Entity> GetList() { string sql = "select * from userinfo"; IList<Entity> list = new List<Entity>(); using (DataTable dt = GetDataTable(sql, CommandType.Text)) { Entity en; foreach (DataRow dr in dt.Rows) { en = new Entity(); en.Id = Convert.ToInt32(dr["id"]); en.Name = dr["name"].ToString(); en.Age = Convert.ToInt32(dr["age"]); en.Address = dr["address"].ToString(); list.Add(en); } } return list; } /// <summary> /// 查询全部数据 /// </summary> /// <returns>返回DataTable</returns> public DataTable GetTable() { string sql = "select * from userinfo"; IList<Entity> list = new List<Entity>(); DataTable dt = GetDataTable(sql, CommandType.Text); return dt; }
4、当然为了简单起见,就把上边的代码都放在了一个DBHelper类当中。继续建立一个实体类Entity
/// <summary> /// Entity实体类 /// </summary> public class Entity { private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } private int age; public int Age { get { return age; } set { age = value; } } private string address; public string Address { get { return address; } set { address = value; } } }
准备工作基本完成:也就说靠这些东西已经能从数据库中存数据和取数据了。
5、主要的部分:
建立Get_Excel类,这里是导入Excel到数据库,因为涉及到工作单Sheet所以先获取工作单名字,代码如下注释很清晰:
/// <summary> /// Excel导入到数据库 /// </summary> public class Get_Excel { /// <summary> /// 将Excel表格转化为DataTable /// </summary> /// <param name="filepath"></param> /// <param name="sheetname"></param> /// <returns></returns> public DataTable ExcelToSql(string filepath, string sheetname) { string strConn; strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;"; OleDbConnection conn = new OleDbConnection(strConn); OleDbDataAdapter oada = new OleDbDataAdapter("select * from [" + sheetname + "]", strConn); DataSet ds = new DataSet(); oada.Fill(ds); return ds.Tables[0]; } /// <summary> /// 获取Excel的Sheet工作单名字 /// </summary> /// <param name="filepath"></param> /// <returns></returns> public ArrayList ExcelSheetName(string filepath) { ArrayList al = new ArrayList(); string strConn; // strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;"; //支持2003 strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;"; //支持2007以上版本 OleDbConnection conn = new OleDbConnection(strConn); conn.Open(); DataTable sheetNames = conn.GetOleDbSchemaTable (System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); conn.Close(); foreach (DataRow dr in sheetNames.Rows) { al.Add(dr[2]); } return al; } }
接下来我们来创建一个简单的界面以便于一会导入数据,需要个FileUpload控件(当然file标签也行)当然要注意的是对于获取绝对路径获取的问题,一般想获取客户端的绝对路径可能性不现实。因为存在浏览器的问题,在IE下FileUpload1.PostedFile.FileName是可以获取到绝对路径的,前提是IE中 工具 -> Inter选项 ->安全 ->自定义级别->将文件上载服务器包含本地目录路径->启用 这样方可访问,这个根本没什么用。一般解决这个问题都是把文件上传到服务器善后获取服务器上的路径。然后文件使用后删除就OK 了。(当然简单起见我就用IE了,不那么麻烦了。)
这个是上面的那个Button的事件。
/// <summary> /// 将导入数据库 /// </summary> protected void setBtn_Click(object sender, EventArgs e) { string path = FileUpload1.PostedFile.FileName; //获取文件路径 Get_Excel gete = new Get_Excel(); ArrayList name = gete.ExcelSheetName(path); //获取名字数组 string sheet = name[0].ToString(); //获取第一个Sheet名字 DataTable dt = gete.ExcelToSql(path, sheet); //获取读取的Excel的表格 if (dt.Rows.Count > 0) { DBHelper db = new DBHelper(); Entity en = new Entity(); //循环DataRow 将数据插入到数据库 foreach (DataRow dr in dt.Rows) { en.Name = dr[0].ToString(); en.Age = Convert.ToInt32(dr[1]); en.Address = dr[2].ToString(); db.AddExcel(en); } } this.Label1.Text = "数据导入成功"; }
这样就实现的把Excel导入到数据库了。
6、接下来我们来看一下怎么样导出Excel表格,首先要建立模板Demo.xslx 设置好类型跟导出的类型匹配。
然后下面的代码就是导出的主要代码了,主要就是依靠模板,然后建立临时表格,生成后删除临时表格。替换作用
/// <summary> /// Excel导入到数据库 /// </summary> public class Set_Excel { /// <summary> /// 模板导出Excel /// </summary> public void ToExcel(List<Entity> list) { // 根据模板文件创建副本 string filePath = HttpContext.Current.Server.MapPath("~/Excle表格/" + Guid.NewGuid().ToString() + ".xlsx"); File.Copy(HttpContext.Current.Server.MapPath("~/Excle表格/Demo.xlsx"), filePath); try { // 使用OleDb驱动程序连接到副本 OleDbConnection conn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=Excel 8.0;"); using (conn) { conn.Open(); foreach (Entity i in list) { // 增加记录 OleDbCommand cmd = new OleDbCommand("INSERT INTO [Sheet1$]([姓名],[年龄],[地址]) VALUES(@Name,@Age,@Address)", conn); //[ID],@Id, //cmd.Parameters.AddWithValue("@Id","1"); cmd.Parameters.AddWithValue("@Name", i.Name); cmd.Parameters.AddWithValue("@Age", i.Age); cmd.Parameters.AddWithValue("@Address", i.Address); cmd.ExecuteNonQuery(); } } // 输出副本的二进制字节流 HttpContext.Current.Response.ContentType = "application/ms-excel"; HttpContext.Current.Response.AppendHeader("Content-Disposition", "p_w_upload;filename=userinfo.xlsx"); HttpContext.Current.Response.BinaryWrite(File.ReadAllBytes(filePath)); } catch (Exception ex) { throw new ApplicationException(ex.Message); } finally { // 删除副本 File.Delete(filePath); } } }
还没完接下来还有页面呢,简单起见我们就拖控件了,接着看:
cs代码如下:
private DBHelper db = new DBHelper(); protected void Page_Load(object sender, EventArgs e) { this.DataGrid1.DataSource = db.GetList(); this.DataGrid1.DataBind(); } protected void Button1_Click(object sender, EventArgs e) { List<Entity> list = db.GetList().ToList(); Set_Excel sete = new Set_Excel(); sete.ToExcel(list); }
这样就完成了Oledb导入导出Excel的全部过程了。如果单单应付一个简单表格,绰绰有余。但是复杂一点业务的话,就说不准了。呵呵!