XLS电子表格C#

时间:2016-04-13 18:56:43

标签: c# database xls data-conversion

我试图抓取XLS电子表格中的单元格,将它们分配给字符串数组,然后操纵数据并导出到多个CVS文件。

问题是XLS电子表格包含不相关的信息,可用数据直到第17行才开始,而列没有标题只有默认的Sheet1。

我已经查看了相关问题并尝试自己搞清楚但没有成功。下面的代码来读取XLS有点可行,但是由于行长度从一个XLS文件到另一个XLS文件不同而且处理空行和空行,所以它很麻烦。

CODE

public static void xlsReader()
        {
            string fileName = string.Format("{0}\\LoadsAvailable.xls", Directory.GetCurrentDirectory());
            string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";" + @"Extended Properties='Excel 8.0;HDR=Yes;'";
            string queryString = "SELECT * FROM [Sheet1$]";


            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                OleDbCommand command = new OleDbCommand(queryString, connection);
                connection.Open();
                OleDbDataReader reader = command.ExecuteReader();

                int counter = 0;
                while (reader.Read())
                {
                    Console.WriteLine("Line " + counter + ":" + reader[28].ToString()); // Just for testing
                    counter++;
                }
            }

        }

我可以通过循环来做一堆技巧来获取所需的数据但是必须有一个查询字符串,它可以从第17行获得只有8列的数据(不是26列,18列为空)?

我尝试了很多查询字符串示例,并且无法通过缝合来使用起始行索引或过滤掉空数据。

1 个答案:

答案 0 :(得分:0)

这是一个方便的方法,可以将excel文件转换为平面文件。

您可能希望更改连接字符串属性以满足您的需要。我的案子需要标题。

请注意,您需要在计算机上安装Access数据库引擎。我需要32位版本,因为我的开发应用程序是32位。我打赌你也需要它。

我参数化了平面文件的分隔符,因为我遇到的情况是我不需要逗号而是管道符号。

如何调用方法ex:ConvertExcelToFlatFile(openFileName, savePath, '|'); // pipe delimited

// Converts Excel To Flat file
    private void ConvertExcelToFlatFile(string excelFilePath, string csvOutputFile, char delimeter, int worksheetNumber = 1)
    {

        if (!File.Exists(excelFilePath)) throw new FileNotFoundException(excelFilePath);
        if (File.Exists(csvOutputFile)) throw new ArgumentException("File exists: " + csvOutputFile);

        // connection string
        var cnnStr = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml; IMEX=1; HDR=NO\"", excelFilePath);
        var cnn = new OleDbConnection(cnnStr);

        // get schema, then data
        var dt = new DataTable();
        try
        {
            cnn.Open();
            var schemaTable = cnn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

            if (schemaTable.Rows.Count < worksheetNumber) throw new ArgumentException("The worksheet number provided cannot be found in the spreadsheet");
            string worksheet = schemaTable.Rows[worksheetNumber - 1]["table_name"].ToString().Replace("'", "");
            string sql = String.Format("select * from [{0}]", worksheet);

            var da = new OleDbDataAdapter(sql, cnn);
            da.Fill(dt);
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            // free resources
            cnn.Close();
        }

        // write out CSV data
        using (var wtr = new StreamWriter(csvOutputFile)) // disposes file handle when done
        {

            foreach (DataRow row in dt.Rows)
            {
                //MessageBox.Show(row.ItemArray.ToString());
                bool firstLine = true;
                foreach (DataColumn col in dt.Columns)
                {
                    // skip the first line the initial 
                    if (!firstLine)
                    {
                        wtr.Write(delimeter);
                    }
                    else
                    {
                        firstLine = false;
                    }

                    var data = row[col.ColumnName].ToString();//.Replace("\"", "\"\""); // replace " with ""
                    wtr.Write(String.Format("{0}", data));
                }
                wtr.WriteLine();
            }
        }


    }