如何使用Microsoft.Office.Interop.Excel从Excel导入DataSet?

Jus*_*gan 24 c# excel interop dataset excel-interop

我想做的事

我正在尝试使用Microsoft.Office.Interop.Excel命名空间打开Excel文件(XSL或CSV,但遗憾的是不是 XSLX)并将其导入DataSet.我无法控制工作表或列名,因此我需要允许对它们进行更改.

我试过的

我以前尝试过这种OLEDB方法,并且遇到了很多问题(错误,速度慢,并且需要事先了解Excel文件的架构),所以我想避免再次这样做.我想要做的是使用Microsoft.Office.Interop.Excel将工作簿直接导入DataSet,或者循环遍历工作表并将每个工作表加载到DataTable中.

信不信由你,我很难找到资源.在StackOverflow上进行的一些搜索发现大多数人都试图进行反向(DataSet => Excel)或OLEDB技术.谷歌没有多大帮助.

到目前为止我得到了什么

    public void Load(string filename, Excel.XlFileFormat format = Excel.XlFileFormat.xlCSV)
    {
        app = new Excel.Application();
        book = app.Workbooks.Open(Filename: filename, Format: format);

        DataSet ds = new DataSet();

        foreach (Excel.Worksheet sheet in book.Sheets)
        {
            DataTable dt = new DataTable(sheet.Name);
            ds.Tables.Add(dt);

            //??? Fill dt from sheet 
        }

        this.Data = ds;
    }
Run Code Online (Sandbox Code Playgroud)

我可以一次导入整本书,或者一次循环一张.我可以使用Interop.Excel执行此操作吗?

reg*_*gie 36

那么在Excelplex上使用Excel Data Reader(此前托管)是一个开源项目呢?它的工作非常适合我从Excel工作表导出数据.

指定链接上给出的示例代码:

FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);

//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();

//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}

//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Run Code Online (Sandbox Code Playgroud)

UPDATE

经过一番搜索,我发现了这篇文章:使用Office Interop Assemblies快速阅读MS Excel.本文仅用于Office Interop Assemblies从给定的Excel工作表中读取数据.该项目的源代码也在那里.我想这篇文章可以作为你想要实现的目标的起点.看看是否有帮助

更新2

下面的代码获取excel workbook并读取所有找到的值,对于每个excel worksheet内部excel workbook.

private static void TestExcel()
    {
        ApplicationClass app = new ApplicationClass();
        Workbook book = null;
        Range range = null;

        try
        {
            app.Visible = false;
            app.ScreenUpdating = false;
            app.DisplayAlerts = false;

            string execPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);

            book = app.Workbooks.Open(@"C:\data.xls", Missing.Value, Missing.Value, Missing.Value
                                              , Missing.Value, Missing.Value, Missing.Value, Missing.Value
                                             , Missing.Value, Missing.Value, Missing.Value, Missing.Value
                                            , Missing.Value, Missing.Value, Missing.Value);
            foreach (Worksheet sheet in book.Worksheets)
            {

                Console.WriteLine(@"Values for Sheet "+sheet.Index);

                // get a range to work with
                range = sheet.get_Range("A1", Missing.Value);
                // get the end of values to the right (will stop at the first empty cell)
                range = range.get_End(XlDirection.xlToRight);
                // get the end of values toward the bottom, looking in the last column (will stop at first empty cell)
                range = range.get_End(XlDirection.xlDown);

                // get the address of the bottom, right cell
                string downAddress = range.get_Address(
                    false, false, XlReferenceStyle.xlA1,
                    Type.Missing, Type.Missing);

                // Get the range, then values from a1
                range = sheet.get_Range("A1", downAddress);
                object[,] values = (object[,]) range.Value2;

                // View the values
                Console.Write("\t");
                Console.WriteLine();
                for (int i = 1; i <= values.GetLength(0); i++)
                {
                    for (int j = 1; j <= values.GetLength(1); j++)
                    {
                        Console.Write("{0}\t", values[i, j]);
                    }
                    Console.WriteLine();
                }
            }

        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        finally
        {
            range = null;
            if (book != null)
                book.Close(false, Missing.Value, Missing.Value);
            book = null;
            if (app != null)
                app.Quit();
            app = null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,values[i, j]是您需要添加到的值dataset.i表示行,而j表示列.


Jul*_*usz 7

你看过这个吗?来自http://www.aspspider.com/resources/Resource510.aspx:

public DataTable Import(String path)
{
    Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
    Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks.Open(path, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);

    Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.ActiveSheet;

    int index = 0;
    object rowIndex = 2;

    DataTable dt = new DataTable();
    dt.Columns.Add("FirstName");
    dt.Columns.Add("LastName");
    dt.Columns.Add("Mobile");
    dt.Columns.Add("Landline");
    dt.Columns.Add("Email");
    dt.Columns.Add("ID");

    DataRow row;

    while (((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2 != null)
    {

        row = dt.NewRow();
        row[0] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 1]).Value2);
        row[1] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 2]).Value2);
        row[2] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 3]).Value2);
        row[3] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 4]).Value2);
        row[4] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)workSheet.Cells[rowIndex, 5]).Value2);
        index++;

        rowIndex = 2 + index;
        dt.Rows.Add(row);
    }
    app.Workbooks.Close();
    return dt;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

object[,] valueArray = (object[,])excelRange.get_Value(XlRangeValueDataType.xlRangeValueDefault);

//Get the column names
for (int k = 0; k < valueArray.GetLength(1); )
{
    //add columns to the data table.
    dt.Columns.Add((string)valueArray[1,++k]);
}

//Load data into data table
object[] singleDValue = new object[valueArray.GetLength(1)];
//value array first row contains column names. so loop starts from 1 instead of 0
for (int i = 1; i < valueArray.GetLength(0); i++)
{
    Console.WriteLine(valueArray.GetLength(0) + ":" + valueArray.GetLength(1));
    for (int k = 0; k < valueArray.GetLength(1); )
    {
        singleDValue[k] = valueArray[i+1, ++k];
    }
    dt.LoadDataRow(singleDValue, System.Data.LoadOption.PreserveChanges);
}
Run Code Online (Sandbox Code Playgroud)