c# 导出excel的三种方式

第一种:流导出

            SaveFileDialog exe = new SaveFileDialog();
            exe.Filter = "Execl files (*.xls)|*.xls";
            exe.FilterIndex = 0;
            exe.RestoreDirectory = true;
            //exe.CreatePrompt = true;
            exe.Title = "Export Excel File";
            exe.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            exe.FileName = string.Format("{0}_{1}", DateTime.Now.ToString("yyyy-MM-dd HH时mm分ss秒"), "导出");
            DialogResult dr = exe.ShowDialog();
            if (dr != DialogResult.OK)
            {
                return;
            }

        Stream ms;
            ms = exe.OpenFile();
            StreamWriter sw = new StreamWriter(ms, System.Text.Encoding.GetEncoding(-0));
            string str = "";
            try
            {
                for (int i = 0; i < dtb.Columns.Count; i++)
                {
                    if (i > 0)
                    {
                        str += "\t";
                    }
                    str += dtb.Columns[i].HeaderText;
                }
                sw.WriteLine(str);
                for (int j = 0; j < dtb.Rows.Count; j++)
                {
                    string temp = "";
                    for (int k = 0; k < dtb.Columns.Count; k++)
                    {
                        if (k > 0)
                        {
                            temp += "\t";
                        }
                        string cell = dtb.Rows[j].Cells[k].Value.ToString();
                        cell = cell.Replace(" ", "").Replace("\r", "").Replace("\n", "").Replace("\r\n", "");
                        temp += cell;
                    }
                    sw.WriteLine(temp);
                }
                sw.Close();
                ms.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            finally
            {
                sw.Close();
                ms.Close();
            }

第二种:使用 Microsoft.Office.Interop.Excel.dll

Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            if (xlApp == null)
            {
                MessageBox.Show("无法创建Excel对象,可能您的机子未安装Excel");
                return;
            }
            try
            {

                Workbooks wbs = xlApp.Workbooks;
                Workbook wb = wbs.Add(XlWBATemplate.xlWBATWorksheet);
                Worksheet ws = (Worksheet)wb.Worksheets[1];
                Range range = xlApp.Range[ws.Cells[1, 1], ws.Cells[1, colcount]];
                range.Font.Size = 10;
                range.Font.Bold = true;
                range.Interior.ColorIndex = 15;
                range.HorizontalAlignment = Constants.xlCenter;




                object[,] obj = new object[rowcount + 1, colcount];
                foreach (DataGridViewColumn col in dtb.Columns)
                {
                    obj[rowindex, colindex++] = col.HeaderText;
                }
                for (rowindex = 1; rowindex < rowcount + 1; rowindex++)
                {
                    for (colindex = 0; colindex < colcount; colindex++)
                    {
                        obj[rowindex, colindex] = "'" + dtb[colindex, rowindex - 1].Value;
                    }
                    System.Windows.Forms.Application.DoEvents();
                }
                range = ws.Range[xlApp.Cells[1, 1], xlApp.Cells[rowcount + 1, colcount]];
                range.Value2 = obj;
                wb.Saved = true;
                wb.SaveCopyAs(exe.FileName);





                //for (int i = 0; i < dtb.ColumnCount; i++)
                //{
                //    if (dtb.Columns[i].Visible)
                //    {
                //        colindex++;
                //        ws.Cells[1, colindex] = dtb.Columns[i].HeaderText;
                //    }
                //}
                //for (int r = 0; r < dtb.Rows.Count; r++)
                //{
                //    colindex = 0;
                //    for (int i = 0; i < dtb.ColumnCount; i++)
                //    {
                //        if (dtb.Columns[i].Visible)
                //        {
                //            colindex++;
                //            ws.Cells[r + 2, colindex] = "'" + dtb.Rows[r].Cells[i].Value;
                //        }
                //    }
                //}
                //System.Windows.Forms.Application.DoEvents();
                //wb.SaveAs(exe.FileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show("导出文件时出错,文件可能正被打开!\n" + ex.Message);
            }
            finally
            {
                xlApp.Quit();
                GC.Collect();
            }

这两种方法导出 .xlsx 格式的 Excel 文件时,没办法打开。导出 .xls 格式的,会提示文件格式和扩展名不匹配(没找到办法解决,找到的园友留下言),但是可以打开的。

第二种电脑必须要安装 office,而且导出速度慢,导出大数据时性能很差。

第三种:Microsoft.Jet.OLEDB

// Excel 2003 版本连接字符串
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:/xxx.xls;Extended Properties='Excel 8.0;HDR=Yes;IMEX=2;'";

// Excel 2007 以上版本连接字符串
string strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/xxx.xlsx;Extended Properties='Excel 12.0;HDR=Yes;IMEX=2;'";

Provider:驱动程序名称

Data Source:指定 Excel 文件的路径

Extended Properties:Excel 8.0 针对 Excel 2000 及以上版本;Excel 12.0 针对 Excel 2007 及以上版本。

HDR:Yes 表示第一行包含列名,在计算行数时就不包含第一行。NO 则完全相反。

IMEX:0 写入模式;1 读取模式;2 读写模式。如果报错为“不能修改表 sheet1 的设计。它在只读数据库中”,那就去掉这个,问题解决。

private string ToExcel(DataGridView dtb,string filename)
        {
            try
            {
                int colcount = dtb.ColumnCount;
                int rowcount = dtb.RowCount;
                if (rowcount > 0)
                {
                    string path = @"export\";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    string pfilename = path + filename + ".xls";
                    File.Copy(path + "model.xls", pfilename);
                    //string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pfilename + ";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=2;\"";
                    using (OleDbConnection ole =new OleDbConnection())
                    {
                        //ole.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + pfilename + ";Extended Properties=\"Excel 12.0 Xml;HDR=Yes\"";
                        ole.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pfilename + ";Extended Properties=\"Excel 8.0;HDR=Yes;\"";
                        ole.Open();
                        using(OleDbCommand oleCmd=new OleDbCommand())
                        {
                            oleCmd.Connection = ole;

                            //System.Data.DataTable dtsheet = ole.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
                            //foreach(DataRow dr in dtsheet.Rows)
                            //{
                            //    oleCmd.CommandText = "drop table [" + dr["TABLE_NAME"].ToString() + "]";
                            //    oleCmd.ExecuteNonQuery();
                            //}
                            //oleCmd.CommandText = "drop table [Sheet1$]";
                            //oleCmd.ExecuteNonQuery();

                            ArrayList alCol = new ArrayList();
                            OleDbParameter[] para = new OleDbParameter[colcount];
                            ArrayList aric = new ArrayList();
                            ArrayList ariv = new ArrayList();
                            for(int i = 0; i < colcount; i++)
                            {
                                para[i] = new OleDbParameter("@" + dtb.Columns[i].HeaderText, OleDbType.VarChar);
                                alCol.Add("[" + dtb.Columns[i].HeaderText + "] VarChar");
                                aric.Add("[" + dtb.Columns[i].HeaderText + "]");
                                ariv.Add("@" + dtb.Columns[i].HeaderText);
                            }
                            string strIs = "insert into [Sheet1$] (" + string.Join(",", aric.ToArray()) + ") values (" + string.Join(",", ariv.ToArray()) + ")";
                            string strCs = "create table [Sheet1$] (" + string.Join(",", alCol.ToArray()) + ")";

                            oleCmd.CommandText = strCs;
                            int en = oleCmd.ExecuteNonQuery();

                            List<OleDbParameter> lop = new List<OleDbParameter>();
                            ArrayList arrow = new ArrayList();
                            for(int j = 0; j < rowcount; j++)
                            {
                                arrow.Clear();
                                lop.Clear();
                                oleCmd.Parameters.Clear();
                                for(int k = 0; k < colcount; k++)
                                {
                                    para[k].Value = dtb[k, j].Value.ToString();
                                    oleCmd.Parameters.Add(para[k]);
                                }
                                //oleCmd.Connection = ole;
                                oleCmd.CommandText = strIs;
                                oleCmd.ExecuteNonQuery();
                            }
                        }
                    }
                    return "success";
                }else
                {
                    return "null";
                }
            }catch(Exception ex)
            {
                return ex.Message;
            }
        }

这种方法需要指定一个已经存在的 Excel 文件作为写入数据的模板,不然的话就得使用流创建一个新的 Excel 文件,但是这样是没法识别的,那就需要用到 Microsoft.Office.Interop.Excel.dll 里面的 Microsoft.Office.Interop.Excel.Workbook.SaveCopyAs() 方法另存为一下,这样性能也就更差了。

使用操作命令创建的表都是在最后面的,前面的也没法删除(我是没有找到方法),当然也可以不再创建,直接写入数据也可以。但是很奇怪,直接写入时列头下的第一行会空白着,数据从第三行开始写入。如果是新建表写入数据就不会出现这种情况。

posted @ 2019-11-15 16:25  君莫笑·秋  阅读(21427)  评论(2编辑  收藏  举报