【问题标题】:How to force a CSV column to treat numbers as text, in C# using StringBuilder如何在 C# 中使用 StringBuilder 强制 CSV 列将数字视为文本
【发布时间】:2021-10-30 14:33:58
【问题描述】:

我有一个 C# 程序,它从 RESTful API 读取数据,并将其输出到 CSV 文件中。

            if (response.IsSuccessful)
            {
                //serialize the data into the Devices[] array RootObject
                RootObject ro = new RootObject();
                ro = JsonConvert.DeserializeObject<RootObject>(response.Content);

                //create a new DataTable with columns specifically required
                DataTable dt = new DataTable("tblDevices");
                dt.Columns.Add("AssetNumber");
                dt.Columns.Add("DeviceFriendlyName");
                dt.Columns.Add("IMEI");

                //iterate through each device data and add it into a DataRow
                foreach(Device d in ro.Devices)
                {
                    DataRow dr = dt.NewRow();

                    dr["AssetNumber"] = d.AssetNumber;
                    dr["DeviceFriendlyName"] = d.DeviceFriendlyName;

                    dr["IMEI"] = '"'+d.Imei+'"';   //<-- this is always a "number" in CSV

还有字符串生成器代码:

                    //now turn the datatable into a enumerated string
                    StringBuilder sb = new StringBuilder();
                    IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                                      Select(column => column.ColumnName);
                    sb.AppendLine(string.Join(",", columnNames));

                    //read each row of the datateble, enumrate and save into the StringBuilder object
                    foreach (DataRow row in dt.Rows)
                    {
                        IEnumerable<string> fields = row.ItemArray.Select(field => field.ToString());
                        sb.AppendLine(string.Join(",", fields));
                    }

                    //finally save the string as a CSV file
                    string FilePath = ConfigurationManager.AppSettings["FilePath"];
                    string wsFileName = FilePath+"\\airwatch_"+DateTime.Now.ToString("yyyyMMddHHmm")+".csv";
                    File.WriteAllText(wsFileName, sb.ToString());

当我打开 CSV 时,我得到的 IMEI 号码在 Excel 中始终是一个数字。

因此,它没有将数字显示为字符串 - “353034999819999”,而是将其显示为“3.53034E+14”。是的,这是一个很大的数字。

我不希望它是指数。我想要的是 Excel 中的字符串。

我已经尝试在字段周围使用双引号,如上面的代码所示,它始终作为数字传递。我也尝试过在值的开头使用单引号,但它看起来像一个以单引号开头的字符串。

如何将此值保存在 CSV 文件中,作为字符串而不是数字?

【问题讨论】:

  • 试着用这种方式把数字放在引号里"=""353034999819999""",看这个answer

标签: c# string type-conversion


【解决方案1】:

在excel中将该列格式化为数字:

如果你不想这样做,那么你可以试试这个代码:

// make sure you use the CsvHelper nuget package.
using CsvHelper;
using System;
using System.Collections.Generic;
using System.IO;

class Program
{
    static void Main(string[] args)
    {

        var recordsToSave = new List<Foo>();
        recordsToSave.Add(new Foo()
        {
            LargeNumber = "=\"353034999819999\"",
            Name = "SomeName"
        });

        var fileStream = new FileStream("output.csv", FileMode.CreateNew);
        using StreamWriter writer = new StreamWriter(fileStream);
        using var csv = new CsvWriter(writer);
        csv.WriteRecords(recordsToSave);
    }

    class Foo
    {
        public string Name { get; set; }

        public string LargeNumber { get; set; }
    }

}



【讨论】:

  • 谢谢。看起来有点工作,但是当我在 Excel 中将值转换为文本 (=VALUETOTEXT([@IMEI])) 时,我得到了我真正想要的,并且在我将复制/粘贴为值之后。所以你的答案是 >>close
【解决方案2】:

嗨,如果它对你有帮助,我有一个 DataGridView 和一个看起来像“8940012004412026012”的列。对于导出到 CVS,我使用:

 if (rap_cuiclient.Rows.Count > 0)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "CSV (*.csv)|*.csv";
            sfd.FileName = "Output.csv";
            bool fileError = false;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(sfd.FileName))
                {
                    try
                    {
                        File.Delete(sfd.FileName);
                    }
                    catch (IOException ex)
                    {
                        fileError = true;
                        MessageBox.Show("Tabelul este gol" + ex.Message);
                    }
                }
                if (!fileError)
                {
                    try
                    {
                        int columnCount = rap_cuiclient.Columns.Count;
                        string columnNames = "";
                        string[] outputCsv = new string[rap_cuiclient.Rows.Count + 1];
                        for (int i = 0; i < columnCount; i++)
                        {
                            columnNames += rap_cuiclient.Columns[i].HeaderText.ToString() + ",";
                        }
                        outputCsv[0] += columnNames;

                        for (int i = 1; (i - 1) < rap_cuiclient.Rows.Count; i++)
                        {
                            for (int j = 0; j < columnCount; j++)
                            {
                                outputCsv[i] += rap_cuiclient.Rows[i - 1].Cells[j].Value.ToString() + ",";
                            }
                        }

                        File.WriteAllLines(sfd.FileName, outputCsv, Encoding.UTF8);
                        MessageBox.Show("Datele au fost exportate cu scucces !!!", "Info");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Error :" + ex.Message);
                    }
                }
            }
        }
        else
        {
            MessageBox.Show("Nu sunt date pentru export !!!", "Info");
        }

这就是结果

【讨论】:

  • 谢谢,但这是在 Excel 中将数字显示为字符串吗?我假设这段代码 - Cells[j].Value.ToString() 将数字转换为字符串,但真正的测试是当您在 Excel 中打开 CSV 时 - 它是什么样的?
  • 尝试在 Excel 中打开一个新文件,转到数据,从文本中选择,然后在进入文本导入向导的第 3 步时选择 CSV 文件,选择列中的文本和带有大号的表列
猜你喜欢
  • 2021-06-14
  • 1970-01-01
  • 2011-05-06
  • 2016-01-12
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多