如何在不使用逐行访问的情况下从数据表中编写Excel

时间:2011-08-26 18:47:48

标签: .net asp.net excel

我试图通过逐行循环数据表来使用数据表数据填充Excel。

在这个过程中,需要更多时间才能完成20-30万条记录(15分钟)

有没有其他方法可以写入Excel而不逐行循环更快?

我没有使用sqlserver,只是将带有20K记录的xml填充到数据集并填充excel。

我在google中找到了以下代码,但这在.net中不起作用。(表示没有定义ExcelFile)

    Dim ef2 As New ExcelFile

    ' Imports all the tables from DataSet to new file.
    For Each table In ds.Tables
        ' Add new worksheet to the file.
        Dim ws As ExcelWorksheet = ef2.Worksheets.Add(table.TableName)

        ' Change the value of the first cell in the DataTable.
        table.Rows(0)(0) = "This is new file!"

        ' Insert the data from DataTable to the worksheet starting at cell "A1".
        ws.InsertDataTable(table, "A1", True)
    Next

    ' Save the file to XLS format.
    ef2.SaveXls("DataSet.xls")

2 个答案:

答案 0 :(得分:0)

为什么不从创建多个线程开始。每个线程将同时读取1000条记录(逐个)并将它们写入各自的临时文件或Stream Writer。最后,合并结果。

希望有所帮助。

答案 1 :(得分:0)

看看这篇文章,它解释了如何使用OpenXML SDK将DataTable导出到Excel。

http://lateral8.com/articles/2010/3/5/openxml-sdk-20-export-a-datatable-to-excel.aspx

以下是文章的主要内容:

创建ExcelExport类

现在在项目中创建一个名为ExcelExport.cs的新类文件。将以下引用添加到文件的开头:

使用System; 使用System.Data; 使用System.Linq; 使用DocumentFormat.OpenXml.Packaging; 使用DocumentFormat.OpenXml.Spreadsheet;

接下来,将以下方法添加到文件中:

public void ExportDataTable(DataTable table, string exportFile)
{
    //create the empty spreadsheet template and save the file 
    //using the class generated by the Productivity tool  ExcelDocument excelDocument = new ExcelDocument();
    excelDocument.CreatePackage(exportFile);

    //populate the data into the spreadsheet  using (SpreadsheetDocument spreadsheet =
    SpreadsheetDocument.Open(exportFile, true))
    {
        WorkbookPart workbook = spreadsheet.WorkbookPart;
        //create a reference to Sheet1  WorksheetPart worksheet = workbook.WorksheetParts.Last();
        SheetData data = worksheet.Worksheet.GetFirstChild<SheetData>();

        //add column names to the first row  Row header = new Row();
        header.RowIndex = (UInt32)1;

        foreach (DataColumn column in table.Columns)
        {
            Cell headerCell = createTextCell(table.Columns.IndexOf(column) + 1, 1, column.ColumnName);
            header.AppendChild(headerCell); 
        }

        data.AppendChild(header);

        //loop through each data row  DataRow contentRow;
        for (int i = 0;i < table.Rows.Count; i++)
        {
            contentRow = table.Rows[i];
            data.AppendChild(createContentRow(contentRow, i + 2));
        }
    }            
}

上面的方法首先使用之前创建的ExcelDocument类创建一个新文件,该文件保存到exportFile参数中指定的位置。创建文件后,会出现两个主循环。第一个循环遍历DataTable对象的列,并使用createTextCell方法为每个列名创建一个Cell对象:

private Cell createTextCell(int columnIndex, int rowIndex, object cellValue)
{
    Cell cell = new Cell();

    cell.DataType = CellValues.InlineString;
    cell.CellReference = getColumnName(columnIndex) + rowIndex;

    InlineString inlineString = new InlineString();
    Text t = new Text();

    t.Text = cellValue.ToString();
    inlineString.AppendChild(t);
    cell.AppendChild(inlineString);

    return cell;

}

接下来,使用createContentRow方法将每一行附加到工作表:

private Row createContentRow(DataRow dataRow, int rowIndex)
{
    Row row = new Row  {RowIndex = (UInt32)rowIndex }; 

    for (int i = 0; i < dataRow.Table.Columns.Count; i++)
    {
        Cell dataCell = createTextCell(i + 1, rowIndex, dataRow[i]);
        row.AppendChild(dataCell);
    }
    return row;
}

createTextCell方法使用一个额外的支持方法来完成将行和列映射到正确的单元格引用的工作,方法getColumnName:

private string getColumnName(int columnIndex)
{
    int dividend = columnIndex;
    string columnName = String.Empty;
    int modifier;

    while (dividend > 0)
    {
        modifier = (dividend - 1) % 26;
        columnName = 
            Convert.ToChar(65 + modifier).ToString() + columnName;
        dividend = (int)((dividend - modifier) / 26);
    }

    return columnName;
}

此方法提供了一种快速简便的方法,可将列索引号映射到Excel列名(A-Z)。 OpenXML SDK中的Cell对象需要指定有效的Excel单元格引用(例如A1,C2),因此此方法与行索引引用组合以创建单元格引用。值得注意的是,此处的索引不是从零开始的。

最后,要实现上面的类,请使用以下代码:

//create DataTable from sample data DataSet sampleDataSet = new DataSet();
sampleDataSet.ReadXml(context.Server.MapPath("~/sampleData.xml"));
DataTable productsTable = sampleDataSet.Tables[0];
string exportFile = context.Server.MapPath("~/excelExport.xslx");

ExcelExport export = new ExcelExport();
export.ExportDataTable(productsTable, exportFile);