三月 30 2009

c#如何读取excel文件

Category: .net ? 刘武 @ 22:11

使用OLEDB可以对excel文件进行读取,我们只要把该excel文件作为数据源即可。

一 在D盘创建excel文件test.xls:

二 将工作表Sheet1的内容读取到DataSet

string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
    "Extended Properties='Excel 8.0'";
DataSet ds = new DataSet();
OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
oada.Fill(ds);

读取的DataSet为:

从图中可以看出excel文件中的第一行变成了DataSet中的列名,这正是系统的默认设置。

三 如果想把第一行也作为数据行,那我们可以给连接字符串添加一个HDR=No属性

如:

string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
    "Extended Properties='Excel 8.0;HDR=No'";
DataSet ds = new DataSet();
OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
oada.Fill(ds);
结果也许会让你有点想不到:

第一行的第一列和第三列都变成空的了,这是因为系统把第一列识别成了数字,把第三列识别成了日期,而第一行的数据不符合格式的要求,所以就变成空的了。

四 我们还可以把所有列都做为字符串来读取,只要添加属性IMEX=1即可

string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
    "Extended Properties='Excel 8.0;HDR=No;IMEX=1'";
DataSet ds = new DataSet();
OleDbDataAdapter oada = new OleDbDataAdapter("select * from [Sheet1$]", strConn);
oada.Fill(ds);
结果又会如何呢?

是不是再次出乎你的意料,第三行的日期怎么变成数字了,其实excel在转换格式的时候就自动把日期变成数字了,那这个数字是怎么来的呢 ? 如果你把日期改成1900年1月1日,那么你可以看到他的转换结果是1,以此类推,39902是哪一天就明白了吧。

五 也许你并不想读取整个excel的内容

如果只想读取前两列可以用:select * from [Sheet1$A:B]

如果只想读取A1到B2的内容,就用:select * from [Sheet1$A1:B2]

六 如果不知道工作表的名字或名字被人为修改了该怎么办呢?

我们可以通过索引来获取指定工作表的名字,以下方法可以用来获取工作表名称的数组:

ArrayList al = new ArrayList();
string strConn;
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:/test.xls;"+
    "Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
DataTable sheetNames = conn.GetOleDbSchemaTable
    (OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
conn.Close();
foreach (DataRow dr in sheetNames.Rows)
{
    al.Add(dr[2]);
}
return al;

Tags: ,

三月 17 2009

在asp.net webservice中如何使用session

Category: asp.net ? 刘武 @ 22:11

在使用asp.net编写webservice时,默认情况下是不支持session的,但我们可以把WebMethod的EnableSession选项设为true来显式的打开它,请看以下例子:

1 新建网站WebSite 

2 新建web服务WebService.asmx,它具有以下两个方法:

[WebMethod(EnableSession = true)]
public string Login(string name)
{
    Context.Session["name"] = name;
    return name;
}

[WebMethod(EnableSession = true)]
public string GetName()
{
    if (Context.Session["name"] != null)
        return Context.Session["name"].ToString();
    else
        return "";
}

3 添加asp.net页面SessionInWebservice.aspx


<form id="form1" runat="server">
    <div>
        <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
        <asp:Button ID="btnLogin" runat="server"
            Text="Login" OnClick="btnLogin_Click" />
    </div>
    <div>
        <asp:Button ID="btnGetName" runat="server"
            Text="GetName" OnClick="btnGetName_Click" />
        <asp:Label ID="lblName" runat="server" Text="Label"></asp:Label>
    </div>
</form>

SessionInWebservice.aspx.cs

protected void btnLogin_Click(object sender, EventArgs e)
{
    WebService ws = new WebService();
   
    ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
    WebService ws = new WebService();
    lblName.Text = ws.GetName();
}

问题似乎到此结束了,按Login按钮记录用户名以后,再按GetName就可以获取到刚才输入的名字。

但如果我们另外新建一个website,并添加web引用来调用刚才编写的webservice,问题就出来了,GeName方法并没有获取到我们刚才登录的用户名(如果是在winform中调用该方法,也会出现同样的问题)。莫非这个方法行不通了?

其实不然,我们给该WebService的CookieContainer赋值就可以了,修改SessionInWebservice.aspx.cs 的代码:

private static System.Net.CookieContainer cookieContainer
    = new System.Net.CookieContainer();

protected void btnLogin_Click(object sender, EventArgs e)
{
    localhost.WebService ws = new localhost.WebService();
    ws.CookieContainer = cookieContainer;
    ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
    localhost.WebService ws = new localhost.WebService();
    ws.CookieContainer = cookieContainer;
    lblName.Text = ws.GetName();
}

请注意:Login方法和GetName方法必须指定同一个CookieContainer,因此在这里我们使用了静态变量。

但如果是在不同的页面中调用该webservice,问题依旧存在,因此我们需要重新修改代码,通过编写新类继承上面的webservice,并给CookieContainer赋值就可以解决该问题了: 

public class WebService1:localhost.WebService
{
    private static System.Net.CookieContainer cookieContainer;

    static WebService1()
    {
        cookieContainer = new System.Net.CookieContainer();
    }

    public WebService1()
    {
        this.CookieContainer = cookieContainer;
    }
}

调用的时候也不需要重新给CookieContainer赋值了:

protected void btnLogin_Click(object sender, EventArgs e)
{
    WebService1 ws = new WebService1();
    ws.Login(txtName.Text);
}
protected void btnGetName_Click(object sender, EventArgs e)
{
    WebService1 ws = new WebService1();
    lblName.Text = ws.GetName();
}

 

Tags: ,

三月 9 2009

利用模态DIV结合UpdateProgress防止页面重复提交

Category: asp.net ? 刘武 @ 22:27

页面在提交的时候可能因为服务器处理慢而导致用户多次重复的点击某个按钮,因此我们需要防止用户这么做,常见的方法是在客户端把该按钮disable掉,但页面处理完或出现错误的时候又需要恢复按钮的状态,这样操作起来往往比较复杂,在atlas页面中,我们可以利用模态DIV和UpdateProgress来实现同样的效果,实现起来也比较简单 。看下面的页面


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>无标题页</title>
    <style type="text/css">
    #modalDiv
    {
        position: absolute;
        top: 0%;
        left: 0%;
        width: 100%;
        height: 100%;
        z-index:1001;
        background-color: black;
        opacity:.60;
        filter: alpha(opacity=10);
    }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" DisplayAfter="0">
            <ProgressTemplate>
                <div id="modalDiv">
                </div>
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Button ID="Submit" runat="server"
                    OnClick="Submit_Click" Text="Submit" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>

Tags: , , , ,

三月 2 2009

怎么获取汉字的拼音缩写

Category: .net ? 刘武 @ 23:36

在google里找到这个方法,还挺实用的,特意收藏,以备以后查看:

/// <summary>
/// 获取中文拼音缩写
/// </summary>
/// <param name="strInput">输入的中文</param>
/// <returns>拼音缩写</returns>


public static string GetPYForShort(string strInput)
{
    string result = "";
    foreach (char c in strInput)
    {
        if ((int)c >= 33 && (int)c <= 126)
        {
            //保留字母和符号
            result += c.ToString();
        }
        else
        {
            result += GetPYChar(c.ToString());
        }
    }
    return result;
}

/// <summary>
/// 取单个字符的拼音声母
/// </summary>
/// <param name="c">要转换的单个汉字</param>
/// <returns>拼音声母</returns>


private static string GetPYChar(string cInput)
{
    byte[] array = new byte[2];
    array = System.Text.Encoding.Default.GetBytes(cInput);
    int i = (short)(array[0] - '\0') * 256 + ((short)(array[1] - '\0'));

    if (i < 0xB0A1) return "*";
    if (i < 0xB0C5) return "a";
    if (i < 0xB2C1) return "b";
    if (i < 0xB4EE) return "c";
    if (i < 0xB6EA) return "d";
    if (i < 0xB7A2) return "e";
    if (i < 0xB8C1) return "f";
    if (i < 0xB9FE) return "g";
    if (i < 0xBBF7) return "h";
    if (i < 0xBFA6) return "g";
    if (i < 0xC0AC) return "k";
    if (i < 0xC2E8) return "l";
    if (i < 0xC4C3) return "m";
    if (i < 0xC5B6) return "n";
    if (i < 0xC5BE) return "o";
    if (i < 0xC6DA) return "p";
    if (i < 0xC8BB) return "q";
    if (i < 0xC8F6) return "r";
    if (i < 0xCBFA) return "s";
    if (i < 0xCDDA) return "t";
    if (i < 0xCEF4) return "w";
    if (i < 0xD1B9) return "x";
    if (i < 0xD4D1) return "y";
    if (i < 0xD7FA) return "z";

    return "*";
}

Tags: ,