上篇博客中主要记录一些关于DBF数据文件的概念性知识。包括DBF的数据结构和用处。在这里记录一下在C#中导出DBF文件的实现方式。
DBF文件也是一种数据库文件,我们导出DBF文件也就是将数据库中的数据导出到DBF文件中。所以最主要的就是讲DataTable转换成DBF,包括数据和数据类型。
DBF文件也是一种数据库文件,我们导出DBF文件也就是将数据库中的数据导出到DBF文件中。所以最主要的就是讲DataTable转换成DBF,包括数据和数据类型。
<span style="font-size:24px;">private bool WriteDBFfile(string filepath, DataTable dt, List<string> columnNames, string tableName, Dictionary<string, char> nametype = null)
{
#region ***************************************写t**************************************
nametype = ConvertColumnType(dt, tableName); ;
FileStream fs = null;
BinaryWriter bw = null;
try
{
int rowCount = dt.Rows.Count;
int columnCount = dt.Columns.Count;
//if (rowCount > 0 && columnCount > 0)
//{
fs = new FileStream(filepath, FileMode.Create, FileAccess.Write);
bw = new BinaryWriter(fs);
byte tempByte;
byte[] tempBytes;
int tempInt;
int[] fieldLength = new int[columnCount];
int tempMax = 0;
for (int i = 0; i < columnCount; i++)
{
tempMax = 0;
for (int j = 0; j < rowCount; j++)
{
if (dt.Rows[j][i].ToString() != null && dt.Rows[j][i].ToString() != "")
{
if (dt.Rows[j][i].ToString().Length > tempMax)
{
tempMax = dt.Rows[j][i].ToString().Length;
}
}
}
char dbfType = 'C';
if (nametype.ContainsKey(columnNames[i].ToLower()))
{
dbfType = nametype[columnNames[i].ToLower()];
}
if (tableName.StartsWith("F") && dbfType == 'N')
{
tempMax = 8;
}
else if (dbfType == 'N')
{
tempMax = 1;
}
//数êy字×?类àà型Dí长3¤度è至á少éù13,£?此′?处′|直±接ó设éè置?所ù有óD列áD最×?小D?长3¤度è为a13
fieldLength[i] = tempMax * 2 < 13 ? 13 : tempMax * 2;
}
/
tempByte = 0x03;
bw.Write(tempByte);
tempBytes = new byte[3];
tempInt = DateTime.Now.Year - 1900;
tempBytes[0] = System.Convert.ToByte(tempInt);
tempBytes[1] = System.Convert.ToByte(DateTime.Now.Month);
tempBytes[2] = (byte)(DateTime.Now.Day);
bw.Write(tempBytes);
bw.Write(rowCount);
tempInt = 33 + columnCount * 32;
bw.Write((Int16)tempInt);
tempInt = 1;
for (int i = 0; i < columnCount; i++)
{
tempInt += fieldLength[i];
}
bw.Write((Int16)tempInt);
tempBytes = new byte[20];
bw.Write(tempBytes);
string tempColumnName;
for (int i = 0; i < columnCount; i++)
{
tempColumnName = columnNames[i];
tempBytes = ConvertStringToBytes(tempColumnName, 11);
bw.Write(tempBytes);
char dbfType = 'C';
if (nametype.ContainsKey(tempColumnName.ToLower()))
{
dbfType = nametype[tempColumnName.ToLower()];
}
tempByte = (byte)dbfType;//数êy据Y类àà型Dí为a字×?符·?串′?
bw.Write(tempByte);
//第μú12-15为a保±£留á?字×?节ú
tempBytes = new byte[4];
bw.Write(tempBytes);
//第μú16个?字×?节ú为a字×?段?长3¤度è
tempMax = fieldLength[i];
tempByte = (byte)tempMax;
bw.Write(tempByte);
//接ó着×?第μú17-31都?为a保±£留á?字×?节ú
tempBytes = new byte[15];
if (tableName.StartsWith("F") && dbfType == 'N' && tempColumnName.StartsWith("z"))
{
tempBytes[0] = (byte)2;/
}
bw.Write(tempBytes);
}
tempByte = 0x0D;
bw.Write(tempByte);
object tempValue;
for (int i = 0; i < rowCount; i++)
{
//每?一ò?行DD第μú一ò?个?字×?节ú默?认è?为a20
tempByte = 0x20;
bw.Write(tempByte);
for (int j = 0; j < columnCount; j++)
{
tempValue = dt.Rows[i][j];
if (tempValue != null)
{
double val;
if (double.TryParse(tempValue.ToString(), out val) && Equals(val, DbfsjdcViewModel_2015.FXB_DEF))
{
tempValue = "";
}
tempBytes = ConvertStringToBytes(tempValue.ToString(), fieldLength[j], true);
bw.Write(tempBytes);
}
else
{
tempBytes = ConvertStringToBytes("", fieldLength[j], true);
bw.Write(tempBytes);
}
}
}
}
catch (Exception except)
{
MessageBox.Show(except.Message);
}
finally
{
if (bw != null)
{
bw.Close();
bw.Dispose();
}
if (fs != null)
{
fs.Close();
fs.Dispose();
}
nametype.Clear();
}
return System.IO.File.Exists(filepath);
#endregion ***************************************写D′入è?DBF文?件t**************************************
}
类型转换将String类型转换为Bytes类型方法:
private byte[] ConvertStringToBytes(string tempStr, int limitLength, bool needAppendWhiteSpace = false)
{
try
{
//originaldqdm,sourcelsgxmc,sourcelsgxdm,
//org_dqdm,src_lsgxmc,src_lsgxdm
switch (tempStr)
{
case "originaldqdm":
tempStr = "org_dqdm";
break;
case "sourcelsgxmc":
tempStr = "src_lsgxmc";
break;
case "sourcelsgxdm":
tempStr = "src_lsgxdm";
break;
}
byte[] tempBytes = UTF8Encoding.GetEncoding("gb2312").GetBytes(tempStr);
byte[] result = null;
if (tempBytes.Length == limitLength)
{
result = tempBytes;
}
else if (tempBytes.Length > limitLength)
{
result = new byte[limitLength];
for (int i = 0; i < limitLength; i++)
{
result[i] = tempBytes[i];
}
}
else if (tempBytes.Length < limitLength)
{
result = new byte[limitLength];
for (int i = 0; i < tempBytes.Length; i++)
{
result[i] = tempBytes[i];
}
if (needAppendWhiteSpace)
{
for (int i = tempBytes.Length; i < limitLength; i++)
{
result[i] = (byte)32;
}
}
}
return result;
}
catch (Exception except)
{
MessageBox.Show(except.Message);
return null;
}
}
提取DataTable 列名,并转化为 List
private Dictionary<string, char> ConvertColumnType(DataTable dt, string tableName)
{
Dictionary<string, char> lstType = new Dictionary<string, char>();
foreach (DataColumn dc in dt.Columns)
{
string colName = dc.ColumnName;
string colType = dc.DataType.ToString();
char dbfType = 'C';
switch (colType)
{
case "System.Int32":
case "System.Int64":
case "System.Double":
case "System.Decimal":
case "System.UInt16":
case "System.UInt32":
case "System.UInt64":
case "System.Byte":
case "System.SByte":
dbfType = 'N';
break;
case "System.DateTime":
dbfType = 'D';
break;
case "System.Int16":
case "System.String":
dbfType = 'C';
break;
default:
dbfType = 'C';
break;
}
if (!lstType.ContainsKey(colName.ToLower()))
{
lstType.Add(colName.ToLower(), dbfType);
}
}
return lstType;
}</span>