【问题标题】:LinqToCSV format column as TextLinqToCSV 格式列为文本
【发布时间】:2023-03-06 17:38:01
【问题描述】:

我正在使用 LinqToCSV 将列表输出到 CSV。示例代码片段如下:

class Person
{
    [CsvColumn(Name = "Name", FieldIndex = 1)]
    public string UserName { get; set; }
    [CsvColumn(Name = "Address 1", FieldIndex = 2)]
    public string Address1 { get; set; }
    [CsvColumn(Name = "Telephone", FieldIndex = 3)]
    public string Telephone { get; set; }
}


private void OutputToCSV(string filenamePrefix, List<Person> people)
{
    CsvFileDescription outputFileDescription = new CsvFileDescription
    {
        SeparatorChar = ','
        FirstLineHasColumnNames = true, 
        FileCultureName = "en-GB"
    };

    CsvContext cc = new CsvContext();
    cc.Write(
        people,
        @"C:\temp\people.csv",
        outputFileDescription);            
}

我的问题是电话号码。如果它在对象中为 0123456789012,那么当我在 Excel 中打开 CSV 时,它被视为一个数字,并且前导零被删除。我想将 CSV 中的列预先格式化为文本。

根据Stop Excel from automatically converting certain text values to dates,我可以用等号开始字段并将值放在引号中,但是我可以设置一个属性,这意味着 LinqToCSV 将为我执行此操作吗?我真的不想使用 LinqToCSV,然后打开文件并对其进行编辑以得到我想要的。

【问题讨论】:

  • 使用 EPPlus 代替 CSV 创建一个真实 Excel 文件。 CSV 没有任何格式信息,因此无法判断字段是文本还是数字
  • Panagiotis:这看起来是一个不错的选择,也是创建 Excel 文件的好方法,但不是 CSV 文件。

标签: c# linqtocsv


【解决方案1】:

您打算创建 CSV 或 Excel 文件吗?如果是后者,那么如果您改用 Nuget 的 Epplus 会不会容易得多?即:

void Main()
{
  ExcelPackage pck = new ExcelPackage();
  List<Person> people = new List<Person> {
    new Person { UserName="Cetin", Address1="A1", Telephone="012345"},
    new Person { UserName="Timbo", Address1="A2", Telephone="023456"},
    new Person { UserName="StackO", Address1="A3", Telephone="0 345 6789 01 23"},
  };


  var wsEnum = pck.Workbook.Worksheets.Add("MyPeople");

  //Load the collection starting from cell A1...
  wsEnum.Cells["A1"].LoadFromCollection(people, true, TableStyles.Medium9);
  wsEnum.Cells[wsEnum.Dimension.Address].AutoFitColumns();
  //...and save
  var fi = new FileInfo(@"d:\temp\People.xlsx");
  if (fi.Exists)
  {
    fi.Delete();
  }
  pck.SaveAs(fi);
}

class Person
{
  public string UserName { get; set; }
  public string Address1 { get; set; }
  public string Telephone { get; set; }
}

【讨论】:

  • 问题是针对 CSV 文件,而不是 Excel 文件。 CSV 文件通常在 Excel 中打开,但也用于导入其他系统。
  • 阅读我在顶部所说的话。 CSV 表示逗号分隔值,用于在不同介质之间传输数据,并不是 Excel 特有的 - “经常在 Excel 中打开”是不正确的说法。它通常只适用于经常使用 Excel 的人。
  • 我去看看 Epplus。据我所知,不需要将文件导入其他任何东西,我认为它只是在 Excel 中使用,所以这可以完成工作。
  • 哦,那当然调查一下。它很简单,它会创建 xlsx 文件,即使用户的机器上没有安装 Excel。
【解决方案2】:

正如您所说,这是一个 Excel 问题,您需要数据具有前导 = 符号,以便 0123456789012 变为 ="0123456789012"。

您可以使用 OutputFormat 更改格式,但您需要调整格式:

[CsvColumn(FieldIndex = 2, OutputFormat = "dd MMM HH:mm:ss")]

【讨论】:

  • 它实际上不是 Excel 问题,无法判断该字段包含字符串或数字。 CSV 没有任何类型信息,因此 Excel 在导入时会尝试猜测字段类型
  • 所有 CSV 文件都只是文本。但是,Excel 会将值转换为数字,因此添加“=”符号会告诉 Excel 将其视为数字。
  • 不,它会将其转换为公式。 Excel 在这些情况下使用单引号 (')。不过最好创建一个 real Excel 文件。既简单又安全
  • “其他地方”可能是一个不会有问题的数据库。
  • 任何字段前缀都会使 CSV 不适合任何其他应用程序使用。例如,如果不先去除前缀,就无法在数据库中导入这样的文件。所以前缀几乎需要 Excel - 或其他以相同方式处理前缀的应用程序
【解决方案3】:

尝试使用 OutputFormat 来强制执行 ToString()。您也可以将它与您的其他修复程序结合使用并使用 OutputFormat="=C" 但我没有尝试过。

[CsvColumn(Name = "Telephone", FieldIndex = 3, OutputFormat = "C")]
public string Telephone { get; set; }

【讨论】:

  • 问题不在于输出格式。所有 CSV 条目都是文本,但 Excel 将其作为数字读取并进行修改。必须将数字更改为具有前导“=”。
  • 不,这会将其转换为公式。 Excel 对包含应视为文本的数字数据的字段使用单引号 (')
  • 我已经尝试将单引号直接放入 CSV。 Excel 显示报价!
猜你喜欢
  • 2017-05-12
  • 2010-09-15
  • 2017-10-10
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
  • 2016-12-15
  • 1970-01-01
  • 2015-08-19
相关资源
最近更新 更多