【问题标题】:How can I get values from a csv file where some of the cells contain commas?如何从某些单元格包含逗号的 csv 文件中获取值?
【发布时间】:2016-11-22 21:19:15
【问题描述】:

我有一个脚本,它导入一个 csv 文件并读取每一行以更新 Sitecore 中的相应项目。它适用于许多产品,但问题在于行中某些单元格中包含逗号的某些产品(例如产品描述)。

protected void SubmitButton_Click(object sender, EventArgs e)
{
    if (UpdateFile.PostedFile != null)
    {
        var file = UpdateFile.PostedFile;

        // check if valid csv file

        message.InnerText = "Updating...";

        Sitecore.Context.SetActiveSite("backedbybayer");
        _database = Database.GetDatabase("master");
        SitecoreContext context = new SitecoreContext(_database);
        Item homeNode = context.GetHomeItem<Item>();


        var productsItems =
            homeNode.Axes.GetDescendants()
                .Where(
                    child =>
                        child.TemplateID == new ID(TemplateFactory.FindTemplateId<IProductDetailPageItem>()));

        try
        {
            using (StreamReader sr = new StreamReader(file.InputStream))
            {
                var firstLine = true;
                string currentLine;
                var productIdIndex = 0;
                var industryIdIndex = 0;
                var categoryIdIndex = 0;
                var pestIdIndex = 0;
                var titleIndex = 0;
                string title;
                string productId;
                string categoryIds;
                string industryIds;
                while ((currentLine = sr.ReadLine()) != null)
                {
                    var data = currentLine.Split(',').ToList();
                    if (firstLine)
                    {
                        // find index of the important columns
                        productIdIndex = data.IndexOf("ProductId");
                        industryIdIndex = data.IndexOf("PrimaryIndustryId");
                        categoryIdIndex = data.IndexOf("PrimaryCategoryId");
                        titleIndex = data.IndexOf("Title");
                        firstLine = false;
                        continue;
                    }

                    title = data[titleIndex];
                    productId = data[productIdIndex];
                    categoryIds = data[categoryIdIndex];
                    industryIds = data[industryIdIndex];

                    var products = productsItems.Where(x => x.DisplayName == title);
                    foreach (var product in products)
                    {
                        product.Editing.BeginEdit();
                        try
                        {
                            product.Fields["Product Id"].Value = productId;
                            product.Fields["Product Industry Ids"].Value = industryIds;
                            product.Fields["Category Ids"].Value = categoryIds;
                        }
                        finally
                        {
                            product.Editing.EndEdit();
                        }
                    }
                }
            }

            // when done
            message.InnerText = "Complete";
        }
        catch (Exception ex)
        {
            message.InnerText = "Error reading file";
        }             
    }
}

问题在于,当描述字段包含逗号时,例如“产品是一种有效的预防性生物杀菌剂”,它也会被拆分并抛出索引,因此categoryIds = data[8] 会得到错误的值。

电子表格是我们的客户提供的数据,因此除非必要,否则我宁愿不要求客户编辑文件。有没有办法在我的代码中处理这个问题?有没有其他方法可以读取不会用逗号分割所有内容的文件?

【问题讨论】:

  • 你说“导入一个 xls 文件”。您的意思是“导入 csv 文件”吗?如果您尝试读取 CSV 文件,请使用真正的 CSV 解析器。谷歌搜索应该出现几个。正确解析 CSV 并不像您想象的那么简单。
  • 最简单的解决方案:将分隔符切换为 Semikolon ;。由于您的 csv-sheet 包含复杂的文本,逗号不是最好的分隔符
  • 对不起,是的,这是一个 csv 文件,但我可以尝试导入一个 xls 文件。
  • 当您从 exel 文件中读取数据时,您可以导入带有双引号 "" 或 [] 标记的所有文本列的数据,并将这些分隔符用作字符串列的开始/结束标记。您可能需要修改脚本来处理这些分隔符。

标签: c# excel file csv xls


【解决方案1】:

我建议使用 Ado.Net,如果字段的数据在引号内,它将像字段一样解析它并忽略其中的任何逗号..

代码示例:

static DataTable GetDataTableFromCsv(string path, bool isFirstRowHeader)
{
    string header = isFirstRowHeader ? "Yes" : "No";

    string pathOnly = Path.GetDirectoryName(path);
    string fileName = Path.GetFileName(path);

    string sql = @"SELECT * FROM [" + fileName + "]";

    using(OleDbConnection connection = new OleDbConnection(
              @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + 
              ";Extended Properties=\"Text;HDR=" + header + "\""))
    using(OleDbCommand command = new OleDbCommand(sql, connection))
    using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
    {
        DataTable dataTable = new DataTable();
        dataTable.Locale = CultureInfo.CurrentCulture;
        adapter.Fill(dataTable);
        return dataTable;
    }
}

【讨论】:

    猜你喜欢
    • 2016-08-28
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    相关资源
    最近更新 更多