我用单例构造了一个读取excel到dataset的类。CExcelHelper,类里面提供如下读取excel到dataset的方法 /// <summary>
/// 将excel中指定sheet内容读入dataset
/// </summary>
/// <param name="fileName">excel文件路径</param>
/// <param name="sheetNames">需从excel中读取的sheet名称</param>
/// <returns></returns>
public DataSet TransExcelToDataSet(string fileName, List<string> sheetNames)
{
OleDbConnection objConn = null;
DataSet data = new DataSet(); try
{
//创建读取excel连接
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
objConn = new OleDbConnection(strConn);
objConn.Open();
OleDbDataAdapter sqlada = new OleDbDataAdapter();
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
sqlada.SelectCommand = objCmd;
//填充dataset
sqlada.Fill(data, sheetName);
}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!"+e.Message);
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
}
return data;
}
在本机使用vs自带开发服务器下,能正常操作。但是发布后放到本机IIS里,就抛出异常。
excel所在目录我已经给了everyone完全控制权限,仍然有异常。
异常信息为: 未指定的错误。
求指点。
在线等。
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";把里面的空格都去掉 string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
我试试。
对了。本机是office2003
Extended Properties='Excel 8.0; HDR=YES; IMEX=1' 这个没有影响吧?
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source="+ fileName
+ ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
objConn = new OleDbConnection(strConn);
objConn.Open();
OleDbDataAdapter sqlada = new OleDbDataAdapter();
try
{
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
sqlada.SelectCommand = objCmd;
//填充dataset
sqlada.Fill(data, sheetName);
}
}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message);
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
}
要写成
fileName = Server.MapPath("~/x.xls")
x.xls放在网站的根目录下
首先谢谢你的回复。
这个肯定是有的,这段代码能够在VS里正常跑。一切操作都很正常,只是放到IIS后,出现问题了。
但是IIS里我又为excel所在的文件夹设置了everyone的完全控制权限,仍然有异常,这是我最郁闷的地方。
版本也要统一。
最好和你开发环境装的一样。
谢谢。
目前我是在本机VS里能正常跑。在本机IIS里跑出现异常了。
如果说环境有改变,那就是开发服务器和IIS的区别了。
+ ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
string strSql = "select * From [" + sheetName.Trim() + "$]";2个变量的内容看都是什么
未指定的错误
fileName: D:\Project\ReportHBSys资料\Publish\DataReceive\RelationData\ImportRelationData\012\201010\核销报表.xls sheetName:
我把try的位置换了下。好像是
objConn.Open();这里产生异常了。
我再发布。
+ "';Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
objConn = new OleDbConnection(strConn);
try
{
objConn.Open();
//OleDbDataAdapter sqlada = new OleDbDataAdapter(); ////遍历从配置文件中读取的sheet名称
//foreach (string sheetName in sheetNames)
//{
// if (!string.IsNullOrEmpty(sheetName))
// {
// sheet = sheetName;
// string strSql = "select * From [" + sheetName.Trim() + "$]";
// OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
// sqlada.SelectCommand = objCmd;
// //填充dataset
// sqlada.Fill(data, sheetName);
// }
//}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message + " fileName: " + fileName + " ; sheetName:" + sheet);
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
}注意看异常捕获的位置。
这说明连接有问题。也就是说,未能读取到excel文件。
可能是权限不够。
异常信息如下:
将excel中指定sheet内容读入dataset出错!
未指定的错误
fileName: D:\Project\ReportHBSys资料\Publish\DataReceive\RelationData\ImportRelationData\012\201010\核销报表.xls ; sheetName: --------------------------------------------------------这里需要说明的是 fileName 路径里的文件是真实存在的。唯一的问题是,应该设置什么权限?
目前的现象表明,所有问题都在 连接 上了。
但是我拼接路径都能访问,为何程序里构建OleDbConnection 却无法读取那个文件呢?
fileName = Server.MapPath("~/DataReceive/RelationData/ImportRelationData/012/201010/核销报表.xls");进行测试,
另外,最好不要使用中文
检查核销报表.xls的安全性设置
-----------------------------------这个设置能否麻烦说得详细点?
这个文件是由用户上传的,路径,文件名称都是根据规则生成的。
/// 读取数据源
/// </summary>
/// <param name="filenameurl"></param>
/// <param name="table"></param>
/// <returns></returns>
public DataSet ExecleDs(string filenameurl, string table)
{
DataSet ds = new DataSet(); try
{
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + filenameurl + ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open(); Microsoft.Office.Interop.Excel.Application objExcelFile = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook objWorkBook;
Microsoft.Office.Interop.Excel._Worksheet objImportSheet;
objExcelFile.DisplayAlerts = false;
objWorkBook = objExcelFile.Workbooks.Open(filenameurl, 0, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
objImportSheet = (Microsoft.Office.Interop.Excel._Worksheet)objWorkBook.Sheets[1];
string tablename = objImportSheet.Name.ToString(); OleDbDataAdapter odda = new OleDbDataAdapter("select * from [" + tablename + "$]", conn);
odda.Fill(ds, table);
conn.Close();
objWorkBook.Close(false, Type.Missing, Type.Missing);
objExcelFile.Quit();
objWorkBook = null;
objImportSheet = null;
objExcelFile.Workbooks.Close();
KillProcess("EXCEL"); GC.Collect(); }
catch (Exception ex)
{
Response.Write(ex.ToString());
}
return ds; }
majic2008
(majic2008)---------------------------多谢。
可能我们的思路不太一样,我是直接将excel中的sheet里的数据读入datatable,所以没有用到com组件,而且由于com组件在开发环境和用户环境上部署太麻烦,所以没有采用。
根据别人指点
加上了 try
{
using(objConn)
{
OleDbDataAdapter sqlada = new OleDbDataAdapter(); //遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
sheet = sheetName;
string strSql = "select * From [" + sheetName.Trim() + "$]";
OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
sqlada.SelectCommand = objCmd;
//填充dataset
sqlada.Fill(data, sheetName);
}
}
}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message + " fileName: " + fileName + " ; sheetName:" + sheet);
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
}
using() 在 sqlada.Fill(data, sheetName);
时产生异常。
服务器是你自己的吗
DataReceive_RelationData_ImportSingleRelationData.ImportData(String companyID, String period) +3252
DataReceive_RelationData_ImportSingleRelationData.DoRequest() +1267
DataReceive_RelationData_ImportSingleRelationData.Page_Load(Object sender, EventArgs e) +5
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +33
System.Web.UI.Control.OnLoad(EventArgs e) +99
System.Web.UI.Control.LoadRecursive() +47
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061
在iis里启用匿名访问,主目录里面设置读取
首先文件是用户上传的。对excel本身的权限设定,是无法完成的。
我启用过everyone用户,给予了完全控制权限,还是异常。
我做过这样的测试,写了另外一个项目来访问我抛异常项目里的那个excel文件,能正常访问。
说明文件本身没有问题。
2个项目的访问方式和代码写的都一样吗?你是http://localhost访问的还是ip访问的》
我直接在B项目里写了绝对路径D:\......来访问那个excel文件的。都是localhost,是为了检验两个问题:
1.IIS是正常的
2.文件是正常的
如果你把文件路径写死之后还有这个VS开发可以IIS发布不行的问题就应该是权限配置的问题。
在服务器上进行设置
打开 控制面板->管理工具->组件服务->计算机->我的电脑->DECOM配置
找到Microsoft Excel 应用程序 进行权限配置主要是安全标签和标识标签。安全标签3个选项都是用自定义将与IIS有关的两个用户(已IIS开头)加入,标识标签选为交互式。
看看有没有Microsoft Excel Sheet 应用程序也需要做相同的配置不然还是会报权限错误。
{
private static CExcelHelper _helper = null; private CExcelHelper()
{ } public static CExcelHelper CreateHelperInstance()
{
if (_helper == null)
{
_helper = new CExcelHelper();
}
return _helper;
} /// <summary>
/// 将excel中指定sheet内容读入dataset
/// </summary>
/// <param name="fileName">excel文件路径</param>
/// <param name="sheetNames">需从excel中读取的sheet名称</param>
/// <returns></returns>
public DataSet TransExcelToDataSet(string fileName, List<string> sheetNames)
{
OleDbConnection objConn = null;
DataSet data = new DataSet(); string sheet = string.Empty; //创建读取excel连接
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
objConn = new OleDbConnection(strConn);
try
{
using (objConn)
{
OleDbDataAdapter sqlada = null;
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
sqlada = new OleDbDataAdapter(strSql, objConn);
//填充dataset
sqlada.Fill(data, sheetName);
sheet = sheetName;
}
}
}
}
catch (Exception e)
{
//throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message + " strConn: " + strConn + " ; sheetName:" + sheet);
throw e;
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
GC.Collect();
}
return data;
}
}
崩溃。
在别的电脑上,情况和我电脑一样,VS里能正常跑,但是部署到IIS后就出异常了。
可以看做是进程未杀掉的原因。
但是我这,第一次访问的时候就抛出那个异常了。
你调试就知道了肯定是objConn.Open();这条出错!!
变通方法有两种
1、在服务器端写读好数据
2、将此excel用System.Diagnostics.Process.Start()打开,再进行读取操作
我试试。Diagnostics.Process.Start();这个需要被什么调用?
无论你是用程序打开还是自己打开都行
using (objConn)
{
System.Diagnostics.Process.Start(fileName);
OleDbDataAdapter sqlada = null;
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
sqlada = new OleDbDataAdapter(strSql, objConn);
//填充dataset
sqlada.Fill(data, sheetName);
sheet = sheetName;
}
}
}页面挂掉了。
/// <summary>
/// 将excel中指定sheet内容读入dataset
/// </summary>
/// <param name="fileName">excel文件路径</param>
/// <param name="sheetNames">需从excel中读取的sheet名称</param>
/// <returns></returns>
public DataSet TransExcelToDataSet(string fileName, List<string> sheetNames)
{
OleDbConnection objConn = null;
DataSet data = new DataSet(); try
{
//创建读取excel连接
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0; HDR=YES; IMEX=1'";
objConn = new OleDbConnection(strConn);
System.Diagnostics.Process.Start(fileName);//加到这里
objConn.Open();
OleDbDataAdapter sqlada = new OleDbDataAdapter();
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
OleDbCommand objCmd = new OleDbCommand(strSql, objConn);
sqlada.SelectCommand = objCmd;
//填充dataset
sqlada.Fill(data, sheetName);
}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!"+e.Message);
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
}
return data;
}
{ objConn = new OleDbConnection(strConn);
System.Diagnostics.Process.Start(fileName);
using (objConn)
{
OleDbDataAdapter sqlada = null;
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
sqlada = new OleDbDataAdapter(strSql, objConn);
//填充dataset
sqlada.Fill(data, sheetName);
sheet = sheetName;
}
}
}
}
catch (Exception e)
{
//throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message + " strConn: " + strConn + " ; sheetName:" + sheet);
throw e;
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
GC.Collect();
}
依然死掉。
那就说明,你对网站的理解还存在不足。用绝对路径去访问excel文件,能输出信息。??说明你的连接字符串还是有问题,没有把相对路径转换成绝对路径。用绝对路径去访问excel文件,能输出信息。那么,你的代码生成的路径跟这个绝对路径是完全一样的吗?
将excel中指定sheet内容读入dataset出错!
未指定的错误
fileName: D:\Project\ReportHBSys资料\Publish\DataReceive\RelationData\ImportRelationData\012\201010\核销报表.xls ; sheetName:(1)把路径中所有的中文去掉。没看到你的filename怎么来的,如果用户上传的,并通过QueryString这样的URL部分进行传输,要进行编码,以避免#这样的符号以及一些中文不能被正确处理。
(2)在IIS中设置应用程序池用户凭据为System试试,以确认是否权限问题。除了文件权限,使用OLE数据引擎,也需要权限。若IIS没有应用程序池,就将ASPNET账号设为管理员组。
A项目发布后得到的路径为path,由于我发布是指定了目录的,所以即使我的文件生成是根据规则来的,但是这时候我仍然可以直接读取这个硬盘上的excel文件。既然我使用绝对路径读取excel能够成功,至少说明A项目本身是没有问题,问题就出在连接字符串上,而连接字符串我们经过异常捕获抛出,可以看到连接字符串里的文件路径和我们的绝对路径是一样的
迷惑。
{
string strConn;
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + FilePath + ";Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
OleDbDataAdapter myCommand = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);
DataSet myDataSet = new DataSet();
try
{
myCommand.Fill(myDataSet);
}
catch (Exception ex)
{
MessageBox.Show("该Excel文件的工作表的名字不正确," + ex.Message);
}
return myDataSet;
}
public DataSet GetUserInfoFromExcel(out string ErrMsg)
{
try
{
ErrMsg = "";
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel files(*.xls)|*.xls"; string conn = Global.g_SqlConnStr;//数据库联接字符串 if (openFileDialog.ShowDialog() == DialogResult.OK)
{
FileInfo fileInfo = new FileInfo(openFileDialog.FileName);
string filePath = fileInfo.FullName;//获取所打开的文件的全路径
//判断当前Excel是否是员工信息的Excel
if (!fileInfo.Name.Contains("内部职员数据"))
{
MessageBox.Show("当前选择的Excel文件不是员工信息文件");
return;
}
string connExcel = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
#region 解决管家导出的excel数据必须打开再保存才能导入的问题
//创建Application对象
Microsoft.Office.Interop.Excel.Application xApp = new Microsoft.Office.Interop.Excel.ApplicationClass(); //xApp.Visible = true;
//得到WorkBook对象, 可以用两种方式之一: 下面的是打开已有的文件
Microsoft.Office.Interop.Excel.Workbook xBook = xApp.Workbooks._Open(filePath,
Missing.Value, Missing.Value, Missing.Value, Missing.Value
, Missing.Value, Missing.Value, Missing.Value, Missing.Value
, Missing.Value, Missing.Value, Missing.Value, Missing.Value); Microsoft.Office.Interop.Excel.Worksheet xSheet = (Microsoft.Office.Interop.Excel.Worksheet)xBook.Sheets[1]; //保存方式一:保存WorkBook
//xBook.SaveAs(filePath,
//Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
//Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value,
//Missing.Value, Missing.Value);
//xSheet = null;
string sheetname = "";
sheetname = xSheet.Name.Trim() + "$";
xBook = null;
xApp.Quit(); //这一句是非常重要的,否则Excel对象不能从内存中退出
xApp = null; #endregion OleDbConnection oleDbConnection = new OleDbConnection(connExcel);
oleDbConnection.Open();//打开数据库连接
//获取excel表
System.Data.DataTable dataTable = oleDbConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); //获取sheet名,其中[0][1]...[N]: 按名称排列的表单元素
//string tableName = dataTable.Rows[0][2].ToString().Trim();
string tableName = sheetname.Trim();
tableName = "[" + tableName.Replace("'", "") + "]"; //利用SQL语句从Excel文件里获取数据
string query = "SELECT * FROM " + tableName;
DataSet dataSet = new DataSet();
OleDbDataAdapter oleAdapter = new OleDbDataAdapter(query, connExcel);
oleAdapter.Fill(dataSet, "Employee_Info");
return dataSet;
}
}
catch (Exception ex)
{
ErrMsg = ex.Message;
}
}
/// <summary>
/// 读取excel到dataset里显示
/// </summary>
/// <returns></returns>
private DataSet excelToDataset()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = Application.ExecutablePath;
ofd.Filter = "电子表格文件(*.xls *xlsx)|*.xls;*.xlsx";
ofd.FilterIndex = 1;
ofd.RestoreDirectory = true; OleDbConnection objConn = null;
System.Data.DataTable dt = null;
OleDbDataAdapter myCommand = null;
DataSet ds = null;
if (ofd.ShowDialog() == DialogResult.OK)
{
this.txtFileName.Text = ofd.FileName;
this.lblNumber.Visible = true;
try
{
//string connString = "Provider=Microsoft.Ace.OleDb.12.0;" + "Data Source=" + ofd.FileName + ";" + "Extended Properties=Excel 12.0;";
//string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ofd.FileName + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"";
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ofd.FileName + ";Extended Properties='Excel 8.0;IMEX=1'"; objConn = new OleDbConnection(connString);
objConn.Open();
dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }); //获得excel中的表
if (dt != null)
{
string strExcel = "select * from [" + lst[0] + "]";
ds = new DataSet();
myCommand = new OleDbDataAdapter(strExcel, objConn);
myCommand.Fill(ds, "table1");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return ds;
}
http://topic.csdn.net/u/20101110/15/2a9e68db-9082-4891-8174-a9ae4e22d2b9.html
使用这个插件实现了我想要的功能。
但是,我自己写的使用驱动读取excel的功能始终有异常。这让我心理很不爽。
帖子我暂时不会关闭,等更多人来围观,也请大家继续指点!不过,分,到时候我会发给大家的!
thank you!
{
OleDbConnection objConn = null;
DataSet data = new DataSet(); //创建读取excel连接
string strConn = "Provider=Microsoft.Jet.OleDb.4.0;" + "data source=" + fileName
+ ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
try
{ objConn = new OleDbConnection(strConn);
using (objConn)
{
OleDbDataAdapter sqlada = null;
//遍历从配置文件中读取的sheet名称
foreach (string sheetName in sheetNames)
{
if (!string.IsNullOrEmpty(sheetName))
{
string strSql = "select * From [" + sheetName.Trim() + "$]";
sqlada = new OleDbDataAdapter(strSql, objConn);
//填充dataset
sqlada.Fill(data, sheetName);
}
}
}
}
catch (Exception e)
{
throw new Exception("将excel中指定sheet内容读入dataset出错!" + e.Message + " strConn: " + strConn + " ; fileName:" + fileName);
//throw e;
}
finally
{
if (objConn != null)
{
objConn.Dispose();
objConn.Close();
}
GC.Collect();
}
return data;
}
这个excel我在当前项目中用绝对路径的方式访问,然后输出过一个时间,证明excel是正常的
SHEETNAME明显错了啊 输出的应该是strConn: Provider=Microsoft.Jet.OleDb.4.0;Persist Security Info=False;data source=D:\Project\ReportHBSysPublish\DataReceive\RelationData\ImportRelationData\012\201010\核销报表.xls;Extended Properties='Excel 8.0;HDR=YES;IMEX=1' ; sheetName:核销报表
这个样子才对