这样的代码,单纯看注释,就会烦死人!!!!!
- #region 导出EXCEL方法二
- ///
- /// 此方法关键之处是使用Range一次存储内存中的多行多列数据到Excel
- /// 此方法效率明显高的多,推荐使用
- /// 此方法个人觉得很精彩,大家在看代码的时候可以使用设置断点来看每个变量值的变化
- ///
- ///
- ///
- public void SaveToExcel(DataGridView gridView, SaveFileDialog saveFileDialog)
- {
- /* 文件保存对话框 */
- saveFileDialog.Filter = InfoListUs[36]; // "Execl files (*.xls)|*.xls";
- saveFileDialog.FilterIndex = 0;
- saveFileDialog.CreatePrompt = true;
- saveFileDialog.Title = InfoListUs[37]; // "导出文件保存路径";
- saveFileDialog1.RestoreDirectory = true; //控制对话框在关闭之前是否恢复当前目录
- if (saveFileDialog.ShowDialog() == DialogResult.OK)
- {
- string strName = saveFileDialog.FileName; //从对话框中取得文件名
- /* 文件名不能为空 */
- if (strName.Length != 0)
- {
- System.Reflection.Missing miss = System.Reflection.Missing.Value; //这是什么玩意的?
- /* 创建EXCEL对象: appExcel,Workbook,Worksheet,Range */
- Microsoft.Office.Interop.Excel.Application appExcel;
- appExcel = new Microsoft.Office.Interop.Excel.Application();
- Microsoft.Office.Interop.Excel.Workbook workbookData;
- Microsoft.Office.Interop.Excel.Worksheet worksheetData;
- Microsoft.Office.Interop.Excel.Range rangedata;
- appExcel.Visible = false; //设置对象不可见
- // Microsoft.Office.Interop.Excel.Range Range = (Microsoft.Office.Interop.Excel.Range)NewExcel.get_Range("A1", "H2");//获取多个单元格区域
- /*
- * 在调用Excel应用程序,或创建Excel工作簿之前,记着加上下面的两行代码。
- * 因为Excel有一个Bug,如果你的操作系统的环境不是英文的,而Excel就会在执行下面的代码时,报异常。
- */
- System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
- System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
- workbookData = appExcel.Workbooks.Add(miss);
- worksheetData = (Microsoft.Office.Interop.Excel.Worksheet)workbookData.Worksheets.Add(miss, miss, miss, miss);
- worksheetData.Name = "saved"; //给工作表赋名称
- // 清零计数器并开始计数
- TimeP = new System.DateTime(0);
- timer1.Start();
- /*
- * 保存到WorkSheet的表头,你应该看到,是一个Cell一个Cell的存储,
- * 这样效率特别低,解决的办法是,使用Rang,一块一块地存储到Excel
- */
- int ColumnCellIndex = 0;
- for (int i = 0; i gridView.ColumnCount; i++)
- {
- if ((i== 4) || (i == 8) || (i == 10) || (i == 11))
- continue;
- worksheetData.Cells[1, ColumnCellIndex + 1] = gridView.Columns[i].HeaderText.ToString();
- ColumnCellIndex++;
- }
- //
- // 先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围;也可以给例如A1到H10这样的范围
- // 因为第一行已经写了表头,所以所有数据都应该从A2开始
- //
- rangedata = worksheetData.get_Range("A2", miss);
- Microsoft.Office.Interop.Excel.Range xlRang = null;
- int iRowCount = gridView.RowCount; //iRowCount为实际行数,最大行
- int iParstedRow = 0, iCurrSize = 0;
- //
- // iEachSize为每次写行的数值,可以自己设置,
- // 每次写1000行和每次写2000行大家可以自己测试下效率
- //
- int iEachSize = 1000;
- int iColumnAccount = gridView.ColumnCount; //iColumnAccount为实际列数,最大列数
- //
- // 在内存中声明一个iEachSize×iColumnAccount的数组,
- // iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
- //
- object[,] objVal = new object[iEachSize, iColumnAccount];
- try
- {
- //
- // 给进度条赋最大值为实际行数最大值
- // progressBar1.Maximum = gridView.RowCount;
- //
- iCurrSize = iEachSize;
- int ColumnCellIndex_1 = 0;
- while (iParstedRow iRowCount)
- {
- if ((iRowCount - iParstedRow) iEachSize)
- iCurrSize = iRowCount - iParstedRow;
- for (int i = 0; i iCurrSize; i++)
- {
- ColumnCellIndex_1 = 0;
- for (int j = 0; j iColumnAccount; j++)
- {
- /* 下面四个行的数据不需要导出 */
- if ((j == 4) || (j == 8) || (j == 10) || (j == 11))
- continue;
- objVal[i, ColumnCellIndex_1] = gridView[j, i + iParstedRow].Value.ToString();
- ColumnCellIndex_1++;
- }
- System.Windows.Forms.Application.DoEvents();
- }
- /*
- * 建议使用设置断点研究下哈
- * 例如A1到H10的意思是从A到H,第一行到第十行
- * 下句很关键,要保证获取orkSheet中对应的Range范围
- * 下句实际上是得到这样的一个代码语句 xlRang = worksheetData.get_Range("A2","H100");
- * 注意看实现的过程
- * 'A' + iColumnAccount - 1这儿是获取你的最后列,A的数字码为65,大家可以仔细看下是不是得到最后列的字母
- * iParstedRow + iCurrSize + 1获取最后行
- * 若WHILE第一次循环的话这应该是A2,最后列字母+最后行数字
- * iParstedRow + 2要注意,每次循环这个值不一样,他取决于你每次循环RANGE取了多大,也就是iEachSize设置值的大小
- */
- xlRang = worksheetData.get_Range("A" + ((int)(iParstedRow + 2)).ToString(), ((char)('A' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());
- xlRang.Value2 = objVal; // 调用Range的Value2属性,把内存中的值赋给Excel
- iParstedRow = iParstedRow + iCurrSize;
- }
- /* 设置A1-H1行头字体的大小 */
- rangedata = (Microsoft.Office.Interop.Excel.Range)appExcel.get_Range("A1", "H1");
- rangedata.Font.Size = 20;
- rangedata.Font.Bold = true;
- /* 保存工作表 */
- worksheetData.SaveAs(strName, miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
- System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
- xlRang = null;
- this.KillSpecialExcel(appExcel);
- timer1.Stop();
- /* 数据已经成功导出到 */
- MessageBox.Show(MessListUs[18] + saveFileDialog.FileName.ToString(), MessListUs[19], MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- catch (Exception ex)
- {
- timer1.Stop();
- return;
- }
- /* 别忘了在结束程序之前恢复环境! */
- System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
- }
- }
- }