Csvhelper和Excel操作

4

CSVHelper是一个很好的用于CSV文件操作(读/写)的工具,但有没有办法使用这个工具来读/写Excel文件? 我想把它与CSV合并起来,以便能够从CSV中读取/写入Excel。

3个回答

3

我最近了解到这个CsvHelper扩展程序:CsvHelper.Excel。虽然我自己没有使用过,但它似乎可以满足你的需求。在幕后,它使用了ClosedXml库。


有人知道这个Excel库是否可以与CsvHelper结合使用,用于Excel部分转换,并包含足够的Excel操作工具,例如带/不带映射文件? - user6156963
有几个开源的.NET库可以读取Excel文件,也有几个专有工具。但我不确定你是否能够与CsvHelper进行很好的集成。你具体是在寻找什么? - Michael Richardson
2
警告:目前(2019年12月),CsvHelper.Excel库与最新的CsvHelper库API不再兼容。请参见https://github.com/christophano/CsvHelper.Excel/issues/10。 - Steve
@Steve...该死! - CShark
1
@Steve,现在已经将其移动到新的存储库(https://github.com/youngcm2/CsvHelper.Excel)。 - user692942

1

我最近完成了一个使用CSVHelper Excel扩展的小工具,因此想向您展示它的工作原理。如果您想要复制相同的结果,只需使用这个特定的库即可。 https://github.com/youngcm2/CsvHelper.Excel Chris Young's Nuget Package 要使用此库,只需定义标题和源,然后了解基本的读写步骤即可。

Github链接如下:Sapphire Code

类定义

Sapphire类包含Excel文件中的所有标题。空格、破折号和下划线都被替换了。它可选地实现了IEquatable接口,其中包括Equals和GetHashCode两种方法,以便更容易地比较源数据和目标数据。

public class Sapphire : IEquatable<Sapphire>
{
    public int Sno { get; set; }
    public string Requestid { get; set; }
    //...... More Properties
    public bool Equals(Sapphire? other)
    {
        //Check whether the compared object is null.
        if (Object.ReferenceEquals(other, null)) return false;

        //Check whether the compared object references the same data.
        if (Object.ReferenceEquals(this, other)) return true;

        //Check whether the products' properties are equal.
        return Requestid.Equals(other.Requestid);
    }
    // If Equals() returns true for a pair of objects
    // then GetHashCode() must return the same value for these objects.
    public override int GetHashCode()
    {

        //Get hash code for the Name field if it is not null.
        int requestid = string.IsNullOrEmpty(Requestid) ? 0 : Requestid.GetHashCode();
        //Calculate the hash code for the product.
        return requestid;
    }

}

public class SapphireMap : ClassMap<Sapphire>
{
    public SapphireMap()
    {
        Map(m => m.Sno).Name("SNo");
        Map(m => m.Requestid).Name("RequestID");
        //...... More Mapped Properties            
    }

}

阅读

由于我们不希望CSVHelper猜测相同,因此传递了工作表名称和HeaderPositions。

    using CsvHelper;
    using CsvHelper.Configuration;
    using CsvHelper.Excel;
public class SapphireHelper
    {    
public List<Sapphire> ReadToEnd(string file, string? SheetName = "Summary Report", int? HeaderLocatedAtRowNumber = 4)
        {
            using (var csv = new CsvReader(new ExcelParser(file, "Summary Report", CultureInfo.InvariantCulture)))
            {
                if (HeaderLocatedAtRowNumber > 0)
                {
                    for (int i = 0; i < HeaderLocatedAtRowNumber; i++)
                    {
                        csv.Read();
                    }
                }
                csv.Context.RegisterClassMap<SapphireMap>();
                var configuration = new CsvConfiguration(CultureInfo.InvariantCulture)
                {
                    HasHeaderRecord = true,
                    HeaderValidated = null,
                    MissingFieldFound = null,
                    IgnoreBlankLines = true,
                    ShouldSkipRecord = (records) => records.Record.All(string.IsNullOrWhiteSpace)
                };
                var records = csv.GetRecords<Sapphire>().ToList();
                return records;
            }
        }
    }

编程

Update方法请求SapphireHelper从两个文件中读取数据,然后比较两者,并使用distinct方法更新目标文件。我试图保持这个例子简单明了。当然,已经成功地测试了代码的正常流程。

public int Update(string source, string destination)
    {
        SapphireHelper sr = new SapphireHelper();
        var recordsAtDestination = sr.ReadToEnd(file: destination, SheetName: "Summary Report", HeaderLocatedAtRowNumber: 0);
        var recordsAtSource = sr.ReadToEnd(file: source, SheetName: "Summary Report", HeaderLocatedAtRowNumber: 4);
        recordsAtDestination.AddRange(recordsAtSource);
        WriteToDestination(destination, recordsAtDestination.Distinct());
        

        return 0;
    }

    private int WriteToDestination(string file, IEnumerable<Sapphire> payload)
    {           
        using (var writer = new ExcelWriter(file,"Summary Report"))
        {
            writer.WriteHeader<Sapphire>();
            writer.WriteRecords(payload);
        }
        return 0;
    }

使用方法

使用方法非常简单高效。只需使用Sapphire Writer将目标文件夹更新为源文件夹中的所有文件。源文件数组是一个简单的字符串数组,包含文件路径。 oneLoneDestinationFile也是一个单一的字符串路径。

SapphireHelper writer = new SapphireHelper();
writer.Update(sourcefilesStringArray.ToString(), oneLoneDestinationFile.ToString());

0

不行。你需要将它与一个单独处理Excel的库结合起来使用。


抱歉,我使用了你的库和Chris Young的扩展。它工作得非常好,对于上面的问题我深表歉意。我希望有一种方法可以取消那个反对票。 - Paras Parmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接