(08-11-29日更新,增加了Xls和Xlsx文件导入支持)
1. 功能:
1.1. *配置文件格式:生成的DataTable的主键、文件内容中是否有表头、列分隔符、列是否可空、列中数据类型(String型可加长度限制)、列是否导进DataTable(过滤文件中的列,不读入DataTable);
1.2. 支持TXT、CSV、XLS、XLSX四种格式;
1.3. 生成错误信息报告:支持读到N条错误数据后,终止文件解析(N在config文件中配置);
1.4. 解析大文件时,支持行读;
1.5. 支持传入文件名或者Stream(例如Web上传后直接取得数据流)
2. 使用示例:
2.1 数据文件(数据保存成DemoDataFile.txt)
happyhippy|other info|
1984
-
9
-
11
|
test|unuseful info|
9999
-
12
-
30
|
0
或(带表头信息的数据):
雇员姓名|无用信息不用导入|生日|薪水
happyhippy|other info|
1984
-
9
-
11
|
test|unuseful info|
9999
-
12
-
30
|
0
2.2 配置定义
Code
<?xml version="1.0" encoding="utf-8" ?>
<DataTableSchema>
<FileType Ext="csv" HasHeader="true"/>
<FileType Ext="txt" CellSplit="," HasHeader="true"/>
<FileType Ext="xls" HasHeader="true"/>
<FileType Ext="xlsx" HasHeader="true"/>
<Columns>
<Column Name="EmployeeName" Type="System.String" Length="50" Description="雇员姓名" PrimaryKey="true"></Column>
<Column Name="Birthday" Type="System.DateTime" Description="生日" AllowNull="true"></Column>
<Column Name="Salary" Type="System.Decimal" Description="薪水" AllowNull="false"></Column>
</Columns>
</DataTableSchema>
各个属性代表的意思:
FileType节点:CellSplit:列分隔符;HasHeader:文件内容中是否有表头(如果设成了true,则文件中的表头必须跟配置文件中的列的Description字段一致);
Column节点:PrimaryKey:指定生成的DataTable的主键(默认false);AllowNull:设定是否可空(默认true);Type:列中数据类型(无默认值,必须指定;String型须加长度限制);Used:列是否导进DataTable(默认true)
2.3 导入结果
2.4 调用示例代码(4种读取方式)
Code
XmlDocument dom = new XmlDocument();
dom.Load("demoSchema.xml"); //可以将配置定义放在数据库或其他地方
string schema = dom.InnerXml;
ImportTxtFile(schema);
ImportXlsFile(schema);
private static void ImportXlsFile(string schema)
{
string fileFullName = "Excel.xls";
DataTable resultDT = null;
try
{
//法1:传入文件名,按schema中的配置进行解析
resultDT = ImportHelper.Import(fileFullName, schema);
//法2:文件流解析
using (Stream fileStram = new FileStream(fileFullName, FileMode.Open, FileAccess.Read))
{
resultDT = ImportHelper.Import(fileStram, schema, FlatFileType.XLS);
}
//法3:如果数据量大,可以进行行读:
using (FlatFileReader reader = FlatFileReader.GetFlatFileReader(fileFullName, schema))
{
reader.CheckHeadRow();
int totelCount = 0; //记录读了多少行
while (reader.Read())
{
if (reader.ReadRow(totelCount + 1))
totelCount++;
if (totelCount % 500 == 0) //每批读500条记录
{
resultDT = reader.GetResultTable();//接下来可以对resultDT进行处理
reader.ClearResultTable();
}
}
if (totelCount % 500 > 0)
{
resultDT = reader.GetResultTable(); //最后一批记录
//接下来可以对resultDT进行处理
}
if (reader.ErrorInfoTable != null && reader.ErrorInfoTable.Rows.Count > 0)
throw new ErrorFileException("解析文件出错", reader.ErrorInfoTable);
}
}
catch (ErrorFileException efex)
{
DataTable errorInfoTable = efex.ErrorInfoDataTable;//存储了错误信息的DataTable
}
}
private static void ImportTxtFile(string schema)
{
string fileFullName = "DemoDataFile.txt";
DataTable resultDT = null;
try
{
//法1:传入文件名,按schema中的配置进行解析
resultDT = ImportHelper.Import(fileFullName, schema);
//法2:文件流解析
using (Stream fileStram = new FileStream(fileFullName, FileMode.Open, FileAccess.Read))
{
resultDT = ImportHelper.Import(fileStram, schema, FlatFileType.TXT);
}
//法3:如果数据量大,可以进行行读:
using (FlatFileReader reader = FlatFileReader.GetFlatFileReader(fileFullName, schema))
{
reader.CheckHeadRow();
int totelCount = 0; //记录读了多少行
while (reader.Read())
{
if (reader.ReadRow(totelCount + 1))
totelCount++;
if (totelCount % 500 == 0) //每批读500条记录
{
resultDT = reader.GetResultTable();//接下来可以对resultDT进行处理
reader.ClearResultTable();
}
}
if (totelCount % 500 > 0)
{
resultDT = reader.GetResultTable(); //最后一批记录
//接下来可以对resultDT进行处理
}
if (reader.ErrorInfoTable != null && reader.ErrorInfoTable.Rows.Count > 0)
throw new ErrorFileException("解析文件出错", reader.ErrorInfoTable);
}
}
catch (ErrorFileException efex)
{
DataTable errorInfoTable = efex.ErrorInfoDataTable;//存储了错误信息的DataTable
}
}
3. 源代码下载:Happyhippy.ImpotFile.rar
4. 程序结构:
5. 遗留问题:
5.1. CSV读取方式中,禁止将内容转换成数字;