Hi all,
I'm looking for some advice on the best way to proceed with an Export to Excel feature in a reporting application.
I have an application that allows users to run ad-hoc reporting against many data sources. We have a couple hundred people using the application at any given time.
One of the features on the application is to allow users to export the entire results of their queries to an Excel spreadsheet (when viewings results on-screen, we use paging allowing only 15 records to be displayed at a time). We have this working, however we have noticed high memory-usage on our web servers (web-farm 5 machines). We're concerned it's the Excel feature causing problems, so I'm wondering if our method is sound, and if not, what better ways are there.
Basically when a users selects to export to excel, a stored proc is executed using the selected parameters, and the results populated into a SQLDATAREADER. We use the following call to call a function:
This executes the following function residing in one of our classes:
The recordsets can often be 30,000+ records, 30-40 columns.
Users can often wait for 4 or 5 minutes for their workbooks, which for some odd reason are often much bigger than they should be. The user will be prompted to open/save the workbook, which display excessively large workbooks. After opening the workbook, if the user chooses to save it, the SAVE AS TYPE shows Web Page (*htm,*html), not Microsoft Excel Workbook, which is significantly smaller in size.
So I'm wondering why the file type is not a workbook when being sent to the user, and is this causing my slow-downs/memory usage?
And does anyone have a better technique that would perform faster and perhaps be more memory-friendly?
By the way, small recordsets work fine, speed is good, file size is small. Large recordsets are hurting.
Any help/advice would be greatly appreciated.
Thank-you in advance,
Yazster
I'm looking for some advice on the best way to proceed with an Export to Excel feature in a reporting application.
I have an application that allows users to run ad-hoc reporting against many data sources. We have a couple hundred people using the application at any given time.
One of the features on the application is to allow users to export the entire results of their queries to an Excel spreadsheet (when viewings results on-screen, we use paging allowing only 15 records to be displayed at a time). We have this working, however we have noticed high memory-usage on our web servers (web-farm 5 machines). We're concerned it's the Excel feature causing problems, so I'm wondering if our method is sound, and if not, what better ways are there.
Basically when a users selects to export to excel, a stored proc is executed using the selected parameters, and the results populated into a SQLDATAREADER. We use the following call to call a function:
Code:
DataSetToExcel.ConvertToExcel(dr, Response)
This executes the following function residing in one of our classes:
Code:
Public Shared Sub ConvertToExcel(ByVal dr As SqlDataReader, ByVal response As HttpResponse)
response.Clear()
response.Charset = ""
response.ContentType = "application/vnd.ms-excel"
response.AddHeader("Content-Disposition", "attachment;filename=AIC_Export.xls")
Dim objSB As StringBuilder = New StringBuilder("")
Dim intFieldCnt As Integer
objSB.Append("<style>.text { mso-number-format:\@; } </style>")
objSB.Append("<Table cellspacing=""0"" cellpadding=""0"" border=""1"" bordercolor=""#000000"" width=""100%"" style=""font-size:8pt;"">")
'Column formatting
'Header captions
objSB.Append("<TR bgcolor=""#D0D0D0"">")
For intFieldCnt = 0 To dr.FieldCount - 1
objSB.Append("<TH>" & dr.GetName(intFieldCnt) & "</TH>")
Next
objSB.Append("</TR>")
'Data fields
Dim strTextFields As String = AvalancheFunctions.GetExcelFormatFields("TEXT")
While dr.Read()
objSB.Append("<TR>")
For intFieldCnt = 0 To dr.FieldCount - 1
'objSB.Append(IIf(InStr("CLASS;DIST CAT;CPN;FPN;MPN;BRANCH CODE;SHIPTO #;CUST NO;ORDER NO;AUTHORIZATION CODE;AUTH CODE", UCase(dr.GetName(intFieldCnt))) > 0, "<TD class='text'>" & dr.GetValue(intFieldCnt) & "</TD>", "<TD>" & dr.GetValue(intFieldCnt) & "</TD>"))
'(see line below) STYLE=""vnd.ms-excel.numberformat:@"" was added for Excel 97 users
objSB.Append(IIf(InStr(strTextFields, UCase(dr.GetName(intFieldCnt))) > 0, "<TD class='text' STYLE=""vnd.ms-excel.numberformat:@"">" & dr.GetValue(intFieldCnt) & "</TD>", "<TD>" & dr.GetValue(intFieldCnt) & "</TD>"))
Next
objSB.Append("</TR>")
End While
objSB.Append("</Table>")
response.Write(objSB.ToString())
response.End()
End Sub
The recordsets can often be 30,000+ records, 30-40 columns.
Users can often wait for 4 or 5 minutes for their workbooks, which for some odd reason are often much bigger than they should be. The user will be prompted to open/save the workbook, which display excessively large workbooks. After opening the workbook, if the user chooses to save it, the SAVE AS TYPE shows Web Page (*htm,*html), not Microsoft Excel Workbook, which is significantly smaller in size.
So I'm wondering why the file type is not a workbook when being sent to the user, and is this causing my slow-downs/memory usage?
And does anyone have a better technique that would perform faster and perhaps be more memory-friendly?
By the way, small recordsets work fine, speed is good, file size is small. Large recordsets are hurting.
Any help/advice would be greatly appreciated.
Thank-you in advance,
Yazster