删除在.net中使用excel打开csv文件时显示的科学符号

vwoqyblh  于 2023-02-25  发布在  .NET
关注(0)|答案(2)|浏览(134)

根据我的要求,我想生成一个csv与csv助手,并需要打开相同的使用微软excel。但在这种情况下,值,例如“123456789455454111”被转换为1.23457E+17。
我已经尝试使用下面的代码,但仍然没有运气.

using (var csv = new CsvWriter(writer, config))
{
    csv.Context.TypeConverterOptionsCache.GetOptions<string>().Formats = new[] { "0" };

我已经将变量定义为字符串,但它仍然转换为科学记数法。

var data = new List<MyData>
        {
            new MyData { Value1 = "12345678945545411341" },
            new MyData { Value1 = "9876543214545454222"}
        };

class MyData
{
    public string Value1 { get; set; }
}

有什么办法可以让我达到这个目的吗?
注意:我知道我们可以通过添加'或任何其他非数字字符来避免科学记数法转换,但根据我的要求,我需要显示数值。

nle07wnf

nle07wnf1#

CSV文件只是文本文件。它们没有样式。其他应用程序如何显示文本文件是不可能的。
如果要使用Excel打开文件,更好的办法是使用Epplus、ClosedXML、NPOI等众多Excel库之一创建一个实际的Excel文件。Excel本身支持日期和数字,显示格式由单元格样式控制。
大多数库都可以保存到流(无论是MemoryStream还是直接保存到ASP.NET响应流),从而允许在Web应用程序中生成格式良好的Excel文件
假设这是您要导出的数据:

class MyData
{
    public string Name {get;set;}
    public decimal Value {get;set;}
    public DateTime Recorded {get;set;}
}

var data = new List<MyData>{
            new MyData("Measure1, 12345678945545411341m,DateTime.Now()),
            new MyData("Measure2,  9876543214545454222m,DateTime.Now())
};

使用EPPlus

使用EPPlus,您可以使用单个LoadFromCollectionLoadFromDataTableLoadFromDataReader将数据加载到Excel工作表中。

using(var package = new ExcelPackage(@"c:\temp\myWorkbook.xlsx"))
{
    var sheet = package.Workbook.Worksheets.Add("My Sheet");
    var table=sheet.Cells.LoadFromCollection(data, true, TableStyles.Medium9);;

    // Save to file
    package.Save();
}

这会将数据加载到Excel工作表中,同时保留类型并生成一个带有标题和Medium9表格样式的表格
日期和数字的显示方式由单元格的样式控制。样式格式字符串与Excel中使用的样式格式字符串相同。以下行指定了一个不带小数的数字:

sheet.Cells["A1:A25"].Style.Numberformat.Format = "#";

EPPlus的最新版本允许通过属性指定标题名称、数字格式等:

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

    [EpplusTableColumn(NumberFormat = "#")]
    public decimal Value {get;set;}

    [EpplusTableColumn(NumberFormat = "yyyy-MM-dd")]
    public DateTime Recorded {get;set;}
}

您可以在库的Github存储库中检查Loading Data Samples

使用封闭XML

ClosedXML是另一个流行的开源库,这个代码片段将创建一个包含列表数据的Excel文件:

var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("Data Sheet");

var tableWithData = ws.Cell(1, 1).InsertTable(data.AsEnumerable());

wb.SaveAs("MyFile.xlsx");

库的documentation显示了插入和格式化数据的各种其他方法
样式的工作方式与此类似:

ws.Column("E").Style.NumberFormat.Format = "#";

library docs深入介绍了如何创建表格、样式单元格和列等

o75abkj4

o75abkj42#

问题是Excel无法处理大于15位的数字。learn.microsoft.com
Excel遵循IEEE 754关于如何存储和计算浮点数的规范。因此,Excel只存储数字中的15位有效数字,并将第15位之后的数字更改为零
我尝试将这些数字作为文本添加到Excel中,然后将单元格转换为数字。Excel仍然将它们视为文本。在第3行,我尝试对A1和A2求和,结果得到0.00

在Excel中完整显示这些数字的唯一方法是让Excel将它们格式化为文本而不是数字。
您可以使用数据选项卡将CSV文件导入Excel并告诉Excel“不要检测数据类型”,或者您可以尝试一些针对CSV数据的黑客攻击,如在数据前面放置制表符,或将数据用双引号括起来,并在="<long number>"之前加上等号,最终输出为field1,"=""<long number>""",field3

void Main()
{
    var data = new List<MyData>
    {
        new MyData { Value1 = "12345678945545411341" },
        new MyData { Value1 = "9876543214545454222"}
    };

    using (var writer = new StreamWriter(@"C:\Temp\TestExcelScientific.csv"))
    using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
    {
        csv.Context.RegisterClassMap<MyDataMap>();

        csv.WriteRecords(data);
    }
}

public class MyDataMap : ClassMap<MyData>
{
    public MyDataMap()
    {
        Map(x => x.Value1).TypeConverter<ExcelTextConverter>();
    }
}

public class ExcelTextConverter : DefaultTypeConverter
{
    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        value = "\t" + value;

        return base.ConvertToString(value, row, memberMapData);
    }
}

public class MyData
{
    public string Value1 { get; set; }
}

相关问题