zoukankan      html  css  js  c++  java
  • 快速保存ListView内存中大量数据到Excel(转)

    Fast Save data from ListView to Excel WorkSheet
    remex1980 原创于 2007-5-19 19:59:27
    原作者: remex1980

    存储到Excel的结果 

    简介

    本文描述如何快速保存ListView内存中大量数据到Excel的WorkSheet。关键之处是使用Range一次存储多行多列数据。

    实施


    如果需要将内存中的数据存储到Excel文件中,首先,引用Excel的Com组件。如下图:
    引用Excel的Com组件 


    然后创建Excel应用程序对象appExcel,以及其它的工作簿等。

                Microsoft.Office.Interop.Excel.Application appExcel;

    appExcel = new Microsoft.Office.Interop.Excel.Application();
    Workbook workbookData;
    Worksheet worksheetData;

    在调用Excel应用程序,或创建Excel工作簿之前,记着加上下面的这段代码:

                System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
    System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");


    这是因为Excel有一个Bug,如果你的操作系统的环境不是英文的,而,Excel是那么就会在下面的代码时,报异常。
    详细请参考:Excel环境异常解决 http://www.msproject.cn/QA/qa_excel_old_format.aspx

    接下来就是该创建工作簿,创建一个WorkSheet了。

                workbookData = appExcel.Workbooks.Add(Missing.Value);
    worksheetData = (Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
    worksheetData.Name = "Saved";


    存储ListView中的列到WorkSheet的表头:

               
    // Save columns name
    for (int i = 0; i < listViewData.Columns.Count; i++)
    {
    worksheetData.Cells[1, i+1] = listViewData.Columns[i].Text;
    }


    快速存储ListView中的大量数据

    上面存储列名时候,你应该看到,是一个Cell一个Cell的存储,这样效率特别低,解决的办法是,使用Rang,一块一块地存储到Excel。

                Range rangedata;


    rangedata = worksheetData.get_Range("A2", Missing.Value);

    Range xlRang = null;
    int iRowCount = listViewData.Items.Count;
    int iParstedRow = 0, iCurrSize = 0;
    int iEachSize = 1000; // each time you
    int iColumnAccount = listViewData.Columns.Count;
    object[,] objVal = new object[iEachSize, iColumnAccount];
    try
    {
    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] = listViewData.Items[i + iParstedRow].SubItems[j].Text;
    }
    // Get Save Range from Excel WorkSheet
    // such as A1 H10, means From A to H Columns, and 1 to 10 rows
    xlRang = worksheetData.get_Range("A" + ((int)(iParstedRow + 2)).ToString(), ((char)('A' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());

    xlRang.Value2 = objVal;

    iParstedRow = iParstedRow + iCurrSize;
    }

    // change number format of the data column

    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
    xlRang = null;

    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    return ;
    }


    上面的代码,先在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数。然后将ListView中顺序取最大行数的数据,存储到这个矩阵中。
    接着,在Excel的WorkSheet中,获取对应的Range。需要注意的是,在Excel中,行的索引是从1开始(不像C#,C++中的数组是从0开始的),列的索引是从A开始的,如果有三列,那么就是从A-C。

    调用Range的Value2属性,把内存中的值赋给Excel就可以了。

    这样的效率将远远高于一个一个单元存储。

    提示

    别忘了在结束程序之前恢复你的环境!

                System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;


    程序界面:
    主界面 

  • 相关阅读:
    vue脚手架搭建项目步骤(转载)
    使用css样式设置按钮禁用
    如何设置页面文本不可复制?
    System.IO.IOException:需要的特权不被客户端持有。
    vs中 git fetch与git pull的区别
    如何获取按钮开关选中的状态?
    Uncaught TypeError: XXX is not a function...
    解决bootstrap缩小布局会乱的问题,缩小一定程度后出现横向滚动条
    日期(年月日)与时间戳互转换
    Java中的Finally
  • 原文地址:https://www.cnblogs.com/adaiye/p/listViewToexcel.html
Copyright © 2011-2022 走看看