zoukankan      html  css  js  c++  java
  • c#实现将DataTable中的数据导出到DBF文件(转)

    由于种种原因,需要将某些数据以dbf的形式导出,网上苦寻资料,走了许多弯路;

    首先记录下走的弯路

    1.DBF字段名称长度限制

    在编程过程中老是报一些奇怪的错误,创建表格的sql语句拿到sql数据库中跑完全没有问题,但是数据库中老是报各种奇怪的错误,比如建表语句:


    create table 表格(公司本年度总收入 int,公司本年度总支出 int)

    在程序中执行这段语句总是会出现错误:“公司本年度”已经存在于表中,百思不得其解;
    后来经过查资料,各种死磕,最后发现所有成功导出的dbf文件中所有字段都不超过5个汉字,10个英文字符,这是dbf毫无人性的地方,字段定义不能超过10个字节,如果超过则自动截取,运气好截取的前五个字没有重复就成功导出,脸黑的就。。。

    2.DBF字段类型

    目前真没有找到DBF字段类型官方详细的介绍,我只能说说我当前用过的有varchar,int,double,char,numeric,至于长度什么的,这个自己下个fvp玩玩就知道了;

    废话少说,直接上代码


    public class DbfExportHelper
    {
    /// <summary>
    /// 数据库所在路径
    /// </summary>
    private string filePath = "";

    /// <summary>
    /// 连接字符串
    /// </summary>
    private string connstring = "";


    /// <summary>
    /// 数据库连接
    /// </summary>
    private OleDbConnection Connection = new OleDbConnection();

    /// <summary>
    /// 错误信息
    /// </summary>
    private string _ErrInfo;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="filePath">dbf文件所在文件夹路径</param>
    public DbfExportHelper(string filePath)
    {
    this.filePath = filePath;
    this.connstring = string.Format("Provider = Microsoft.Jet.OLEDB.4.0 ;Data Source ={0};Extended Properties=dBASE IV;", filePath);
    this.Connection = new OleDbConnection(connstring);
    }

    /// <summary>
    /// 改变数据库所在路径
    /// </summary>
    /// <param name="filePath">新文件夹路径</param>
    /// <returns></returns>
    public bool ChangeDbfPosition(string filePath)
    {
    bool success = true;
    if (!Directory.Exists(filePath))
    {
    success = false;
    }
    else {
    this.filePath = filePath;
    this.connstring = string.Format("Provider = Microsoft.Jet.OLEDB.4.0 ;Data Source ={0};Extended Properties=dBASE IV;", filePath);
    this.Connection = new OleDbConnection(connstring);
    this._ErrInfo = string.Empty;

    }
    return success;
    }




    /// <summary>
    /// 构造dbf文件,文件名称为dt的表名,后缀名为dbf
    /// </summary>
    /// <param name="dt">待写入的表格数据</param>
    /// <returns></returns>
    public bool CreateNewTable(DataTable dt){
    bool success = false;
    OleDbCommand command = Connection.CreateCommand();
    try
    {
    if(File.Exists(filePath +@""+dt.TableName+".dbf"))
    {
    File.Delete(filePath + @"" + dt.TableName + ".dbf");
    }
    Connection.Open();
    command.CommandType = CommandType.Text;
    List<string> cols = new List<string>();
    foreach(DataColumn dc in dt.Columns)
    {
    string colType = "";
    string colName = dc.ColumnName;
    switch (dc.DataType.Name)
    {
    case "Boolean":
    colType = "bool";
    break;
    case "Double":
    case "Float":
    colType = "double";
    break;
    case "Int16":
    case "Int32":
    case "Int64":
    case "Int":
    colType = "int";
    break;
    case "String":
    colType = "varchar";
    break;
    default:
    colType = "varchar";
    break;
    }

    cols.Add(string.Format(@"{0} {1}",colName,colType));
    }
    string cols_where = string.Join(",", cols);
    string sql = string.Format(@"CREATE TABLE {0} ({1})", dt.TableName,cols_where);
    command.CommandText = sql;
    //"CREATE TABLE table1 (自动编号 int,名称 Char(5),工资 Double)";
    command.ExecuteNonQuery();
    success = true;
    }
    catch (Exception c)
    {
    _ErrInfo = c.Message;
    }
    finally
    {
    command.Dispose();
    if (Connection.State == System.Data.ConnectionState.Open)
    Connection.Close();
    command.Dispose();
    }
    return success;
    }

    /// <summary>
    /// 导入数据到dbf文件
    /// </summary>
    /// <param name="dt"></param>
    /// <returns>导入的数据条数</returns>
    public int fillData(DataTable dt)
    {
    int count = 0;
    OleDbCommand dc = Connection.CreateCommand();
    _ErrInfo = "";
    try
    {
    Connection.Open();
    //导入数据
    foreach (DataRow row in dt.Rows)
    {
    string sqlInsert = "insert into " + dt.TableName + "({0}) values({1})";
    string invalues = "";
    string cols = "";
    foreach (DataColumn col in dt.Columns)
    {
    if (row[col].ToString() != string.Empty && row[col].ToString() != null && row[col].ToString() != "null")
    {
    cols += col.ColumnName + ",";
    if (col.DataType == typeof(string))
    {
    invalues += "'" + row[col].ToString() + "',";

    }
    else
    {
    invalues += row[col].ToString() + ",";
    }
    }
    }
    invalues = invalues.Remove(invalues.Length - 1, 1);
    cols = cols.Remove(cols.Length - 1, 1);
    sqlInsert = string.Format(sqlInsert, cols,invalues);
    dc.CommandText = sqlInsert;
    count+= dc.ExecuteNonQuery();
    }
    }
    catch (Exception err)
    {
    _ErrInfo = err.Message;
    }
    finally
    {
    if (Connection != null)
    Connection.Close();
    dc.Dispose();
    }
    return count;
    }

    /// <summary>
    /// 摧毁对象
    /// </summary>
    public void Dispose() {
    if (Connection != null)
    Connection.Dispose();
    }
    }


    这里使用的是Microsoft.Jet.OLEDB.4.0这个驱动,Microsoft.Jet.OLEDB.4.0是一种ACCESS数据库的搜索引擎,但是好像没有装access的电脑上也能用,

    自己写了个测试代码:


    DataTable dt = new DataTable();// 这里是取数据的步骤,
    dt.TableName = "ceshi";// 必须有表名
    DbfExportHelper helper = new DbfExportHelper(@"E:download");
    helper.CreateNewTable(dt);
    helper.fillData(dt);

    注意:

    如果是web后台的方法,当部署在iis上可能无法生成dbf,错误代码为0x80070002;

    解决方法:

    1.打开iis管理器,选择应用程序池

    2.选择建站使用的程序池,我这里选择的是.net 4.0,右键选择高级设置

    3.将启用32位应用程序改为True即可


    ————————————————
    版权声明:本文为CSDN博主「hustchenshu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/dujiajiyiyi/article/details/53841398

  • 相关阅读:
    android ART hook
    Bind Enum to ListControl
    注意WPF中绑定使用的是引用类型
    Android开发第2篇
    Android开发第1篇
    Extension method for type
    DB2实用命令记录
    TDD三大定律
    【InstallShield】 为什么卸载后有的文件没有删掉
    GAC write failed when upgrade with InstallShield
  • 原文地址:https://www.cnblogs.com/xihong2014/p/15351885.html
Copyright © 2011-2022 走看看