【问题标题】:Query string selections for XLS spreadsheet C#XLS 电子表格 C# 的查询字符串选择
【发布时间】:2017-08-16 09:51:57
【问题描述】:

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

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

我查看了相关问题并尝试自己解决,但没有成功。以下用于读取 XLS 的代码有点工作,但使用起来很麻烦,因为行长度因一个 XLS 文件而异,并且它会自动拉出空列和行。

代码

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 列为空)?

我已经尝试了许多查询字符串示例,但无法缝合以使用起始行索引或过滤掉空数据。

【问题讨论】:

    标签: c# database xls data-conversion


    【解决方案1】:

    这是一种将excel文件转换为平面文件的便捷方法。

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

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

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

    如何调用方法例如: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();
                }
            }
    
    
        }
    

    【讨论】:

    • 试过了,效果很好!我更改了连接字符串和分隔符并产生了结果。猜猜没有办法绕过清除空白和数百个空单元格的分隔符的诡计。感谢您的帮助,并且知道我现在走在正确的道路上。
    • @abflett 没问题。这个解决方案花了我一段时间才弄清楚。你能给我加号和答案吗?谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2014-09-27
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多