以上是方法的代码,就是将datagrilview中的数据导入到Excel中,网上找的导入方法,然后自己加的一个for循环判断,但是每次运行程序就造成电脑cpu占用大,所以请大牛帮我看看 这个for循环是不是死循环啊,或者有没有好的办法解决这个问题,求指教,在线等在线等

解决方案 »

  1.   

    你把这几行代码移到for循环外面试一下。
      

  2.   

    我试过了,放到for外面的话,第4步骤的关闭Excel对象操作只能执行一次,然后程序就停止了,然后显示对象未引用实例的错误,如果吧1和4步骤都放到for外面 cpu占用还是很高,
      

  3.   


    我试过了,放到for外面的话,第4步骤的关闭Excel对象操作只能执行一次,然后程序就停止了,然后显示对象未引用实例的错误,如果吧1和4步骤都放到for外面 cpu占用还是很高,
      

  4.   

    canstop那个阻塞的判断有给这个值改变过吗?是不是一直堆积在这里啊!
      

  5.   

    有个判断暂停的按钮控制着,这部代码调试的时候没有运行到这里,应该不是这的原因,应该是 这部分的原因,每次都是在这部分快速调试循环的时候,cpu就高了,如果一步步调试cpu也不会升高,实在不太清楚原因
      

  6.   


    我试过了,放到for外面的话,第4步骤的关闭Excel对象操作只能执行一次,然后程序就停止了,然后显示对象未引用实例的错误,如果吧1和4步骤都放到for外面 cpu占用还是很高,
    你的程序总共开了几个线程?
      

  7.   


    我试过了,放到for外面的话,第4步骤的关闭Excel对象操作只能执行一次,然后程序就停止了,然后显示对象未引用实例的错误,如果吧1和4步骤都放到for外面 cpu占用还是很高,
    你的程序总共开了几个线程?我就给这个方法开了一个现成,其他没有,我设置断点发现 就是这个for循环导致的cpu升高的,但是不知道该怎么解决
      

  8.   

    你用的这个组件,应该是个OLE类的组件,本来效率不高。我以前在做VBA开发的时候,在循环处理Excel表格的时候很慢,原因是循环赋值过程中,
    会刷新单元格,非常耗费资源,你加试试。类似如下:Sub compute_fill_all()
        Application.Calculation = xlCalculationManual
        Application.ScreenUpdating = False
        
        'Rev
        Call compute_fill_fm_data("", 0, 0)
        'Cost
        Call compute_fill_fm_data("(Comp.)Proj_Cost DIF", 60, 0)
        'Vat
        Call compute_fill_fm_data("", 111, 1)
        'Dept OverHead
        Call compute_fill_fm_data("(Comp.)Cost center DIF", 163, 0)
        
        Application.Calculation = xlCalculationAutomatic
        Application.ScreenUpdating = True
        
        MsgBox "Calculate Complete."
    End Sub执行前关闭UI刷新
    Application.ScreenUpdating = False
    执行完打开刷新
    Application.ScreenUpdating = True
      

  9.   

    按照你说的添加了一下,但是还是没有什么效果,现在的情况是数据导入到Excel表格的速度与电脑占用cpu成正比例,导出速度越快,CPU占用越高,比如可以在for循环里面加个sleep ,这样对cpu升高的减少有一些效果,但是导入数据的速度就大大降低了,唉,有点烦,
      

  10.   

    进入vs菜单  分析->性能探查器  勾选cpu使用率 然后开始     程序会启动,使用一段时间之后退出程序  然后vs会分析你程序运行期间代码对cpu的占用情况  你看看是哪些代码占用了很多cpu 然后针对性的改进
      

  11.   

    能运行就表示没有死循环之类的东西
    CPU 使用率高,表示程序运行很积极,基本没有停顿
    图中显示高使用率的是 Excel 而不是你的程序感觉你的观点很奇特,难道说:不能发挥出 CPU 优异性能的程序,才是好程序?
      

  12.   


    老哥,我知道是Excel占用cpu高,这个程序本身就是去操作Excel去填入数据,因为数据量比较大,程序一直在那循环几十万次,所以才会造成现在这个情况,我只是想 有没有办法优化一下,找有这方面经验的大牛给点建议,我自己已经不知道该怎么去改善了,才来咨询的,我没有恶意啊
      

  13.   

    这个方法我昨天试过了,我看了一下主要还是对于Excel的操作,每次操作都要加载模板打开Excel,然后写入数据,这样会造成大量的cpu占用,但是把这部分放到循环外面的话,最后对于每次操作Excel 的内存释放就只能全部数据导入结束才能释放,因为只实例化了一次如果释放了 程序就结束了,可是如果 操作Excel不释放的话,这样会造成占用更大的cpu,我已经有点绝望了,感觉除非换个方法了,目前这个方法已经找不到更好的改善办法了
      

  14.   

    编辑EXCEL的时候 一定要批量操作,千万不能一个一个格写,批量的API 查一下就好。
      

  15.   

    你手动“玩儿命地”连续打开几十个 excel 工作簿平且拼命点击工作簿玩儿命操作,平均1分钟内操作完别人需要一个月才能手动操作完的事情,看看电脑会不会卡?这是一个框架设计问题。纠结个别语句是永远也看不懂、无法设计清楚的。
      

  16.   

    读取一个公共模板之后的内部数据,未必要“挪到 for循环之外”,你完全可以把中间对象放到 cache 中。这样当存在中间对象时则直接使用,不存在的时候才需要读取一次公共 Excel 模板。但是整个框架,最糟糕的地方当然是你的 WaitOne 阻塞代码。有这类设计基本上就说明你是想不到“卡顿”的。真正的机制还是要看你自己的设计逻辑,比如说你想一批次并发处理几个表?或者是顺序定时处理表?等等。不会设计而滥用多(2个)线程这就会自己把自己阻塞住。
      

  17.   

    磁盘 I/O 操作本来就是阻塞的。如果你拼命进行磁盘 I/O,那么不要是进程被阻塞,整个 windows 系统肯定也被阻塞死掉。这是整个设计问题,必须从根本上去重新设计。比如说避免“导出”。
      

  18.   

    不要使用框架,就把这些数据使用HTML拼成一个字符串,把字符串导出到EXCEL文件,这样占的内存比较少。       /// <summary>
            /// 导出文件至CSV文件
            /// </summary>
            /// <param name="dt">数据表</param>
            /// <param name="strFileName">导出后的文件名,不要加后缀名</param>
            public void ExportDataGridToCSV(DataTable dt, string strFileName)
            {
                //string strFile = "";
                string path = HttpContext.Current.Server.MapPath("/Files/AutoCreate/Excel/");            //File info initialization
                if (!strFileName.EndsWith(".xls"))
                {
                    strFileName = strFileName + ".xls";
                }
                strFileName = path + "/" + strFileName;
                //path = HttpContext.Current.Server.MapPath(strFile);
                if (File.Exists(strFileName))
                {
                    File.Delete(strFileName);
                }
                StringBuilder sbHtml = new StringBuilder();
                sbHtml.Append("<table cellspacing='0' border='1' cellpadding='0'>");
                sbHtml.Append("<tr>");
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    sbHtml.Append("<td>\t");
                    sbHtml.Append(dt.Columns[i].ColumnName);
                    sbHtml.Append("</td>");
                }
                sbHtml.Append("</tr>");
                foreach (DataRow dr in dt.Rows)
                {
                    sbHtml.Append("<tr>");
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        sbHtml.Append("<td>\t");
                        sbHtml.Append(dr[i].ToString());
                        sbHtml.Append("</td>");
                    }
                    sbHtml.Append("</tr>");
                }
                sbHtml.Append("</table>");            System.IO.FileStream fs = new FileStream(strFileName, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                StreamWriter sw = new StreamWriter(fs, new System.Text.UnicodeEncoding());
                sw.Write(sbHtml.ToString());
                sw.Flush();
                sw.Close();
            }
      

  19.   

    这个批量操作是什么意思?比如我有30万条数据,每一条数据导入到一个Excel表格,所以要导入到30万个表格里面,批量操作的话,是不是比如每次以500个为一批的导入?还是怎样?这样的话也是在一直循环的就行导入直到30万条都倒入才算结束啊,,我还是不太理解,
      

  20.   

    首先感谢回复,还写了这么多,然后 我对html真的不是太懂,我还算是个新手  你写的这个方法是将所有数据导入到一个Excel表中了么? 我也看的不是太懂,我这个要做的是比如有30万条数据,每条数据导入一个表,所以要导入到30万个表中的,可能就像15楼的大佬说的,我要重新构思一下这个框架了
      

  21.   

    我大致看了一下逻辑: 将一个 Excel 拆分成 多个 Excel 问题来了:
    > 你为什么不 一次性把 源Excel 全部读完,然后释放掉 源文件。
    > 你为什么不把 源数据拆分好了之后,汇总成一个 List<DataTable> —— 然后再把 每个Table 写入 Excel ?
    > 为什么要 WaitOne()  —— 为什么要多线程? 你在内存中,得到 List<DataTable> 之后,再使用 多线程不行么?—— 一个函数只做一件事,你一个函数 做了好几件事: 读取源Excel,拆分源Excel,写入新Excel,协调资源
      

  22.   

    一个excel也能导致cpu占满,明显的死循环啊!
      

  23.   

    每一行都创建并导出一个XLS文件,CPU不高就没天理了
      

  24.   

    首先感谢回复,还写了这么多,然后 我对html真的不是太懂,我还算是个新手  你写的这个方法是将所有数据导入到一个Excel表中了么? 我也看的不是太懂,我这个要做的是比如有30万条数据,每条数据导入一个表,所以要导入到30万个表中的,可能就像15楼的大佬说的,我要重新构思一下这个框架了我写的就是一个被调函数,你用的是WINFORM,注意把这几行代码改一下,然后直接传入文件名、DataTable表调用就可以了       /// <summary>            string path = HttpContext.Current.Server.MapPath("/Files/AutoCreate/Excel/")//path可以写死一个路径
      生成后打开这个路径,看文件是不是生成到了这里,如果可以打开的话就成功了。这个速度很快,不会占太大资源的。
      

  25.   

    我原来也写过excel导出  确实是比较占cpu  我导出一个大约2W行的excel  导出当时cpu飙升85以上  好了就马上降下来了但是你这个阻塞用的......
      

  26.   

    你的数据源是windorm上的一个 datagrilview的控件吗? 
    1. 里面有30万条数据吗,用户在用这个Winform时候,载入这30万的数据时间也不少吧? 一般都会做分页去展现给使用者,这样用户体验更好。系统Loading轻。
    2. 你要把一个30万条的数据源,每一条存到一个Excel中,存成30万个Excel,这要用来干吗?背后是什么需求需要这样的?要生成30万个Excel文到硬盘上,那怎么做速度都会很慢的。如果是只生成一个Excel文件中,估计一分钟内就可以结束。
    3. 另外,给你一个NPOI 写Excel的方式,会比微软的这个COM元件效率快很多。public static bool DataSetToExcel(DataSet _ds, string _Path)
            {
                try
                {
                    #region NPOI 导出方式
                    HSSFWorkbook hw = new HSSFWorkbook();                #region styleH for 报表 Body 列名,正常字体,加粗,不加边框 左对齐
                    IFont fontH = hw.CreateFont();
                    fontH.Boldweight = (short)FontBoldWeight.BOLD;                ICellStyle styleH = hw.CreateCellStyle();
                    styleH.SetFont(fontH);
                    styleH.Alignment = HorizontalAlignment.CENTER;
                    styleH.VerticalAlignment = VerticalAlignment.CENTER;                #endregion                #region output every sheet                for (int t = 0; t < _ds.Tables.Count; t++)
                    {
                        HSSFSheet sheet2 = (HSSFSheet)hw.CreateSheet(_ds.Tables[t].TableName);                    HSSFRow rowCol2 = (HSSFRow)sheet2.CreateRow(0);
                        for (int j = 0; j < _ds.Tables[t].Columns.Count; j++)
                        {
                            HSSFCell cell = (HSSFCell)rowCol2.CreateCell(j);
                            //cell.SetCellValue("1000000000000000000000000000000000000000000");
                            cell.SetCellValue(_ds.Tables[t].Columns[j].ColumnName);
                            cell.CellStyle = styleH;
                        }                    for (int i = 0; i < _ds.Tables[t].Rows.Count; i++)
                        {
                            HSSFRow row = (HSSFRow)sheet2.CreateRow(i + 1);
                            for (int j = 0; j < _ds.Tables[t].Columns.Count; j++)
                            {
                                HSSFCell cell = (HSSFCell)row.CreateCell(j);
                                string _celldata = _ds.Tables[t].Rows[i][j].ToString();
                                cell.SetCellValue(_celldata);
                                if (_celldata.Trim().Contains("<br>")) //应用于Web
                                {
                                    cell.SetCellValue(_celldata.Trim().Replace("<br>", "\r\n"));
                                }
                                    cell.CellStyle.WrapText = true;                            cell.CellStyle.Alignment = HorizontalAlignment.CENTER;
                                cell.CellStyle.VerticalAlignment = VerticalAlignment.CENTER;
                            }
                            sheet2.AutoSizeColumn(i);//列宽自适应,对数字和英文有效,若列中存在中文或空格、*等特殊字符,自适应在当前列无效
                        }
                    }
                    #endregion                //hw.Write(System.IO.Stream(@"c:\poi0.xls"));
                    FileStream file = new FileStream(_Path, FileMode.Create);
                    hw.Write(file);
                    file.Close();                #endregion                //sw.WriteLine("生产的excel 建立完成,再次检查文件是否成功建立");
                    #region check if the excel file is created
                    if (!File.Exists(_Path))
                    {
                        //sw.WriteLine("生产的excel 未建立成功");
                        return false;
                    }
                    #endregion
                    return true;
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message, ex);
                }
            }需要引用4个文件:
    NPOI.dll  
    NPOI.OOXML.dll
    NPOI.OpenXml4Net.dll
    NPOI.OpenXmlFormats.dll
     
      

  27.   

    首先感谢回复,还写了这么多,然后 我对html真的不是太懂,我还算是个新手  你写的这个方法是将所有数据导入到一个Excel表中了么? 我也看的不是太懂,我这个要做的是比如有30万条数据,每条数据导入一个表,所以要导入到30万个表中的,可能就像15楼的大佬说的,我要重新构思一下这个框架了我写的就是一个被调函数,你用的是WINFORM,注意把这几行代码改一下,然后直接传入文件名、DataTable表调用就可以了       /// <summary>            string path = HttpContext.Current.Server.MapPath("/Files/AutoCreate/Excel/")//path可以写死一个路径
      生成后打开这个路径,看文件是不是生成到了这里,如果可以打开的话就成功了。这个速度很快,不会占太大资源的。
    还是感谢回复,我又试了一下这个方法,导出几百行数据可以,,当导出7万行数据时,显示成功了,但是导出的Excel表格打不开,显示Excel程序未响应而且我看了一下,这个不是我想要的结果,这是把DataTable里面的数据导入到一个Excel里面了,我之前试过这样的其他的方法,导出到一个表格比较简单的,我现在要实现的是每一条数据导出一个表格,有多少条数据,就导出到多少表格中 
      

  28.   


    这个阻塞可有可无的,去掉也没事,那老哥之前做的占用cpu的方法解决了没有,用的什么方法请指教一二
      

  29.   

    excel导出,如果没有样式等复杂的要求,可以使用OLEDB方式,再System.Data.Oledb中。