2015-03-16 3 views
0

Хорошо, это интересная проблема. Мне было поручено изменить существующий проект VB. В настоящее время пользователь выбирает из серии выпадающих списков для выбора запроса sql и затем запускает этот запрос. Таким образом, пользователь выбирает и выпадающее меню, результаты этого раскрывающегося списка заполняют раскрывающийся список категорий. После выбора категории они получают раскрывающийся список доступных запросов. Как только они выбирают запрос и нажимают кнопку «Запустить», они получают gridview с результатами запроса. Некоторые результаты запроса огромны. Запрос, который я запускаю в качестве теста, содержит 40 столбцов и 20 000 записей. Запрос выполняется менее чем за 5 секунд, но для отображения gridview требуется более минуты. Как только рендеринг gridview будет выполнен, пользователь имеет возможность экспортировать результаты в Excel. И этим я имею в виду, что код открывает экземпляр Excel через gridview.RenderControl и отображает результаты в Excel. Пользователь не хочет сохранять файл excel, а затем перейти к файлу, он хочет, чтобы он открывался прямо из веб-формы, которую они используют, и это то, что делает код в настоящее время.Открыть DataTable в Excel VB

Однако пользователю не нужно смотреть на сетку. Им все равно, видят ли они это вообще. Они хотят просто открыть Excel. Поэтому вместо использования gridview.RenderControl я хочу открыть Excel и заполнить его DataTable (или DataSet) в памяти. Любые мысли о лучшем способе сделать это?

Вот как они в настоящее время заполнения GridView: Dim MyConnection Как SqlConnection Dim МояКоманда Как SqlCommand Dim MyDataTable As DataTable Dim MyReader Как SqlDataReader

 MyConnection = New SqlConnection() 
     MyConnection.ConnectionString = ConfigurationManager.ConnectionStrings(Connection).ConnectionString 

     MyCommand = New SqlCommand() 
     MyCommand.CommandText = Sqlquery 
     MyCommand.CommandType = CommandType.Text 
     MyCommand.Connection = MyConnection 

     MyCommand.Connection.Open() 
     MyReader = MyCommand.ExecuteReader(CommandBehavior.CloseConnection) 

     MyDataTable = New DataTable() 
     MyDataTable.Load(MyReader) 

     If (MyDataTable.Rows.Count > 0) Then 
      QueryresultPanel.Visible = True 
      gvLineItems.DataSource = MyDataTable 
      gvLineItems.DataBind() 
     End If 

     MyDataTable.Dispose() 
     MyCommand.Dispose() 
     MyConnection.Dispose() 

Вот как они открытия и заполнения экземпляра Excel:

 Protected Sub btnExportToExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExportToExcel.Click 
     Response.Clear() 
     Response.Buffer = True 
     ' 
     ' Set the content type to Excel. 
     ' 
     Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls") 
     Response.Charset = "" 
     Response.ContentType = "application/vnd.ms-excel" 
     ' 
     ' Turn off the view state. 
     ' 
     Me.EnableViewState = False 
     Dim oStringWriter As New System.IO.StringWriter() 
     Dim oHtmlTextWriter As New System.Web.UI.HtmlTextWriter(oStringWriter) 
     ' 
     ' Get the HTML for the control. 
     ' 
     gvLineItems.RenderControl(oHtmlTextWriter) 
     ' 
     ' Write the HTML back to the browser. 
     ' 
     Response.Write(oStringWriter.ToString()) 
     Response.[End]() 
    End Sub 

Очевидно, что нет никакого средства RenderControl для DataTable или DataSet a nd не может понять, как получить этот набор записей для визуализации в экземпляре Excel, не сохраняя его сначала.

ответ

0

Хорошо, вот решение, которое я нашел (на случай, если кто-то заинтересован). На самом деле это довольно просто. Я просто зациклился на datatable и использовал StringWriter.

Protected Sub WriteToExcelFile(dt As DataTable) 
    Dim sw As StringWriter 

    For Each datacol As DataColumn In dt.Columns 
     sw.Write(datacol.ColumnName + vbTab) 
    Next 

    Dim row As DataRow 
    For Each row In dt.Rows 
     sw.Write(vbNewLine) 
     Dim column As DataColumn 
     For Each column In dt.Columns 
      If Not row(column.ColumnName) Is Nothing Then 
       sw.Write(row(column).ToString() + vbTab) 
      Else 
       sw.Write(String.Empty + vbTab) 
      End If 
     Next column 
    Next row 

    Response.Clear() 
    Response.ContentType = "application/vnd.ms-excel" 
    Response.AddHeader("Content-Disposition", "attachment;filename=DataTable.xls") 
    Response.Output.Write(sw.ToString()) 
    Response.Flush() 
    System.Web.HttpContext.Current.Response.Flush() 
    System.Web.HttpContext.Current.Response.SuppressContent = True 
    System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest() 
End Sub 
Смежные вопросы