Opening a web page as an Excel file, but with .xlsx files - asp.net

Okay, this might be a bit unusual. If there are better ways to do this (that are just as easy, I'm open to ideas). I found a while ago that I could open a web page consisting of a Gridview or a table, with titles, etc. as an excel file and it worked great! It formatted the Excel file with colors and alignment similar to the html from the page. With later versions of excel, though, it gives me a warning that the format time isn't valid before opening it, though it still seemed to work. So I tried changing the content type to a more current version of excel, but then I don't get anything at all. Here's what I have been doing (below).
Does anyone know how to change it so that I can open the page in a current version of Excel without getting the warning?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Response.AppendHeader("Content-disposition", "attachment; filename=Filename.xls")
Response.ContentType = "application/vnd.ms-excel"
End Sub

You are not creating an Excel file.
You are creating a HTML file with a .xls file extension. That's the wrong extension for a HTML file, and that's why Excel gives you a warning. The correct extension would be .html or .htm. Unfortunately, .html files don't automatically open in Excel, so changing the extension would require your users to manually open the file in Excel instead of just double-clicking it.
I'm afraid there's no easy way to solve this. We had the same problem, and we solved it by creating a real Excel file. There are lots of Excel libraries for .NET available. We used SpreadsheetLight, because it easily allows you to copy a DataTable to an Excel file and send that file to the web client.

Related

Excel Found unreadable content, Do you want to recover contents of this workbook. exporting from RDLC

When trying to Export RDLC as EXCEL(xlsx) using ReportViewer from backend,
Excel is throwing
"Excel Found unreadable content, Do you want to recover contents of this workbook".
I tried to rename the file type as zip and extract the contents and tried to modify xml(just introduced new line after first tag
).
Then followed by Zip and rename to XLSX. which resolved the issue and excel opened without any message.
How to resolve the issue?
Went through many posts which did not solve the actual cause.
I have even tried with Blank RDLC Report. which did not resolve the issue , which shows the issue is not with Report Data. The same is working fine with XLS type.
Thanks in Advance.
Finally found a solution:
As per available code online for downloading RDLC Report from backend,Response is handled badly and forgot to end the response which lead to corrupted file and above error.
Just included Response.End(); at the end and the issue is resolved.

Visual Basic Download Not Doing Anything On Completion

My other issue was with a bigger file made dynamically but now I'm just doing a small, already existing text file to try and get this concept working at least.
I'm attempting to download a file when the user clicks on the button but after the Response lines run nothing seems to download nor does the browser recognize a possible download. I've stepped through it as well as it just goes through every line but the front end no download file begins or prompted for. The file is currently in the bin file of the project and I've also tried just in my own local downloads file. Just contains "hello" nothing major.
The asp:
<asp:button id = "Button1" Class="button" text = "TEST" runat = "server" />
And the vb
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fileToDownload = Server.MapPath("~/bin/test.txt")
Response.ContentType = "text/plain"
Response.AppendHeader("Content-Disposition", "attachment; filename=test.txt")
Response.TransmitFile(fileToDownload)
Response.Flush()
Response.End()
I've tried the response lines in different orders, as well as just using flush or just end. This is just a tempt file of course as the bigger scheme is to dynamically create and excel file and download that to the user.
edit: sry, i just tried your code as-is and it worked on my machine. i'm using firefox. i've seen some long articles about dealing with internet explorer. any chance you're using that?
original post:
can a file be downloaded from bin? just a thought.
also, try removing Response.Flush() and see if that helps. i think Response.End takes care of that - when everything is actually done.

Output Web Page as DOCX?

In the past, if I wanted a web page to display as a .DOC word document, I could do so by doing this in the page load:
Response.AddHeader("content-disposition", "attachment;filename=FullDetail.doc")
Response.ContentType = "application/vnd.word"
I was hoping to output the web page as a .DOCX by doing:
Response.AddHeader("content-disposition", "attachment;filename=FullDetail.docx")
Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
but it doesn't work. I get an error:
The file FullDetail.docx cannot be opened because there are problems with the contents. The file is corrupt and cannot be opened.
The contents of both files look pretty much identical - just an HTML page.
HR Full Detail Report
etc...
The .doc opens fine. The .docx doesn't. If I rename the .docx to .doc, it opens fine in Word 2010. Any suggestions? 
Thanks!
Brad
A docx file is actually a zip file that contains several other files. For example, create a new MS Word doc, put the text "Hello world" in it and save it (example.docx). Then rename the docx file to "example.zip" and open it. You will see that a the content is much more complicated than you might have expected.
Most people find that it is much easier to generate a Word XML file (https://msdn.microsoft.com/en-us/library/bb266220(v=office.12).aspx) or use an API for generating a real docx file (for instance: http://docx.codeplex.com/).

Trouble Understanding Code to Export Excel Spreadsheet from HTML

I have been asked to make changes to an ASP.NET WebForms application written in VB (I normally use C#).
One task is to try and fix an Excel download. The client reported that he gets an error about the spreadsheet being corrupt when he attempts to open it in Excel.
The code that exports the Excel download appears in the Load event of a dedicated ASPX page. And looks something like this:
Dim mytable As New HtmlTable
mytable = [Populate HTML Table Here]
mytable = returnclass.displaytable
mytable.Border = 1
mytable.BorderColor = "#CCCCCC"
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.Buffer = True
Response.Write("<html xmlns:x=""urn:schemas-microsoft-com:office:excel"">")
Response.Write("<head>")
Response.Write("<!--[if gte mso 9]><xml>")
Response.Write("<x:ExcelWorkbook>")
Response.Write("<x:ExcelWorksheets>")
Response.Write("<x:ExcelWorksheet>")
Response.Write("<x:Name>" & worksheetTitle & "</x:Name>")
Response.Write("<x:WorksheetOptions>")
Response.Write("<x:Print>")
Response.Write("<x:ValidPrinterInfo/>")
Response.Write("</x:Print>")
Response.Write("</x:WorksheetOptions>")
Response.Write("</x:ExcelWorksheet>")
Response.Write("</x:ExcelWorksheets>")
Response.Write("</x:ExcelWorkbook>")
Response.Write("</xml>")
Response.Write("<![endif]--> ")
Response.Write("</head>")
Response.Write("<body>")
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=hhexport.xls ")
HttpContext.Current.Response.Charset = ""
'ouput table to html so excel can interperet.
Me.EnableViewState = False
Dim stringWriter As New System.IO.StringWriter()
Dim htmlWriter As New System.Web.UI.HtmlTextWriter(stringWriter)
mytable.RenderControl(htmlWriter)
HttpContext.Current.Response.Write(stringWriter.ToString)
I really don't understand what this is trying to do.
Questions:
The code produces a regular ASP.NET HtmlTable and assigns it to mytable. On what planet can Excel open HTML?
I'm really kind of loss by the XML in general here, and by the <!--[if gte mso 9] comment. Can anyone help me understand what is going on here.
The result appears valid but I'm just not familiar with what the intent is here. Any tips appreciated.
EDIT
On further testing, the problem seems related to the extension given to the file (xls). The current version of Excel will go ahead and load the file if I indicate that. But all formatting is lost. Any suggestions on what type of file this would be?
EDIT
And it looks like the original author got the idea from here, although that page doesn't really describe what is happening.
UPDATE
Thanks for everyone's response. I will credit those replies according to how they addressed the questions above. However, for my purposes the code appears to have worked all along. It just appears that newer versions of Excel now warn the user that an XLS file that contains HTML is a file of a different type than suggested by the file extension. And it appears there is nothing that can be done about this except for exporting using CSV, OpenXML or some other approach. I found more details in this blog.
The code basically wraps an HTML table in some special XML tags that relate to Excel (defining a Workbook and Worksheets, etc). This is supposed to allow the output to be opened by either Excel or a browser.
To answer your questions:
The code produces a regular ASP.NET HtmlTable and assigns it to mytable. On what planet can Excel open HTML? Actually, that's a feature of Excel. You can use a special combination of XML and HTML tags to create files that are open-able on the web and in Excel. See this MSDN article: How to format an Excel workbook while streaming MIME content
I'm really kind of loss by the XML in general here, and by the <!--[if gte mso 9] comment. Can anyone help me understand what is going on here. That specific comment is checking for the availability of MS Excel (whether it's being opened by Excel or a browser), I believe. The XML is specific tags that have special meaning in MS Excel. There's a reference you can download here: Microsoft® Office HTML and XML Reference
I found this article on C# Corner to be pretty helpful in understanding this type of code: Creating a Dynamic Excel Using HTML.
As far as I know Excel has been able to read HTML for quite a while. This particular approach is pretty common, but it's definitely not best practice.
The important part of this logic is here:
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=hhexport.xls ")
HttpContext.Current.Response.Charset = ""
'ouput table to html so excel can interperet.
Me.EnableViewState = False
Dim stringWriter As New System.IO.StringWriter()
Dim htmlWriter As New System.Web.UI.HtmlTextWriter(stringWriter)
mytable.RenderControl(htmlWriter)
HttpContext.Current.Response.Write(stringWriter.ToString)
The Response.Write logic is just being used to control the workbook and worksheet that gets outputted. If that logic was not there, the file would open with three worksheets similar to a new Excel workbook.

Downloaded word file displaying incorrectly

I am working on a website at the moment which is displaying a strange bug with generated word documents. The site has a feature on it which allows the user to download a word document containing information related to their visit. This file is generated via some vb.net code and takes an xml template of the final document and inserts the relevant content required.
The strange behaviour is that on some machines the .doc file generated displays fine and on others it displays as XML when opened in Word. Both behaviours have been seen in the same version of Office (2003) but on seperate machines. My question is really whether the error lies with the set up of word on the individual machines, or whether there is an error in the code.
The code to create the file and download it is as follows:
Response.Clear()
Response.ClearHeaders()
Response.AddHeader("content-disposition", "inline; filename=MyNewFile")
Response.ContentType = "application/msword"
'Create the word file as a byte array based off an xml template document'
Dim objWordGenerator As New WordFileGenerator
Response.BinaryWrite(objWordGenerator.GetWordBytes)
Response.Flush()
Response.Clear()
Response.End()
The actual xml template is quite large so probably not suitable to post here but I can provide any more information if necessary.
Update:
Having managed to fix the original bug (it turns out that the original filename being used didn't have the .doc extension) I have found another bit of strange behaviour.
When the file is opened it opens in Word correctly, however when you go to save it the default file type is XML. When saved as an XML file it will open in Word correctly, but I feel this is slightly confusing behaviour for the end user. I would like the file to default to saving as a DOC file instead. Is there a way to force this to happen?
Update 2:
Below is a section of the XML that relates to the Document properties. The rest of the document deals with content and styles etc, so my assumption is that this is the most relevant section. To reiterate, my problem is that when the downloaded .doc file is opened in word, the default "save as" option is as an XML file.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Word.Document"?>
<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve">
<o:DocumentProperties>
<o:Title>Fancy Word Doc</o:Title>
<o:Author>Bob Bobertson</o:Author>
<o:Characters>999</o:Characters>
<o:Company>A Fancy Company</o:Company>
<o:Version>1.1.1</o:Version>
</o:DocumentProperties>
Cheers
The File -> SaveAs filetype is XML because that is what the file open in Word is. If you want it to say 'Word Document (*.doc) then you will need to create a real Word document on the server and not an XML. Just by putting a .doc extension on the filename doesn't change it's real contents. Word knows the file type that is loaded into it and suggests that as the file type when saving. I don't know of any way to override this behavior.
I've been using Office XML with Excel for awhile now and this is very similar to the code that I'm using to send it down to the client. You might want to try and see if it works for you.
Dim xml As XmlDocument = New XmlDocument()
xml.Load("report.doc")
Response.ContentType = "application/vnd.ms-word"
Response.AppendHeader("CONTENT-DISPOSITION", "attachment; filename=report.doc")
Response.Write(xml.OuterXml)
Try it with firefox and you will probably find that it will be saved with the correct extension.
IIRC, since version 3 IE prefers to ignore the mime type and sniff the file content to see what the "correct" file format is. Maybe is uses the magic cookie?
Is this Word 2007 or later? Try
Response.AddHeader("content-disposition", "attachment; filename='MyNewFile.doc'")
attachment encourages the browser to save the file instead of displaying it.
I ran some tests and could not reproduce your problem on my system in Word 2003. Without a specific example (and actual file that is misbehaving), it would be pure speculation to make any suggestions.

Resources