C#中DataGridView数据导出到Excel

来源:互联网 发布:米折是淘宝网的吗 编辑:程序博客网 时间:2024/05/16 04:59

最近在做一个小程序,需要将DataGridView中的数据导出到Excel中显示和保存。最开始用使用如下代码实现:

SaveFileDialog dlg = new SaveFileDialog();   //实例化一个SaveFileDialog保存文件对话框            dlg.Filter = "Excel files (*.xls)|*.xls";            dlg.FilterIndex = 0;            dlg.RestoreDirectory = true;            dlg.CreatePrompt = true;            dlg.Title = "保存为excel文件";            if (dlg.ShowDialog() == DialogResult.OK)            {                Stream mystream;  //stream类是读写字节数据的数据流类中最基础的基类                mystream = dlg.OpenFile();    //打开用户选定的具有读写权限的文件,并把获取的文件路径赋值给mystream                StreamWriter sw = new StreamWriter(mystream, System.Text.Encoding.GetEncoding(-0));   //实例化数据流的写入,encoding获取编码方式                string columntitle = "";                try                {                    //写入列标题                    for (int i = 0; i < dataGridView_resultDisplay.ColumnCount; i++)                    {                        if (i > 0)                        {                            columntitle += "\t"; //添加一个分隔符                        }                        columntitle += dataGridView_resultDisplay.Columns[i].HeaderText;                    }                    sw.WriteLine(columntitle);                    //写入列内容                    for (int j = 0; j < dataGridView_resultDisplay.Rows.Count; j++)                    {                        string columnvalue = "";                        for (int k = 0; k < dataGridView_resultDisplay.Columns.Count; k++)                        {                            if (k > 0)                                columnvalue += "\t";                            if (dataGridView_resultDisplay.Rows[j].Cells[k].Value == null)                                columnvalue += "";                            else                                columnvalue += dataGridView_resultDisplay.Rows[j].Cells[k].Value.ToString().Trim();                        }                        sw.WriteLine(columnvalue);                    }                    sw.Close();                    mystream.Close();                    textExportPath.Text = dlg.FileName;                                        MessageBox.Show("分类汇总结果已保存到【" + dlg.FileName + "】");                }                catch (Exception ex)                {                    MessageBox.Show(ex.ToString());                }                finally                {                    sw.Close();                    mystream.Close();                }                            }
利用上述代码实现后,能够保存.xls格式的文件。但在打开这个文件时会出现如下问题:


在网上搜上了一下,这种方法生成的Excel根本不是Excel,只不过扩展名是xls而已,所以打开的时候会提示“您尝试打开的文件**.xls的格式与文件扩展名指定的格式不一致”这是Excel的安全问题,暂时解决办法如下,取消Exce的安全检测。怎么样取消Excel的安全检测,可以到修改注册表:

1、开始 -> 运行 -> 输入regedit -> 确定
2、找到注册表子项HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security
3、在右侧空白处点击鼠标右键,选择“新建 -> DWORD值(D)”,输入"ExtensionHardening"点击确定。
4、用鼠标右键点击ExtensionHardening,然后单击“修改(M)”,在数值数据中填写"0"即可确定。
5、关闭注册表编辑器,再次打开xls文件看看是不是提示是不是不见了?
拓展:ExtensionHardening设置的值的数据设置:
0:不检查文件扩展名和文件类型并绕过该函数的警告消息。
1:检查文件扩展名和文件类型。如果它们不匹配会显示警告消息。
2:检查文件扩展名和文件类型。如果它们不匹配不要打开该文件

为了长久解决上面的问题,又查找了一些资料,找到另一条途径实现:

