首页 > 编程语言 >【C#】System.Data.OleDb操作Excel

【C#】System.Data.OleDb操作Excel

时间:2022-09-26 15:46:49浏览次数:45  
标签:OleDb C# cmd Excel new Data ds string

一、DataTable导入导出Excel

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApplication1.UserClass
{
    class FileHelper
    {
        /// <summary>
        /// Excel导出为DataSet
        /// </summary>
        public static DataSet ExcelToDs(string Path)
        {
            string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Path + ";" + "Extended Properties=Excel 8.0;";
            //string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Path + ";" + "Extended Properties=Excel 8.0;HDR=False;IMEX=1";
            OleDbConnection conn = new OleDbConnection(strConn);
            conn.Open();
            string strExcel = "";
            OleDbDataAdapter myCommand = null;
            DataSet ds = null;
            strExcel = "select * from [sheet1$]";
            myCommand = new OleDbDataAdapter(strExcel, strConn);
            ds = new DataSet();
            myCommand.Fill(ds, "table1");
            return ds;
        }

        /// <summary>
        /// Excel导出为DataTable
        /// </summary>
        public DataTable ExcelToDataTable(string Path)
        {
            string connStr = "";
            string fileType = System.IO.Path.GetExtension(Path);
            if (string.IsNullOrEmpty(fileType)) return null;

            if (fileType == ".xls")
                connStr = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Path + ";" + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";
            else
                connStr = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + Path + ";" + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"";
            string sql_F = "Select * FROM [{0}]";

            DataSet ds = new DataSet();

            OleDbConnection conn = null;
            OleDbDataAdapter da = null;
            DataTable dtSheetName = null;
            try
            {
                // 初始化连接,并打开
                conn = new OleDbConnection(connStr);
                conn.Open();

                // 获取数据源的表定义元数据                        
                string SheetName = "";
                dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

                // 初始化适配器
                da = new OleDbDataAdapter();
                for (int i = 0; i < dtSheetName.Rows.Count; i++)
                {
                    SheetName = (string)dtSheetName.Rows[i]["TABLE_NAME"];

                    if (SheetName.Contains("$") && !SheetName.Replace("'", "").EndsWith("$"))
                    {
                        continue;
                    }

                    da.SelectCommand = new OleDbCommand(String.Format(sql_F, SheetName), conn);
                    DataSet dsItem = new DataSet();
                    da.Fill(dsItem);

                    ds.Tables.Add(dsItem.Tables[0].Copy());
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                // 关闭连接
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                    da.Dispose();
                    conn.Dispose();
                }
            }
            return ds.Tables[0];
        }

        /// <summary>
        /// 将DataTable数据保存为Excel文件
        /// </summary>
        public bool SaveToExcel(DataTable dt)
        {
            string Path = SaveDialog("(*.xls)|*.xls");

            bool success = true;
            string connStr = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + Path + ";Extended Properties=Excel 8.0;";//仅支持2003格式的Excel
            OleDbConnection conn = new OleDbConnection(connStr);
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            try
            {
                conn.Open();
                string cmdText = "Create Table sheet1 (";

                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    string columnName = dt.Columns[i].ColumnName;
                    cmdText += " " + columnName;
                    string typeName = GetExcelMapDataType(dt.Columns[i].DataType.Name);
                    cmdText += " " + typeName;
                    if (i == dt.Columns.Count - 1)
                    {
                        cmdText += ")";
                    }
                    else
                    {
                        cmdText += ",";
                    }
                }

                cmd.CommandText = cmdText;
                cmd.ExecuteNonQuery();

                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    cmdText = "Insert into sheet1 values (";
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        string columnName = dt.Columns[j].ColumnName;
                        cmdText += "@" + columnName;
                        cmd.Parameters.AddWithValue("@" + columnName, dt.Rows[i][columnName]);
                        if (j == dt.Columns.Count - 1)
                        {
                            cmdText += ")";
                        }
                        else
                        {
                            cmdText += ",";
                        }
                    }
                    cmd = new OleDbCommand(cmdText, conn);
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        string columnName = dt.Columns[j].ColumnName;
                        string columnType = dt.Columns[j].DataType.Name;
                        if (columnType.ToLower() == "datetime")
                        {
                            OleDbParameter pm = new OleDbParameter();
                            pm.ParameterName = "@" + columnName;
                            pm.OleDbType = OleDbType.Date;
                            pm.Value = dt.Rows[i][columnName];
                            cmd.Parameters.Add(pm);

                            continue;
                        }
                        cmdText += "@" + columnName;
                        cmd.Parameters.AddWithValue("@" + columnName, dt.Rows[i][columnName]);
                    }

                    cmd.ExecuteNonQuery();
                }



            }
            catch (Exception ex)
            {

            }
            finally
            {
                conn.Close();
                conn.Dispose();
            }
            return success;
        }

        /// <summary>
        /// 保留单元格格式导出
        /// </summary>
        static string GetExcelMapDataType(string dataType)
        {
            string result = dataType;
            switch (dataType.ToLower())
            {
                case "int":
                case "int32":
                    result = "INTEGER";
                    break;
                case "datetime":
                    result = "DATE";
                    break;
                case "boolean":
                    result = "bit";
                    break;
                default:
                    break;
            }

            return result;
        }

        /// <summary>
        /// 将DataSet数据保存为Excel文件
        /// </summary>
        public bool DataSetToExcel(DataSet ds)
        {
            string Path = SaveDialog("(*.xls)|*.xls");
            string strCon = string.Empty;
            FileInfo file = new FileInfo(Path);
            string extension = file.Extension;
            switch (extension)
            {
                case ".xls":
                    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path + ";Extended Properties=Excel 8.0;";
                    break;
                case ".xlsx":
                    strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Path + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=0;'";
                    break;
                default:
                    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Path + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=0;'";
                    break;
            }
            try
            {
                using (System.Data.OleDb.OleDbConnection con = new System.Data.OleDb.OleDbConnection(strCon))
                {
                    con.Open();
                    StringBuilder strSQL = new StringBuilder();
                    System.Data.OleDb.OleDbCommand cmd;
                    try
                    {
                        for (int i = 0; i < ds.Tables.Count; i++)
                        {
                            cmd = new System.Data.OleDb.OleDbCommand(string.Format("drop table {0}", ds.Tables[i].TableName), con);    //覆盖文件时可能会出现Table 'Sheet1' already exists.所以这里先删除了一下
                            cmd.ExecuteNonQuery();
                        }

                    }
                    catch
                    {
                        return false;
                    }
                    //创建表格字段
                    for (int i = 0; i < ds.Tables.Count; i++)
                    {
                        strSQL.Clear();
                        strSQL.Append("CREATE TABLE ").Append("[" + ds.Tables[i].TableName + "]");
                        strSQL.Append("(");

                        for (int j = 0; j < ds.Tables[i].Columns.Count; j++)
                        {
                            strSQL.Append("[" + ds.Tables[i].Columns[j].ColumnName + "] text,");
                        }
                        strSQL = strSQL.Remove(strSQL.Length - 1, 1);
                        strSQL.Append(")");

                        cmd = new System.Data.OleDb.OleDbCommand(strSQL.ToString(), con);
                        cmd.ExecuteNonQuery();

                        //添加数据
                        for (int k = 0; k < ds.Tables[i].Rows.Count; k++)
                        {
                            strSQL.Clear();
                            StringBuilder strvalue = new StringBuilder();
                            for (int j = 0; j < ds.Tables[i].Columns.Count; j++)
                            {
                                strvalue.Append("'" + ds.Tables[i].Rows[k][j].ToString() + "'");
                                if (j != ds.Tables[i].Columns.Count - 1)
                                {
                                    strvalue.Append(",");
                                }
                                else
                                {
                                }
                            }
                            cmd.CommandText = strSQL.Append(" insert into [" + ds.Tables[i].TableName + "] values (").Append(strvalue).Append(")").ToString();
                            cmd.ExecuteNonQuery();
                        }
                    }
                    con.Close();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
    }
}
 

 

二、读取Excel单元格字符串截断问题

1、问题描述:
表格某一单元格内容过长,则上位机读取Excel表时,字符串将被截断,导致数据缺失,对后续数据处理造成错误。

2、问题分析:
目前微软提供了两种Office Ole驱动来实现数据库连接,分别为ACE版本和Jet版本。由于Jet引擎只可以访问 Office 97-2003,故上位机代码中采用了调用Microsoft.ACE.OLEDB.12.0驱动的方式,利用Microsoft ACE引擎连接到工作簿,将Excel文件作为数据源来读写。

而OleDb读取文件的方式受Excel ISAM(Indexed Sequential Access Method,即索引顺序存取方法)驱动程序的限制。在读取过程中,Excel ISAM 驱动程序通过扫描sheet中前几行(默认为8行)的内容来确定一个 Excel列的最合适的数据类型,然后选择能够代表其样本中大部分值的数据类型,分配存储大小。该数据类型通常为varchar,其大小为255字符。而实际使用中,常常会出现该列前8行字符串在255个字符以内,8行以外的字符串却大于255个字符的情况,那么这个时候使用OleDb读取Excel就会将后面大于255的字符串截断。

3、改善措施与验证结果:
经翻查资料,得到的解决方案为,通过修改注册表值来更改采样行数。修改路径如下(Excel 2016):
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engines\Excel
TypeGuessRows取值范围为0-16。当TypeGuessRows = 0时会扫描整个页面再匹配合适的数据类型。但试验后发现,该方法只适用于Jet引擎,对于使用ACE引擎的上位机,该方法无效。
在不修改表格读取方式的情况下,一个可以实现字符串正常读取的措施是,把数据大于255的表格放到前8行。在前8行的判定中,数据已经超过255,则该列的数据类型会被设定得更大,就不会出现截断的情况。
由于该方法会增加额外的工作量,不宜作为永久措施。目前的最佳方案是修改文件读取方式,用NPOI方法读取Excel表格。该方法不受ISAM驱动程序限制,可以保证字符串的完整性,同时可以满足读取高版本Excel文件的需求。
经调试,可以确保该方法能够完整读取单元格长度远大于255的字符串。

4、总结:
在处理单一、长度较短的表格时,可以优先选择OleDb方式对表格进行读取;若每一单元格包含的数据类型较为复杂,则推荐在编写上位机时使用NPOI方法读取表格,保证数据处理的可靠性。

 

标签:OleDb,C#,cmd,Excel,new,Data,ds,string
From: https://www.cnblogs.com/Mars-0603/p/16731148.html

相关文章

  • 466Class对象功能_获取Constructor和467反射_Class对象功能_获取Method
    Class对象功能_获取ConstructorConstructor<?>[]getConstructors()Constructor<T>getConstructor(Class<?>...parameterTypes) Constructor<?>[]getDeclaredConst......
  • 464Class对象功能概述和465Class对象功能_获取Field
    Class对象功能概述publicstaticvoidmain(String[]args)throwsException{//获取Person的Class对象ClasspersonClass=Person.class;......
  • 好路径数目-Leetcode6191
    好路径数目题目描述给你一棵n个节点的树(连通无向无环的图),节点编号从0到n-1且恰好有n-1条边。给你一个长度为n下标从0开始的整数数组vals,分别表示每......
  • 【code基础】 List<List<Integer>>
    刷题过程中会遇到List<List>的数据结构,以下展示定义和操作的过程@TestpublicvoidListTest(){List<List<Integer>>res=newArrayList<>();Sy......
  • Win10家庭版启用组策略gpedit.msc
    大家都认为,Windows10家庭版中并不包含组策略,其实不然,它是有相关文件的,只是不让你使用而已。那么我们让系统允许你使用就好了。【操作步骤】1、首先你需要在桌面上新建一个......
  • RocketMQ性能优化【实战笔记】
    转发:https://cloud.tencent.com/developer/article/1496414目录一、系统优化1.最大文件数2.系统参数调整二、RocketMQ性能调优1.开启异步刷盘2.开启堆外内存设置3......
  • 第一个springmvc项目
    第一个SpringMVC项目1、使用配置(实际开发不使用)新建一个Module:springmvc-02-hello,添加web支持导入springmvc依赖<dependency><groupId>org.springframework......
  • SpringCloud微服务架构(二)
    nacos配置管理1.在nacos中添加配置信息2.在弹出表单中填写配置信息3.配置获取的步骤如下4.配置的步骤如下:1)引入Nacos的配置管理客户端依赖<!--nacos配置管理依......
  • elasticsearch:NoNodeAvailableException[None of the configured nodes are available
    NoNodeAvailableException[Noneoftheconfigurednodesareavailable:[{#transport#-1}{9L7K2EanQGSxD5aAmbzAIw}{localhost}{127.0.0.1:9200}]]这里显示无可用节点......
  • Spring MVC框架:第十一章:Ajax
    AjaxAjax程序和服务器数据传输在进行Ajax操作时,SpringMVC会需要将JSON数据和Java实体类进行相互转换,为了实现这个效果需要额外加入jackson-all-1.9.11.jar1.从浏览器发......