FileHelper 库中是否有内置字段属性,它将在最终生成的 CSV 中添加标题行?
我用谷歌搜索并没有找到太多相关信息。目前我有这个:
DelimitedFileEngine _engine = new DelimitedFileEngine(T);
_engine.WriteStream
(HttpContext.Current.Response.Output, dataSource, int.MaxValue);
它可以工作,但没有标题。
我正在考虑拥有像
FieldTitleAttribute
这样的属性并将其用作列标题。
所以,我的问题是在哪一点检查属性并插入标题列?以前有人做过类似的事情吗?
我想插入标题并使用与实际字段名称不同的自定义文本,只需在对象的每个成员上都有一个属性即可:
[FieldTitleAttribute("Custom Title")]
private string Name
也许还有一个选项可以告诉引擎在生成标头时插入标头。
因此,当调用
WriteStream
或 WriteString
时,标题行将插入自定义标题。
我找到了 DelimitedFileEngine 的几个事件,但没有找到检测当前记录是否是第一行以及如何在此之前插入行的最佳方法。
我知道这是一个老问题,但这里有一个适用于 v2.9.9 的答案
FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
engine.HeaderText = engine.GetFileHeader();
这里有一些代码可以做到这一点:https://gist.github.com/1391429
要使用它,您必须用
[FieldOrder]
装饰您的字段(无论如何,这是一个很好的 FileHelpers 实践)。用途:
[DelimitedRecord(","), IgnoreFirst(1)]
public class Person
{
// Must specify FieldOrder too
[FieldOrder(1), FieldTitle("Name")]
string name;
[FieldOrder(2), FieldTitle("Age")]
int age;
}
...
var engine = new FileHelperEngine<Person>
{
HeaderText = typeof(Person).GetCsvHeader()
};
...
engine.WriteFile(@"C:\people.csv", people);
但是对此的支持确实需要在 FileHelpers 本身中添加。我可以立即想到一些在实施之前需要回答的设计问题:
[FieldHeader]
属性,那么我们是否还应该尝试将属性与文件中的列名称匹配?如果它们不匹配,您应该抛出异常吗?如果序数位置与列名称不一致会发生什么?我不知道你是否还需要这个,但这是 FileHelper 的工作方式: 要包含列标题,您需要定义一个字符串,其中标题的分隔方式与文件相同。 例如用“|”作为分隔符:
public const string HeaderLine = @"COLUMN1|COLUMN2|COLUMN3|...";
然后,当调用你的引擎时:
DelimitedFileEngine _engine = new DelimitedFileEngine<T> { HeaderText = HeaderLine };
如果你不想写标题,就不要在引擎上设置
HeaderText
属性。
List<MyClass> myList = new List<MyClass>();
FileHelperEngine engine = new FileHelperEngine(typeof(MyClass));
String[] fieldNames = Array.ConvertAll<FieldInfo, String>(typeof(MyClass).GetFields(), delegate(FieldInfo fo) { return fo.Name; });
engine.HeaderText = String.Join(";", fieldNames);
engine.WriteFile(MapPath("MyClass.csv"), myList);
只是为了包含一个更完整的示例,这会为我节省一些时间,对于 FileHelpers NuGet 包的版本 3.4.1....
给定
[DelimitedRecord(",")]
public class Person
{
[FieldCaption("First")]
public string FirstName { get; set; }
[FieldCaption("Last")]
public string LastName { get; set; }
public int Age { get; set; }
}
以及创建它的代码
static void Main(string[] args)
{
var people = new List<Person>();
people.Add(new Person() { FirstName = "James", LastName = "Bond", Age = 38 });
people.Add(new Person() { FirstName = "George", LastName = "Washington", Age = 43 });
people.Add(new Person() { FirstName = "Robert", LastName = "Redford", Age = 28 });
CreatePeopleFile(people);
}
private static void CreatePeopleFile(List<Person> people)
{
var engine = new FileHelperEngine<Person>();
using (var fs = File.Create(@"c:\temp\people.csv"))
using (var sw = new StreamWriter(fs))
{
engine.HeaderText = engine.GetFileHeader();
engine.WriteStream(sw, people);
sw.Flush();
}
}
你明白了
First,Last,Age
James,Bond,38
George,Washington,43
Robert,Redford,28
我发现您可以使用 FileHelperAsyncEngine 来完成此任务。假设您的数据是一个名为“output”、类型为“outputData”的列表,那么您可以编写如下所示的代码:
FileHelperAsyncEngine outEngine = new FileHelperAsyncEngine(typeof(outputData));
outEngine.HeaderText = "Header1, Header2, Header3";
outEngine.BeginWriteFile(outputfile);
foreach (outputData line in output){
outEngine.WriteNext(line);
}
outEngine.Close();
您可以简单地使用基类中的 FileHelper 的 GetFileHeader 函数
var engine = new FileHelperEngine<ExportType>();
engine.HeaderText = engine.GetFileHeader();
engine.WriteFile(exportFile, exportData);
bool includeHeader = false;
var attributes = classType.GetCustomAttributes(typeof(IgnoreFirstAttribute), false);
if (attributes.Length > 0)
{
IgnoreFirstAttribute myAttribute = (IgnoreFirstAttribute)attributes[0];
includeHeader = myAttribute.NumberOfLines > 0;
}
FileHelperEngine engine = new FileHelperEngine(classType);
if (includeHeader)
engine.HeaderText = engine.GetFileHeader();
var fileContent = engine.WriteString(obj);