在项目引用中添加了Microsoft Excel11 Object Libray,用如下代码实现,即可解决(若无法使用” Microsoft.Office.Interop.Excel”,可参考我的另一篇文章解决):

            int iRows = 0;            int iCols = 0;            int iTrueCols = 0;            int i, j, k;            string SheetName = "test";            Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();            Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Add(System.Reflection.Missing.Value);            Microsoft.Office.Interop.Excel.Worksheet ws = null;            if (wb.Worksheets.Count > 0)            {                ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);            }            else            {                wb.Worksheets.Add(System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);                ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);            }            if (ws != null)            {                if (SheetName.Trim() != null)                {                    ws.Name = SheetName;                }                iRows = dataGridView_resultDisplay.Rows.Count;                iTrueCols = dataGridView_resultDisplay.Columns.Count;                for (i = 0; i < dataGridView_resultDisplay.Columns.Count; i++)                {                    if (dataGridView_resultDisplay.Columns[i].Visible)                    {                        iCols++;                    }                }                MessageBox.Show(Convert.ToString(iTrueCols) + "    "+Convert.ToString(iRows));                for (j = 0; j < iTrueCols; j++)                {                    if (dataGridView_resultDisplay.Columns[j].Visible)                    {                        if (dataGridView_resultDisplay.Columns[j].HeaderText.Trim() != null)                            ws.Rows[1].Cells[j + 1] = dataGridView_resultDisplay.Columns[j].HeaderText.Trim();                    }                }                for (i = 1; i < iRows; i++)                {                    for (j = 0; j < iTrueCols; j++)                    {                        string str;                        if (dataGridView_resultDisplay.Rows[i - 1].Cells[j].Value.ToString().Trim() == null)                        {                            str = "0";                        }                        else                        {                            str = dataGridView_resultDisplay.Rows[i - 1].Cells[j].Value.ToString().Trim();                        }                        ws.Cells[i + 1, j+1] = str;                    }                }                ws.Range[ws.Cells[1, 1], ws.Cells[1, iCols]].Font.Bold = true;                ws.Range[ws.Cells[1, 1], ws.Cells[iRows + 1, iCols]].Font.Size = 10.0;                ws.Range[ws.Cells[1, 1], ws.Cells[iRows + 1, iCols]].RowHeight = 14.25;                               for (j = 0, k = 0; j < iTrueCols; j++)                {                    //省略Visible = false的列                      if (dataGridView_resultDisplay.Columns[j].Visible)                    {                        ws.Range[ws.Cells[1, k + 1], ws.Cells[1, k + 1]].ColumnWidth = (dataGridView_resultDisplay.Columns[j].Width / 8.4) > 255 ? 255 : (dataGridView_resultDisplay.Columns[j].Width / 8.4);                        k++;                    }                }                app.Visible = true;            }

上面的运行后,DataGridView保存到Excel中的数据都是一致的,比如数值类型对应数值类型,文本类型对应文本类型。当然如果你想要保存的数据类型都是字符串或者文本,可以先通过一个二维的String数组将DataGridView的数据保存起来,然后再将数组赋值给Excel。代码改动如下:

        int iRows = 0;        int iCols = 0;        int iTrueCols = 0;        Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();        Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Add(System.Reflection.Missing.Value);        Microsoft.Office.Interop.Excel.Worksheet ws = null;        if (wb.Worksheets.Count > 0)        {            ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);        }        else        {            wb.Worksheets.Add(System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);            ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(1);        }        if (ws != null)        {            if (SheetName.Trim() != "")            {                ws.Name = SheetName;            }            iRows = datagridview.Rows.Count;      //加上列头行               iTrueCols = datagridview.Columns.Count;   //包含隐藏的列,一共有多少列               //求列数,省略Visible = false的列               for (int i = 0; i < datagridview.Columns.Count; i++)            {                if (datagridview.Columns[i].Visible) iCols++;            }            string[,] dimArray = new string[iRows + 1, iCols];            for (int j = 0, k = 0; j < iTrueCols; j++)            {                //省略Visible = false的列                   if (datagridview.Columns[j].Visible)                {                    dimArray[0, k] = datagridview.Columns[j].HeaderText;                    k++;                }            }            for (int i = 0; i < iRows; i++)            {                for (int j = 0, k = 0; j < iTrueCols; j++)                {                    //省略Visible = false的列                       if (datagridview.Columns[j].Visible)                    {                        dimArray[i + 1, k] = datagridview.Rows[i].Cells[j].Value.ToString();                        k++;                    }                }            }            ws.get_Range(ws.Cells[1, 1], ws.Cells[iRows + 1, iCols]).Value2 = dimArray;            ws.get_Range(ws.Cells[1, 1], ws.Cells[1, iCols]).Font.Bold = true;            ws.get_Range(ws.Cells[1, 1], ws.Cells[iRows + 1, iCols]).Font.Size = 10.0;            ws.get_Range(ws.Cells[1, 1], ws.Cells[iRows + 1, iCols]).RowHeight = 14.25;            //ws.Columns[.ColumnWidth = datagridview.Columns[0].Width;               for (int j = 0, k = 0; j < iTrueCols; j++)            {                //省略Visible = false的列                   if (datagridview.Columns[j].Visible)                {                    ws.get_Range(ws.Cells[1, k + 1], ws.Cells[1, k + 1]).ColumnWidth = (datagridview.Columns[j].Width / 8.4) > 255 ? 255 : (datagridview.Columns[j].Width / 8.4);                    //ws.Columns.c = datagridview.Columns[j].Width;                       k++;                }            }        }        app.Visible = true;