简体   繁体   中英

C# - How can I export a list to a spreadsheet faster?

I have a program that calls the following method below, which simply exports a list to an Excel spreadsheet. The majority of the program's runtime is spent executing this method once. In my last run, this method took 5 minutes and 50 seconds to execute, on a list of size ~46,000. Can you give any suggestions on how I can improve my code to make this method run faster? I don't feel that this should take roughly 6 minutes to execute...but the only thing that sticks out to me is that there may be a more efficient way to export a list to a spreadsheet column, without iterating through rows using the dummy integer variable "i", and copying one string at a time to the column.

       public static string ExportListToSpreadsheet(string xlwbk, string xlwksht, List<string> tagnamelist)
    {
        var watch = new Stopwatch();
        watch.Start();
        object misValue = Refl.Missing.Value;
        Excel.Application xlApp = new Excel.Application();
        Excel.Workbook xlWorkbook;
        xlWorkbook = xlApp.Workbooks.Add(misValue);

        Excel.Worksheet xlsheet = xlWorkbook.Sheets.Add();
        xlsheet.Name = xlwksht;
        int i = 1;

        foreach(string tagname in tagnamelist)
        {
                xlsheet.Cells[i,1].Value = tagname;
                i += 1;
        }

        string filename = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\" + xlwbk;
        xlWorkbook.SaveAs(filename, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, misValue,
        misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, misValue, misValue, misValue, misValue, misValue);
        xlWorkbook.Close();
        watch.Stop();
        return watch.Elapsed.ToString();

    }

Thanks for your help.

Give the ClosedXML library a try. I've put DataTables that have tens of thousands of rows into a spreadsheet and it takes like 10 seconds.

For a list you just simply do this:

using ClosedXML.Excel;
..
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("myData");
ws.Cell(1, 1).InsertData(tagnamelist);
wb.SaveAs(@"c:\..\tagnamelist.xlsx");

Not an answer specific to C#, but to any scripting/automation: writing the Excel cells one at a time is terribly inefficient, instead define a Range and set the data all in one hit. Define a 2D array of variants that matches the layout of the data you want, then reference a Range object of the same size in Excel, and set the data.

I put the VBA example as it is easy to test, and I am not familiar with how C# creates arrays (maybe a 2D array of objects). In VBA the ".Value" on the Range is redundant, but might be needed in C#.

Sub WriteBigData()
    Dim vData() As Variant

    Dim lValues As Long
    lValues = 10000

    'Create a 2D array matching the size of your data
    ReDim vData(1 To lValues, 1 To 1) As Variant
    
    'Fill this temporary array with your data 
    'Just simple numbers in this example
    For n = 1 To lValues
        vData(n, 1) = n
    Next n

    Dim rng As Range
    Set rng = Range("A1").Resize(lValues, 1)

    'This sets all the values of the range in one hit
    'with no costly iteration
    rng.Value = vData
End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM