Returning Excel Spreadsheet as web page

G

Guest

Hello

I am trying to return the contents of an Excel file. However, I don't want to just redirect the request to the Excel file since it does not reside in a location where that is appropriate. I am trying to write the contents of the file to the response but am having trouble. My code resides in the handler for a link-button's click event

Response.ClearHeaders()
Response.ClearContent()
Response.ContentType = "application/vnd.ms-excel"
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename + ".XLS")
Response.WriteFile(path)
Response.Flush()
Response.End()

This almost works. When I run it, I get two dialog boxes asking if I want to open or save filename.xls. If I click 'Open' on both, Excel opens up (external from the browser) with the file in it. When I take out the "attachment" designation in the header, I only get 1 dialog box but, if I click 'Open', it ends up displaying the login page of my site in Excel within my browser --- I assume that it is failing some kind of security check or it is being interrpreted as an unauthenticated user at that point

What am I doing wrong? I don't like the two dialog boxes I receive with the code above (and I am sure one of them is resulting in the same behavior of returning the start-page which isn't so good). And, I would prefer that Excel open embedded in the browser instead of in stand-alone mode (although, at this point I would take either behvaior to avoid the second dialog box)

Thanks for any assistance!
 
S

Scott

You aren't doing anything wrong; The only work around I know of, is to change your code and not do a Content-Disposition (and rework via a redirect). The sample code below generates the double open. There was a discussion in this group a few weeks ago; I think the last idea was that this is a bug in IE....

Scott

<%@ Page language="c#" AutoEventWireup="false" %>
<script language="C#" runat="server">
public void Btn1_Click(object sender, System.EventArgs e)
{
string content = "Hello";
Response.Clear();
Response.ClearHeaders();
Response.Charset = "";
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=HelloWorld.csv");
Response.AddHeader("Content-Length", content.Length.ToString());
Response.Write(content);
Response.Flush();
Response.End();
}
</script>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button id="Btn1" runat="server" Text="Button" onclick="Btn1_Click"></asp:Button>
</form>
</body>
</html>
Hello,

I am trying to return the contents of an Excel file. However, I don't want to just redirect the request to the Excel file since it does not reside in a location where that is appropriate. I am trying to write the contents of the file to the response but am having trouble. My code resides in the handler for a link-button's click event:

Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename=" + filename + ".XLS");
Response.WriteFile(path);
Response.Flush();
Response.End();

This almost works. When I run it, I get two dialog boxes asking if I want to open or save filename.xls. If I click 'Open' on both, Excel opens up (external from the browser) with the file in it. When I take out the "attachment" designation in the header, I only get 1 dialog box but, if I click 'Open', it ends up displaying the login page of my site in Excel within my browser --- I assume that it is failing some kind of security check or it is being interrpreted as an unauthenticated user at that point.

What am I doing wrong? I don't like the two dialog boxes I receive with the code above (and I am sure one of them is resulting in the same behavior of returning the start-page which isn't so good). And, I would prefer that Excel open embedded in the browser instead of in stand-alone mode (although, at this point I would take either behvaior to avoid the second dialog box).

Thanks for any assistance!
 
S

Steven Cheng[MSFT]

Hi Keith,

From your description, you encountered some problems when trying to display
a excel file to the reponse of a certain asp.net web page to client, yes?

1. As for the first problem, this seems a known behavior I've also met
before. When we put the code in a button's post back event handler, then
when the page return back, the file download dialog will popup twice. If I
put the the code in page_load instead, if will work ok without the popup
twice problem. You may have a try to confirm this, also I think this maybe
a potential workaround. How do you think ?

2. As for the problems that display "login page" rather than excel, I'd
like to confirm some further things:
1) Are you using FormsAuthentication in your asp.net web application. It
seems that you're redirect to the login page when accessing the excel file.

2). If 1) is right, then have you set authorize protection on the certain
excel files, if so ,I think you can try write a certain excel file which is
not protected (can be accessecd by unauthenticated user who hasn't login
yet). Then run the code a gain to see whether the problem is due to the
form authentication.

Please have a try and wish you good luck! Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
S

Steven Cheng[MSFT]

Hi Keith,

Have you had a chance to check out the suggestions in my last reply or have
you got any further ideas on this issue? If you have anything unclear or if
there're anything else we can help, please feel free to post here. Thanks.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 
G

Guest

Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
S

Scott G.

You could grab the control (button) id and check the postback data; however, the 1st suggestion (sending the file back in the Page_Load) doesn't solve the problem -- I can post a sample that sends a file in Page_Load and IE still does the two dialog thing.

Scott
Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround.

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this.

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
B

Brian Orrell

If you have one button you want to cause the Excel output, make the button's event set a boolean member variable to true. Then override the Render method, and if the variable is true, send the Excel output from there, otherwise, render like normal.

-Brian Orrell
MethodExperts, LLC
(e-mail address removed)

You could grab the control (button) id and check the postback data; however, the 1st suggestion (sending the file back in the Page_Load) doesn't solve the problem -- I can post a sample that sends a file in Page_Load and IE still does the two dialog thing.

Scott
Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround.

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this.

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
S

Scott G.

Interesting idea; but this has the same problem as all of the rest of the solutions. Here's a sample that has your idea and generates two open dialog boxes on my machine.

Scott

<%@ Page language="c#" AutoEventWireup="false" trace="true" %>
<script language="C#" runat="server">
bool m_sendCSV = false;
public void Btn1_Click(object sender, System.EventArgs e)
{
m_sendCSV = true;
}

private void SendCSV()
{
string content = "Hello";
Response.Clear();
Response.ClearHeaders();
Response.Charset = "";
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=HelloWorld.csv");
Response.AddHeader("Content-Length", content.Length.ToString());
Response.Write(content);
Response.Flush();
Response.End();
}

protected override void Render(HtmlTextWriter w)
{
if (m_sendCSV)
{
SendCSV();
}
else
{
base.Render(w);
}
}
</script>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button id="Btn1" runat="server" Text="Button" onclick="Btn1_Click"></asp:Button>
</form>
</body>
</html>
If you have one button you want to cause the Excel output, make the button's event set a boolean member variable to true. Then override the Render method, and if the variable is true, send the Excel output from there, otherwise, render like normal.

-Brian Orrell
MethodExperts, LLC
(e-mail address removed)

You could grab the control (button) id and check the postback data; however, the 1st suggestion (sending the file back in the Page_Load) doesn't solve the problem -- I can post a sample that sends a file in Page_Load and IE still does the two dialog thing.

Scott
Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround.

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this.

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
B

Brian Orrell

I ran your example and it worked just fine.

I put three buttons on the page. With only one causing an Excel sheet to open, the other two just caused changes to the screen. Worked great. What do you mean by two dialog boxes?


Interesting idea; but this has the same problem as all of the rest of the solutions. Here's a sample that has your idea and generates two open dialog boxes on my machine.

Scott

<%@ Page language="c#" AutoEventWireup="false" trace="true" %>
<script language="C#" runat="server">
bool m_sendCSV = false;
public void Btn1_Click(object sender, System.EventArgs e)
{
m_sendCSV = true;
}

private void SendCSV()
{
string content = "Hello";
Response.Clear();
Response.ClearHeaders();
Response.Charset = "";
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=HelloWorld.csv");
Response.AddHeader("Content-Length", content.Length.ToString());
Response.Write(content);
Response.Flush();
Response.End();
}

protected override void Render(HtmlTextWriter w)
{
if (m_sendCSV)
{
SendCSV();
}
else
{
base.Render(w);
}
}
</script>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button id="Btn1" runat="server" Text="Button" onclick="Btn1_Click"></asp:Button>
</form>
</body>
</html>
If you have one button you want to cause the Excel output, make the button's event set a boolean member variable to true. Then override the Render method, and if the variable is true, send the Excel output from there, otherwise, render like normal.

-Brian Orrell
MethodExperts, LLC
(e-mail address removed)

You could grab the control (button) id and check the postback data; however, the 1st suggestion (sending the file back in the Page_Load) doesn't solve the problem -- I can post a sample that sends a file in Page_Load and IE still does the two dialog thing.

Scott
Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround.

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this.

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
S

Scott G.

Read the first message in the thread; there have been a couple of threads on this in the last month. In IE, when one uses the Content-Disposition attachment you'll get two Open dialog boxes before Excel opens. This doesn't happen everywhere, but it definately happens for about 40% of our customers....

The last I worked on this I was convinced it is a bug in IE; but I'm still open to ideas.

Scott
I ran your example and it worked just fine.

I put three buttons on the page. With only one causing an Excel sheet to open, the other two just caused changes to the screen. Worked great. What do you mean by two dialog boxes?


Interesting idea; but this has the same problem as all of the rest of the solutions. Here's a sample that has your idea and generates two open dialog boxes on my machine.

Scott

<%@ Page language="c#" AutoEventWireup="false" trace="true" %>
<script language="C#" runat="server">
bool m_sendCSV = false;
public void Btn1_Click(object sender, System.EventArgs e)
{
m_sendCSV = true;
}

private void SendCSV()
{
string content = "Hello";
Response.Clear();
Response.ClearHeaders();
Response.Charset = "";
Response.ContentType = "application/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=HelloWorld.csv");
Response.AddHeader("Content-Length", content.Length.ToString());
Response.Write(content);
Response.Flush();
Response.End();
}

protected override void Render(HtmlTextWriter w)
{
if (m_sendCSV)
{
SendCSV();
}
else
{
base.Render(w);
}
}
</script>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Button id="Btn1" runat="server" Text="Button" onclick="Btn1_Click"></asp:Button>
</form>
</body>
</html>
If you have one button you want to cause the Excel output, make the button's event set a boolean member variable to true. Then override the Render method, and if the variable is true, send the Excel output from there, otherwise, render like normal.

-Brian Orrell
MethodExperts, LLC
(e-mail address removed)

You could grab the control (button) id and check the postback data; however, the 1st suggestion (sending the file back in the Page_Load) doesn't solve the problem -- I can post a sample that sends a file in Page_Load and IE still does the two dialog thing.

Scott
Thanks for your feedback, but, I haven't got this settled quite yet. If I can get your first suggestion to work, I think it would be a fine resolution, but, I am not sure how. I write the Excel file into the response in the handler for the link-button because there are multiple buttons which could be pressed which will result in different behavior. Is there a way, in the page-load event, to determine which submit button was clicked to post the form? I took a look but didn't see anything obvious. If there is a way of, basically, handling the click during page-load, I think I can go with your workaround.

For your second question, you assumed correctly that I am using forms authentication. I did try changing the permissions on the file and received the same results. I don't see how this approach could work, though. Does this statement "Response.WriteFile(path);" require the file to be accessible by the unauthenticated user? I would have assumed that as long as the ASPNET user which is executing the code can open the file and put the contents into the response, the security of the user would not enter the picture. Let me know if I am missing something on this.

Thanks for you help --- let me know if you have any other ideas. For the time being, I am probably going to accept that there are 2 dialog boxes.
 
S

Steven Cheng[MSFT]

Hi,

Yes, this problem has been mentioned in the newsgroup. And I've also
consult some experts and confirm t hat this is a known issue of IE. The
problem occurs when the request is send as "post" method, and not occur
when we use get method. Unfortunately the problem won't be fixed currently
and we need to wait the longhorn version. So I'm sorry for any
inconvenience brings to you who has suffer the issue. Thanks for your
understanding.

Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Get Preview at ASP.NET whidbey
http://msdn.microsoft.com/asp.net/whidbey/default.aspx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top