现在的位置: 首页 > 综合 > 正文

DevX 导出Excel

2017年11月06日 ⁄ 综合 ⁄ 共 7807字 ⁄ 字号 评论关闭

       ///////////////////////////////////////////////////////////////
        #region 导出EXCEL方法二
        
        /// <summary>
        /// 此方法关键之处是使用Range一次存储内存中的多行多列数据到Excel
        /// 此方法效率明显高的多,推荐使用
        /// 此方法个人觉得很精彩,大家在看代码的时候可以使用设置断点来看每个变量值的变化
        /// </summary>
        /// <param name="gridView"></param>
        /// <param name="saveFileDialog"></param>
        public void ToExcel2(DevExpress.XtraGrid.Views.Grid.GridView gridView, SaveFileDialog saveFileDialog)
        {           
            saveFileDialog.Filter = "Execl files (*.xls)|*.xls";
            saveFileDialog.FilterIndex = 0;
            saveFileDialog.RestoreDirectory = true;
            saveFileDialog.CreatePrompt = true;
            saveFileDialog.Title = "导出文件保存路径";
            saveFileDialog.FileName = "方案文件";
            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;
                    /* 在调用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";
               
                    // 保存到WorkSheet的表头,你应该看到,是一个Cell一个Cell的存储,这样效率特别低,解决的办法是,使用Rang,一块一块地存储到Excel
                    for (int i = 0; i < gridView.Columns .Count; i++)
                    {
                        worksheetData.Cells[1, i + 1] = gridView.Columns[i].Caption.ToString();//HeaderText                     
                    }
                    //先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围,也可以给例如A1到H10这样的范围
                    //因为第一行已经写了表头,所以所有数据都应该从A2开始
                    rangedata = worksheetData.get_Range("A2", miss);

                    Microsoft.Office.Interop.Excel.Range xlRang = null;
                    //iRowCount为实际行数,最大行
                    int iRowCount = gridView.RowCount;
                    int iParstedRow = 0, iCurrSize = 0;
                    //iEachSize为每次写行的数值,可以自己设置,每次写1000行和每次写2000行大家可以自己测试下效率
                    int iEachSize = 100;
                    //iColumnAccount为实际列数,最大列数
                    int iColumnAccount = gridView.Columns.Count;//ColumnCount
                    //在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
                    object[,] objVal = new object[iEachSize, iColumnAccount];

                    int rowIndex = 1;
                    int colIndex = 0;
                    int colNum = gridView.Columns.Count;

                    try
                    {
                        //给进度条赋最大值为实际行数最大值
                        //progressBar1.Maximum = gridView.RowCount;
                        iCurrSize = iEachSize;
                        while (iParstedRow < iRowCount)
                        {
                            if ((iRowCount - iParstedRow) < iEachSize)
                               iCurrSize = iRowCount - iParstedRow;
                            //for (int i = 0; i < iCurrSize; i++)
                            //{
                            //    for (int j = 0; j < iColumnAccount; j++)
                            //    {
                            //       // objVal[i, j] = gridView[j, i + iParstedRow].Value.ToString();
                            //        objVal[i, j] = gridView.GetGroupRowValue(i, gridView.Columns[j]);
                            //    }
                            //   // progressBar1.Value++;
                            //    System.Windows.Forms.Application.DoEvents();
                            //}

                            for (int i = 0; i < gridView.RowCount; i++)
                            {
                                rowIndex++;
                                colIndex = 0;
                                for (int j = 0; j < gridView.Columns.Count; j++)
                                {
                                    colIndex++;
                                    objVal[i, j] = gridView.GetRowCellValue(i, gridView.Columns[j]);

                                }
                                System.Windows.Forms.Application.DoEvents();
                            }

 

                            /*
                             * 建议使用设置断点研究下哈
                             * 例如A1到H10的意思是从A到H,第一行到第十行
                             * 下句很关键,要保证获取workSheet中对应的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());
                            // 调用Range的Value2属性,把内存中的值赋给Excel
                            xlRang.Value2 = objVal;
                            iParstedRow = iParstedRow + iCurrSize;
                        }
                        //保存工作表
                        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;
                       // progressBar1.Value = 0;
                        //调用方法关闭EXCEL进程,大家可以试下不用的话如果程序不关闭在进程里一直会有EXCEL.EXE这个进程并锁定你的EXCEL表格
                        this.KillSpecialExcel(appExcel);
                        //timer1.Stop();
                        MessageBox.Show("数据已经成功导出到:" + saveFileDialog.FileName.ToString(), "导出完成", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                       // timer1.Stop();
                        return;
                    }
                    // 别忘了在结束程序之前恢复你的环境!
                    System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
                }
            }
        }
        #endregion

        #region 结束EXCEL.EXE进程的方法
        /// <summary>
        /// 结束EXCEL.EXE进程的方法
        /// </summary>
        /// <param name="m_objExcel">EXCEL对象</param>
        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        public void KillSpecialExcel(Microsoft.Office.Interop.Excel.Application m_objExcel)
        {
            try
            {
                if (m_objExcel != null)
                {
                    int lpdwProcessId;
                    GetWindowThreadProcessId(new IntPtr(m_objExcel.Hwnd), out lpdwProcessId);

                    System.Diagnostics.Process.GetProcessById(lpdwProcessId).Kill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

抱歉!评论已关闭.